//------------------------------------------------------------------------------------------------------- | |
// 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); | |
} | |
} |