function evaluateForInStatement({ node, environment, evaluate, logger, reporting, typescript, statementTraversalStack }) {
    // Compute the 'of' part
    const expressionResult = evaluate.expression(node.expression, environment, statementTraversalStack);
    // Ensure that the initializer is a proper VariableDeclarationList
    if (!typescript.isVariableDeclarationList(node.initializer)) {
        throw new UnexpectedNodeError({ node: node.initializer, typescript });
    }
    // Only 1 declaration is allowed in a ForOfStatement
    else if (node.initializer.declarations.length > 1) {
        throw new UnexpectedNodeError({ node: node.initializer.declarations[1], typescript });
    }
    for (const literal in expressionResult) {
        // Prepare a lexical environment for the current iteration
        const localEnvironment = cloneLexicalEnvironment(environment);
        // Define a new binding for a break symbol within the environment
        setInLexicalEnvironment({ env: localEnvironment, path: BREAK_SYMBOL, value: false, newBinding: true, reporting, node });
        // Define a new binding for a continue symbol within the environment
        setInLexicalEnvironment({ env: localEnvironment, path: CONTINUE_SYMBOL, value: false, newBinding: true, reporting, node });
        // Evaluate the VariableDeclaration and manually pass in the current literal as the initializer for the variable assignment
        evaluate.nodeWithArgument(node.initializer.declarations[0], localEnvironment, literal, statementTraversalStack);
        // Evaluate the Statement
        evaluate.statement(node.statement, localEnvironment);
        // Check if a 'break' statement has been encountered and break if so
        if (pathInLexicalEnvironmentEquals(node, localEnvironment, true, BREAK_SYMBOL)) {
            logger.logBreak(node, typescript);
            break;
        }
        else if (pathInLexicalEnvironmentEquals(node, localEnvironment, true, CONTINUE_SYMBOL)) {
            logger.logContinue(node, typescript);
            // noinspection UnnecessaryContinueJS
            continue;
        }
        else if (pathInLexicalEnvironmentEquals(node, localEnvironment, true, RETURN_SYMBOL)) {
            logger.logReturn(node, typescript);
            return;
        }
    }
}
/**
 * Evaluates, or attempts to evaluate, a ForInStatement
 */
Evaluates, or attempts to evaluate, a ForInStatement
Evaluates or attempts to evaluate a ForInStatement
function evaluateForInStatement({ node, environment, evaluate, logger, reporting, typescript, statementTraversalStack }) {
    const expressionResult = evaluate.expression(node.expression, environment, statementTraversalStack);
    if (!typescript.isVariableDeclarationList(node.initializer)) {
        throw new UnexpectedNodeError({ node: node.initializer, typescript });
    }
    else if (node.initializer.declarations.length > 1) {
        throw new UnexpectedNodeError({ node: node.initializer.declarations[1], typescript });
    }
    for (const literal in expressionResult) {
        const localEnvironment = cloneLexicalEnvironment(environment);
        setInLexicalEnvironment({ env: localEnvironment, path: BREAK_SYMBOL, value: false, newBinding: true, reporting, node });
        setInLexicalEnvironment({ env: localEnvironment, path: CONTINUE_SYMBOL, value: false, newBinding: true, reporting, node });
        evaluate.nodeWithArgument(node.initializer.declarations[0], localEnvironment, literal, statementTraversalStack);
        evaluate.statement(node.statement, localEnvironment);
        if (pathInLexicalEnvironmentEquals(node, localEnvironment, true, BREAK_SYMBOL)) {
            logger.logBreak(node, typescript);
            break;
        }
        else if (pathInLexicalEnvironmentEquals(node, localEnvironment, true, CONTINUE_SYMBOL)) {
            logger.logContinue(node, typescript);
            continue;
        }
        else if (pathInLexicalEnvironmentEquals(node, localEnvironment, true, RETURN_SYMBOL)) {
            logger.logReturn(node, typescript);
            return;
        }
    }
}
function evaluateForInStatement ( { node , environment , evaluate , logger , reporting , typescript , statementTraversalStack } ) { const expressionResult = evaluate . expression ( node . expression , environment , statementTraversalStack ) ; if ( ! typescript . isVariableDeclarationList ( node . initializer ) ) { throw new UnexpectedNodeError ( { node : node . initializer , typescript } ) ; } else if ( node . initializer . declarations . length > 1 ) { throw new UnexpectedNodeError ( { node : node . initializer . declarations [ 1 ] , typescript } ) ; } for ( const literal in expressionResult ) { const localEnvironment = cloneLexicalEnvironment ( environment ) ; setInLexicalEnvironment ( { env : localEnvironment , path : BREAK_SYMBOL , value : false , newBinding : true , reporting , node } ) ; setInLexicalEnvironment ( { env : localEnvironment , path : CONTINUE_SYMBOL , value : false , newBinding : true , reporting , node } ) ; evaluate . nodeWithArgument ( node . initializer . declarations [ 0 ] , localEnvironment , literal , statementTraversalStack ) ; evaluate . statement ( node . statement , localEnvironment ) ; if ( pathInLexicalEnvironmentEquals ( node , localEnvironment , true , BREAK_SYMBOL ) ) { logger . logBreak ( node , typescript ) ; break ; } else if ( pathInLexicalEnvironmentEquals ( node , localEnvironment , true , CONTINUE_SYMBOL ) ) { logger . logContinue ( node , typescript ) ; continue ; } else if ( pathInLexicalEnvironmentEquals ( node , localEnvironment , true , RETURN_SYMBOL ) ) { logger . logReturn ( node , typescript ) ; return ; } } }
Evaluates, or attempts to evaluate, a ForInStatement
Evaluates or attempts to evaluate a ForInStatement
// Compute the 'of' part // Ensure that the initializer is a proper VariableDeclarationList // Only 1 declaration is allowed in a ForOfStatement // Prepare a lexical environment for the current iteration // Define a new binding for a break symbol within the environment // Define a new binding for a continue symbol within the environment // Evaluate the VariableDeclaration and manually pass in the current literal as the initializer for the variable assignment // Evaluate the Statement // Check if a 'break' statement has been encountered and break if so // noinspection UnnecessaryContinueJS