function evaluateArrowFunctionExpression(options) {
    const { node, environment, evaluate, stack, statementTraversalStack, reporting, typescript } = options;
    const arrowFunctionExpression = hasModifier(node, typescript.SyntaxKind.AsyncKeyword)
        ? async (...args) => {
            // Prepare a lexical environment for the function context
            const localLexicalEnvironment = cloneLexicalEnvironment(environment);
            // Define a new binding for a return symbol within the environment
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: RETURN_SYMBOL, value: false, newBinding: true, reporting, node });
            // Define a new binding for the arguments given to the function
            // eslint-disable-next-line prefer-rest-params
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: "arguments", value: arguments, newBinding: true, reporting, node });
            // Evaluate the parameters based on the given arguments
            evaluateParameterDeclarations(Object.assign(Object.assign({}, options), { node: node.parameters, environment: localLexicalEnvironment }), args);
            // If the body is a block, evaluate it as a statement
            if (typescript.isBlock(node.body)) {
                evaluate.statement(node.body, localLexicalEnvironment);
                // If a 'return' has occurred within the block, pop the Stack and return that value
                if (pathInLexicalEnvironmentEquals(node, localLexicalEnvironment, true, RETURN_SYMBOL)) {
                    return stack.pop();
                }
                // Otherwise, return 'undefined'. Nothing is returned from the function
                else
                    return undefined;
            }
            // Otherwise, the body is itself an expression
            else {
                return evaluate.expression(node.body, localLexicalEnvironment, statementTraversalStack);
            }
        }
        : (...args) => {
            // Prepare a lexical environment for the function context
            const localLexicalEnvironment = cloneLexicalEnvironment(environment);
            // Define a new binding for a return symbol within the environment
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: RETURN_SYMBOL, value: false, newBinding: true, reporting, node });
            // Define a new binding for the arguments given to the function
            // eslint-disable-next-line prefer-rest-params
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: "arguments", value: arguments, newBinding: true, reporting, node });
            // Evaluate the parameters based on the given arguments
            evaluateParameterDeclarations(Object.assign(Object.assign({}, options), { node: node.parameters, environment: localLexicalEnvironment }), args);
            // If the body is a block, evaluate it as a statement
            if (typescript.isBlock(node.body)) {
                evaluate.statement(node.body, localLexicalEnvironment);
                // If a 'return' has occurred within the block, pop the Stack and return that value
                if (pathInLexicalEnvironmentEquals(node, localLexicalEnvironment, true, RETURN_SYMBOL)) {
                    return stack.pop();
                }
                // Otherwise, return 'undefined'. Nothing is returned from the function
                else
                    return undefined;
            }
            // Otherwise, the body is itself an expression
            else {
                return evaluate.expression(node.body, localLexicalEnvironment, statementTraversalStack);
            }
        };
    arrowFunctionExpression.toString = () => `[Function: anonymous]`;
    // Make sure to use the Function that is contained within the Realm. Otherwise, 'instanceof' checks may fail
    // since this particular function comes from the executing context.
    Object.setPrototypeOf(arrowFunctionExpression, getFromLexicalEnvironment(node, environment, "Function").literal);
    return arrowFunctionExpression;
}
/**
 * Evaluates, or attempts to evaluate, an ArrowFunction
 */
