//------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- function generateTestFunctionAndCall( functionTypeAndName, // integer: 0 is declaration, 1 is declaration named 'arguments', 2 is unnamed expression, 3 is expression named 'arguments' parameterArguments, // boolean nestedFunctionType, // integer: 0 is no nested function, 1 is nested function declaration, 2 is nested function expression varDeclarationArgumentsType, // integer: 0 is no var declaration, 1 is var declaration, 2 is initialized var declaration callsEval) // boolean { var typeMap = { "function": "function", "number": "parameter", "string": "var", "object": "arguments" }; // The generated function will look something like this: // safeCall(function () // { // function arguments(arguments) // { // eval(""); // (function arguments() { }); // var arguments = "hi"; // writeLine(typeMap[typeof (arguments)]); // } // arguments(1); // }); var functionCode = ""; switch (functionTypeAndName) { case 2: case 3: functionCode += "("; } functionCode += "function"; var functionName = ""; switch (functionTypeAndName) { case 0: functionName = "foo"; break; case 1: case 3: functionName = "arguments"; } functionCode += " " + functionName + "("; if (parameterArguments) functionCode += "arguments"; functionCode += "){"; if (callsEval) functionCode += 'eval("");'; switch (nestedFunctionType) { case 1: functionCode += "function arguments(){}"; break; case 2: functionCode += "(function arguments(){});"; } switch (varDeclarationArgumentsType) { case 1: case 2: functionCode += "var arguments"; if (varDeclarationArgumentsType === 2) functionCode += '="hi"'; functionCode += ";"; } functionCode += "writeLine(typeMap[typeof(arguments)]);}"; switch (functionTypeAndName) { case 0: case 1: functionCode += functionName; break; case 2: case 3: functionCode += ")"; } functionCode += "(1);"; writeLine(functionCode); eval("safeCall(function(){" + functionCode + "});"); } var booleans = [false, true]; for (var functionTypeAndName = 0; functionTypeAndName <= 3; ++functionTypeAndName) { for (var parameterArgumentsIndex in booleans) { for (var nestedFunctionType = 0; nestedFunctionType <= 2; ++nestedFunctionType) { for (var varDeclarationArgumentsType = 0; varDeclarationArgumentsType <= 2; ++varDeclarationArgumentsType) { for (var callsEvalIndex in booleans) { var parameterArguments = booleans[parameterArgumentsIndex]; var callsEval = booleans[callsEvalIndex]; generateTestFunctionAndCall( functionTypeAndName, parameterArguments, nestedFunctionType, varDeclarationArgumentsType, callsEval); } } } } } // Helpers function writeLine(str) { WScript.Echo("" + str); } function safeCall(func) { try { return func(); } catch (ex) { writeLine(ex.name + ": " + ex.message); } }