commit cc2e2587f391b3c726f8c6bf809d1411fbc43cff Author: ReimarPB Date: Sat Sep 9 13:22:26 2023 +0200 Initial commit diff --git a/example.html b/example.html new file mode 100644 index 0000000..b605496 --- /dev/null +++ b/example.html @@ -0,0 +1,15 @@ + + + diff --git a/runtime-checker.js b/runtime-checker.js new file mode 100644 index 0000000..a32a49c --- /dev/null +++ b/runtime-checker.js @@ -0,0 +1,58 @@ +Function.prototype.addRuntimeChecker = function() { + var handler = { + apply: function(target, thisArg, argumentValues) { + + // https://stackoverflow.com/a/31194949 + var argumentNames = target.toString() + .replace(/[/][/].*$/mg,'') // strip single-line comments + .replace(/\s+/g, '') // strip white space + .replace(/[/][*][^/\*]*[*][/]/g, '') // strip multi-line comments + .split('){', 1)[0].replace(/^[^(]*[(]/, '') // extract the parameters + .replace(/=[^,]+/g, '') // strip any ES6 defaults + .split(',').filter(Boolean); // split & filter [""] + + var argumentNamesWithoutTypes = []; + + for (var i = 0; i < argumentValues.length; i++) { + // Get type from parameter name + var match = argumentNames[i].match(/(.+)_(\w+)/); + if (!match || match.length < 3) { + argumentNamesWithoutTypes.push(argumentNames[i]); + continue; + } + + argumentNamesWithoutTypes.push(match[1]); + + var type = match[2]; + + // Check types + if (typeof argumentValues[i] !== type) + throw new Error("Invalid argument #" + i + " - Expected " + type + ", got " + typeof argumentValues[i]); + } + + // Assign actual names to window object before calling functions + var oldWindow = {}; + for (var i = 0; i < argumentNamesWithoutTypes.length; i++) { + var name = argumentNamesWithoutTypes[i]; + + oldWindow[name] = window[name]; + window[name] = argumentValues[i]; + } + + // Call function + var runtimeCheckerResult = target.apply(thisArg, argumentValues); + + // Re-assign old window values + for (var name in oldWindow) { + if (!oldWindow.hasOwnProperty(name)) continue; + + window[name] = oldWindow[name]; + } + + return runtimeCheckerResult; + } + }; + + return new Proxy(this, handler); +} +