Evaluates, or attempts to evaluate, an ArrowFunction
Evaluates or attempts to evaluate an ArrowFunction
function evaluateArrowFunctionExpression(options) {
    const { node, environment, evaluate, stack, statementTraversalStack, reporting, typescript } = options;
    const arrowFunctionExpression = hasModifier(node, typescript.SyntaxKind.AsyncKeyword)
        ? async (...args) => {
            const localLexicalEnvironment = cloneLexicalEnvironment(environment);
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: RETURN_SYMBOL, value: false, newBinding: true, reporting, node });
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: "arguments", value: arguments, newBinding: true, reporting, node });
            evaluateParameterDeclarations(Object.assign(Object.assign({}, options), { node: node.parameters, environment: localLexicalEnvironment }), args);
            if (typescript.isBlock(node.body)) {
                evaluate.statement(node.body, localLexicalEnvironment);
                if (pathInLexicalEnvironmentEquals(node, localLexicalEnvironment, true, RETURN_SYMBOL)) {
                    return stack.pop();
                }
                else
                    return undefined;
            }
            else {
                return evaluate.expression(node.body, localLexicalEnvironment, statementTraversalStack);
            }
        }
        : (...args) => {
            const localLexicalEnvironment = cloneLexicalEnvironment(environment);
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: RETURN_SYMBOL, value: false, newBinding: true, reporting, node });
            setInLexicalEnvironment({ env: localLexicalEnvironment, path: "arguments", value: arguments, newBinding: true, reporting, node });
            evaluateParameterDeclarations(Object.assign(Object.assign({}, options), { node: node.parameters, environment: localLexicalEnvironment }), args);
            if (typescript.isBlock(node.body)) {
                evaluate.statement(node.body, localLexicalEnvironment);
                if (pathInLexicalEnvironmentEquals(node, localLexicalEnvironment, true, RETURN_SYMBOL)) {
                    return stack.pop();
                }
                else
                    return undefined;
            }
            else {
                return evaluate.expression(node.body, localLexicalEnvironment, statementTraversalStack);
            }
        };
    arrowFunctionExpression.toString = () => `[Function: anonymous]`;
    Object.setPrototypeOf(arrowFunctionExpression, getFromLexicalEnvironment(node, environment, "Function").literal);
    return arrowFunctionExpression;
}
function evaluateArrowFunctionExpression ( options ) { const { node , environment , evaluate , stack , statementTraversalStack , reporting , typescript } = options ; const arrowFunctionExpression = hasModifier ( node , typescript . SyntaxKind . AsyncKeyword ) ? async ( ... args ) => { const localLexicalEnvironment = cloneLexicalEnvironment ( environment ) ; setInLexicalEnvironment ( { env : localLexicalEnvironment , path : RETURN_SYMBOL , value : false , newBinding : true , reporting , node } ) ; setInLexicalEnvironment ( { env : localLexicalEnvironment , path : "arguments" , value : arguments , newBinding : true , reporting , node } ) ; evaluateParameterDeclarations ( Object . assign ( Object . assign ( { } , options ) , { node : node . parameters , environment : localLexicalEnvironment } ) , args ) ; if ( typescript . isBlock ( node . body ) ) { evaluate . statement ( node . body , localLexicalEnvironment ) ; if ( pathInLexicalEnvironmentEquals ( node , localLexicalEnvironment , true , RETURN_SYMBOL ) ) { return stack . pop ( ) ; } else return undefined ; } else { return evaluate . expression ( node . body , localLexicalEnvironment , statementTraversalStack ) ; } } : ( ... args ) => { const localLexicalEnvironment = cloneLexicalEnvironment ( environment ) ; setInLexicalEnvironment ( { env : localLexicalEnvironment , path : RETURN_SYMBOL , value : false , newBinding : true , reporting , node } ) ; setInLexicalEnvironment ( { env : localLexicalEnvironment , path : "arguments" , value : arguments , newBinding : true , reporting , node } ) ; evaluateParameterDeclarations ( Object . assign ( Object . assign ( { } , options ) , { node : node . parameters , environment : localLexicalEnvironment } ) , args ) ; if ( typescript . isBlock ( node . body ) ) { evaluate . statement ( node . body , localLexicalEnvironment ) ; if ( pathInLexicalEnvironmentEquals ( node , localLexicalEnvironment , true , RETURN_SYMBOL ) ) { return stack . pop ( ) ; } else return undefined ; } else { return evaluate . expression ( node . body , localLexicalEnvironment , statementTraversalStack ) ; } } ; arrowFunctionExpression . toString = ( ) => ` ` ; Object . setPrototypeOf ( arrowFunctionExpression , getFromLexicalEnvironment ( node , environment , "Function" ) . literal ) ; return arrowFunctionExpression ; }
Evaluates, or attempts to evaluate, an ArrowFunction
Evaluates or attempts to evaluate an ArrowFunction
// Prepare a lexical environment for the function context // Define a new binding for a return symbol within the environment // Define a new binding for the arguments given to the function // eslint-disable-next-line prefer-rest-params // Evaluate the parameters based on the given arguments // If the body is a block, evaluate it as a statement // If a 'return' has occurred within the block, pop the Stack and return that value // Otherwise, return 'undefined'. Nothing is returned from the function // Otherwise, the body is itself an expression // Prepare a lexical environment for the function context // Define a new binding for a return symbol within the environment // Define a new binding for the arguments given to the function // eslint-disable-next-line prefer-rest-params // Evaluate the parameters based on the given arguments // If the body is a block, evaluate it as a statement // If a 'return' has occurred within the block, pop the Stack and return that value // Otherwise, return 'undefined'. Nothing is returned from the function // Otherwise, the body is itself an expression // Make sure to use the Function that is contained within the Realm. Otherwise, 'instanceof' checks may fail // since this particular function comes from the executing context.