function evaluateMethodDeclaration(options, parent) {
    const { node, environment, evaluate, stack, statementTraversalStack, reporting, typescript } = options;
    const nameResult = evaluate.nodeWithValue(node.name, environment, statementTraversalStack);
    const isStatic = inStaticContext(node, typescript);
    if (parent == null) {
        let updatedParent;
        if (typescript.isClassLike(node.parent)) {
            evaluate.declaration(node.parent, environment, statementTraversalStack);
            updatedParent = stack.pop();
        }
        else {
            updatedParent = evaluate.expression(node.parent, environment, statementTraversalStack);
        }
        stack.push(isStatic ? updatedParent[nameResult] : updatedParent.prototype[nameResult]);
        return;
    }
    const _methodDeclaration = hasModifier(node, typescript.SyntaxKind.AsyncKeyword)
        ? async function methodDeclaration(...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 });
            if (this != null) {
                setInLexicalEnvironment({ env: localLexicalEnvironment, path: THIS_SYMBOL, value: this, newBinding: true, reporting, node });
                // Set the 'super' binding, depending on whether or not we're inside a static context
                setInLexicalEnvironment({
                    env: localLexicalEnvironment,
                    path: SUPER_SYMBOL,
                    value: isStatic ? Object.getPrototypeOf(this) : Object.getPrototypeOf(this.constructor).prototype,
                    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 (node.body == null)
                return;
            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;
        }
        : function methodDeclaration(...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 });
            if (this != null) {
                setInLexicalEnvironment({ env: localLexicalEnvironment, path: THIS_SYMBOL, value: this, newBinding: true, reporting, node });
                // Set the 'super' binding, depending on whether or not we're inside a static context
                setInLexicalEnvironment({
                    env: localLexicalEnvironment,
                    path: SUPER_SYMBOL,
                    value: isStatic ? Object.getPrototypeOf(this) : Object.getPrototypeOf(this.constructor).prototype,
                    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 (node.body == null)
                return;
            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;
        };
    _methodDeclaration.toString = () => `[Method: ${nameResult}]`;
    // 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(_methodDeclaration, getFromLexicalEnvironment(node, environment, "Function").literal);
    parent[nameResult] = _methodDeclaration;
    if (node.decorators != null) {
        for (const decorator of node.decorators) {
            evaluate.nodeWithArgument(decorator, environment, [parent, nameResult], statementTraversalStack);
            // Pop the stack. We don't need the value it has left on the Stack
            stack.pop();
        }
    }
    // Also loop through parameters to use their decorators, if any
    if (node.parameters != null) {
        // 'this' is a special parameter which is removed from the emitted results
        const parameters = node.parameters.filter(param => !(typescript.isIdentifier(param.name) && param.name.text === "this"));
        for (let i = 0; i < parameters.length; i++) {
            const parameter = parameters[i];
            if (parameter.decorators != null) {
                for (const decorator of parameter.decorators) {
                    evaluate.nodeWithArgument(decorator, environment, [parent, nameResult, i], statementTraversalStack);
                    // Pop the stack. We don't need the value it has left on the Stack
                    stack.pop();
                }
            }
        }
    }
}
/**
 * Evaluates, or attempts to evaluate, a MethodDeclaration, before setting it on the given parent
 */
Evaluates, or attempts to evaluate, a MethodDeclaration, before setting it on the given parent
Evaluates or attempts to evaluate a MethodDeclaration before setting it on the given parent
function evaluateMethodDeclaration(options, parent) {
    const { node, environment, evaluate, stack, statementTraversalStack, reporting, typescript } = options;
    const nameResult = evaluate.nodeWithValue(node.name, environment, statementTraversalStack);
    const isStatic = inStaticContext(node, typescript);
    if (parent == null) {
        let updatedParent;
        if (typescript.isClassLike(node.parent)) {
            evaluate.declaration(node.parent, environment, statementTraversalStack);
            updatedParent = stack.pop();
        }
        else {
            updatedParent = evaluate.expression(node.parent, environment, statementTraversalStack);
        }
        stack.push(isStatic ? updatedParent[nameResult] : updatedParent.prototype[nameResult]);
        return;
    }
    const _methodDeclaration = hasModifier(node, typescript.SyntaxKind.AsyncKeyword)
        ? async function methodDeclaration(...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 });
            if (this != null) {
                setInLexicalEnvironment({ env: localLexicalEnvironment, path: THIS_SYMBOL, value: this, newBinding: true, reporting, node });
                setInLexicalEnvironment({
                    env: localLexicalEnvironment,
                    path: SUPER_SYMBOL,
                    value: isStatic ? Object.getPrototypeOf(this) : Object.getPrototypeOf(this.constructor).prototype,
                    newBinding: true,
                    reporting,
                    node
                });
            }
            evaluateParameterDeclarations(Object.assign(Object.assign({}, options), { node: node.parameters, environment: localLexicalEnvironment }), args);
            if (node.body == null)
                return;
            evaluate.statement(node.body, localLexicalEnvironment);
            if (pathInLexicalEnvironmentEquals(node, localLexicalEnvironment, true, RETURN_SYMBOL)) {
                return stack.pop();
            }
            else
                return undefined;
        }
        : function methodDeclaration(...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 });
            if (this != null) {
                setInLexicalEnvironment({ env: localLexicalEnvironment, path: THIS_SYMBOL, value: this, newBinding: true, reporting, node });
                setInLexicalEnvironment({
                    env: localLexicalEnvironment,
                    path: SUPER_SYMBOL,
                    value: isStatic ? Object.getPrototypeOf(this) : Object.getPrototypeOf(this.constructor).prototype,
                    newBinding: true,
                    reporting,
                    node
                });
            }
            evaluateParameterDeclarations(Object.assign(Object.assign({}, options), { node: node.parameters, environment: localLexicalEnvironment }), args);
            if (node.body == null)
                return;
            evaluate.statement(node.body, localLexicalEnvironment);
            if (pathInLexicalEnvironmentEquals(node, localLexicalEnvironment, true, RETURN_SYMBOL)) {
                return stack.pop();
            }
            else
                return undefined;
        };
    _methodDeclaration.toString = () => `[Method: ${nameResult}]`;
    Object.setPrototypeOf(_methodDeclaration, getFromLexicalEnvironment(node, environment, "Function").literal);
    parent[nameResult] = _methodDeclaration;
    if (node.decorators != null) {
        for (const decorator of node.decorators) {
            evaluate.nodeWithArgument(decorator, environment, [parent, nameResult], statementTraversalStack);
            stack.pop();
        }
    }
    if (node.parameters != null) {
        const parameters = node.parameters.filter(param => !(typescript.isIdentifier(param.name) && param.name.text === "this"));
        for (let i = 0; i < parameters.length; i++) {
            const parameter = parameters[i];
            if (parameter.decorators != null) {
                for (const decorator of parameter.decorators) {
                    evaluate.nodeWithArgument(decorator, environment, [parent, nameResult, i], statementTraversalStack);
                    stack.pop();
                }
            }
        }
    }
}
function evaluateMethodDeclaration ( options , parent ) { const { node , environment , evaluate , stack , statementTraversalStack , reporting , typescript } = options ; const nameResult = evaluate . nodeWithValue ( node . name , environment , statementTraversalStack ) ; const isStatic = inStaticContext ( node , typescript ) ; if ( parent == null ) { let updatedParent ; if ( typescript . isClassLike ( node . parent ) ) { evaluate . declaration ( node . parent , environment , statementTraversalStack ) ; updatedParent = stack . pop ( ) ; } else { updatedParent = evaluate . expression ( node . parent , environment , statementTraversalStack ) ; } stack . push ( isStatic ? updatedParent [ nameResult ] : updatedParent . prototype [ nameResult ] ) ; return ; } const _methodDeclaration = hasModifier ( node , typescript . SyntaxKind . AsyncKeyword ) ? async function methodDeclaration ( ... 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 } ) ; if ( this != null ) { setInLexicalEnvironment ( { env : localLexicalEnvironment , path : THIS_SYMBOL , value : this , newBinding : true , reporting , node } ) ; setInLexicalEnvironment ( { env : localLexicalEnvironment , path : SUPER_SYMBOL , value : isStatic ? Object . getPrototypeOf ( this ) : Object . getPrototypeOf ( this . constructor ) . prototype , newBinding : true , reporting , node } ) ; } evaluateParameterDeclarations ( Object . assign ( Object . assign ( { } , options ) , { node : node . parameters , environment : localLexicalEnvironment } ) , args ) ; if ( node . body == null ) return ; evaluate . statement ( node . body , localLexicalEnvironment ) ; if ( pathInLexicalEnvironmentEquals ( node , localLexicalEnvironment , true , RETURN_SYMBOL ) ) { return stack . pop ( ) ; } else return undefined ; } : function methodDeclaration ( ... 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 } ) ; if ( this != null ) { setInLexicalEnvironment ( { env : localLexicalEnvironment , path : THIS_SYMBOL , value : this , newBinding : true , reporting , node } ) ; setInLexicalEnvironment ( { env : localLexicalEnvironment , path : SUPER_SYMBOL , value : isStatic ? Object . getPrototypeOf ( this ) : Object . getPrototypeOf ( this . constructor ) . prototype , newBinding : true , reporting , node } ) ; } evaluateParameterDeclarations ( Object . assign ( Object . assign ( { } , options ) , { node : node . parameters , environment : localLexicalEnvironment } ) , args ) ; if ( node . body == null ) return ; evaluate . statement ( node . body , localLexicalEnvironment ) ; if ( pathInLexicalEnvironmentEquals ( node , localLexicalEnvironment , true , RETURN_SYMBOL ) ) { return stack . pop ( ) ; } else return undefined ; } ; _methodDeclaration . toString = ( ) => ` ${ nameResult } ` ; Object . setPrototypeOf ( _methodDeclaration , getFromLexicalEnvironment ( node , environment , "Function" ) . literal ) ; parent [ nameResult ] = _methodDeclaration ; if ( node . decorators != null ) { for ( const decorator of node . decorators ) { evaluate . nodeWithArgument ( decorator , environment , [ parent , nameResult ] , statementTraversalStack ) ; stack . pop ( ) ; } } if ( node . parameters != null ) { const parameters = node . parameters . filter ( param => ! ( typescript . isIdentifier ( param . name ) && param . name . text === "this" ) ) ; for ( let i = 0 ; i < parameters . length ; i ++ ) { const parameter = parameters [ i ] ; if ( parameter . decorators != null ) { for ( const decorator of parameter . decorators ) { evaluate . nodeWithArgument ( decorator , environment , [ parent , nameResult , i ] , statementTraversalStack ) ; stack . pop ( ) ; } } } } }
Evaluates, or attempts to evaluate, a MethodDeclaration, before setting it on the given parent
Evaluates or attempts to evaluate a MethodDeclaration before setting it on the given parent
// 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 // Set the 'super' binding, depending on whether or not we're inside a static context // 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 // 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 // Set the 'super' binding, depending on whether or not we're inside a static context // 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 // 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. // Pop the stack. We don't need the value it has left on the Stack // Also loop through parameters to use their decorators, if any // 'this' is a special parameter which is removed from the emitted results // Pop the stack. We don't need the value it has left on the Stack