blob: 4155ad7c665cf0f11753cea93003ab11c73b0753 [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// 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);
}
}