/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qv4compilerscanfunctions_p.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QSet>
#include <QtCore/QBuffer>
#include <QtCore/QBitArray>
#include <QtCore/QStack>
#include <private/qqmljsast_p.h>
#include <private/qv4compilercontext_p.h>
#include <private/qv4codegen_p.h>

QT_USE_NAMESPACE
using namespace QV4;
using namespace QV4::Compiler;
using namespace QQmlJS;
using namespace QQmlJS::AST;

static CompiledData::Location location(const QQmlJS::SourceLocation &astLocation)
{
    CompiledData::Location target;
    target.line = astLocation.startLine;
    target.column = astLocation.startColumn;
    return target;
}


ScanFunctions::ScanFunctions(Codegen *cg, const QString &sourceCode, ContextType defaultProgramType)
    : QQmlJS::AST::Visitor(cg->recursionDepth())
    , _cg(cg)
    , _sourceCode(sourceCode)
    , _context(nullptr)
    , _allowFuncDecls(true)
    , defaultProgramType(defaultProgramType)
{
}

void ScanFunctions::operator()(Node *node)
{
    if (node)
        node->accept(this);

    calcEscapingVariables();
}

void ScanFunctions::enterGlobalEnvironment(ContextType compilationMode)
{
    enterEnvironment(astNodeForGlobalEnvironment, compilationMode, QStringLiteral("%GlobalCode"));
}

void ScanFunctions::enterEnvironment(Node *node, ContextType compilationMode, const QString &name)
{
    Context *c = _cg->_module->contextMap.value(node);
    if (!c)
        c = _cg->_module->newContext(node, _context, compilationMode);
    if (!c->isStrict)
        c->isStrict = _cg->_strictMode;
    c->name = name;
    _contextStack.append(c);
    _context = c;
}

void ScanFunctions::leaveEnvironment()
{
    _contextStack.pop();
    _context = _contextStack.isEmpty() ? nullptr : _contextStack.top();
}

void ScanFunctions::checkDirectivePrologue(StatementList *ast)
{
    for (StatementList *it = ast; it; it = it->next) {
        if (ExpressionStatement *expr = cast<ExpressionStatement *>(it->statement)) {
            if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) {
                // Use the source code, because the StringLiteral's
                // value might have escape sequences in it, which is not
                // allowed.
                if (strLit->literalToken.length < 2)
                    continue;
                QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2);
                if (str == QLatin1String("use strict")) {
                    _context->isStrict = true;
                } else {
                    // TODO: give a warning.
                }
                continue;
            }
        }

        break;
    }
}

void ScanFunctions::checkName(const QStringRef &name, const QQmlJS::SourceLocation &loc)
{
    if (_context->isStrict) {
        if (name == QLatin1String("implements")
                || name == QLatin1String("interface")
                || name == QLatin1String("let")
                || name == QLatin1String("package")
                || name == QLatin1String("private")
                || name == QLatin1String("protected")
                || name == QLatin1String("public")
                || name == QLatin1String("static")
                || name == QLatin1String("yield")) {
            _cg->throwSyntaxError(loc, QStringLiteral("Unexpected strict mode reserved word"));
        }
    }
}

bool ScanFunctions::visit(Program *ast)
{
    enterEnvironment(ast, defaultProgramType, QStringLiteral("%ProgramCode"));
    checkDirectivePrologue(ast->statements);
    return true;
}

void ScanFunctions::endVisit(Program *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ESModule *ast)
{
    enterEnvironment(ast, defaultProgramType, QStringLiteral("%ModuleCode"));
    _context->isStrict = true;
    return true;
}

void ScanFunctions::endVisit(ESModule *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ExportDeclaration *declaration)
{
    QString module;
    if (declaration->fromClause) {
        module = declaration->fromClause->moduleSpecifier.toString();
        if (!module.isEmpty())
            _context->moduleRequests << module;
    }

    QString localNameForDefaultExport = QStringLiteral("*default*");

    if (declaration->exportAll) {
        Compiler::ExportEntry entry;
        entry.moduleRequest = declaration->fromClause->moduleSpecifier.toString();
        entry.importName = QStringLiteral("*");
        entry.location = location(declaration->firstSourceLocation());
        _context->exportEntries << entry;
    } else if (declaration->exportClause) {
        for (ExportsList *it = declaration->exportClause->exportsList; it; it = it->next) {
            ExportSpecifier *spec = it->exportSpecifier;
            Compiler::ExportEntry entry;
            if (module.isEmpty())
                entry.localName = spec->identifier.toString();
            else
                entry.importName = spec->identifier.toString();

            entry.moduleRequest = module;
            entry.exportName = spec->exportedIdentifier.toString();
            entry.location = location(it->firstSourceLocation());

            _context->exportEntries << entry;
        }
    } else if (auto *vstmt = AST::cast<AST::VariableStatement*>(declaration->variableStatementOrDeclaration)) {
        BoundNames boundNames;
        for (VariableDeclarationList *it = vstmt->declarations; it; it = it->next) {
            if (!it->declaration)
                continue;
            it->declaration->boundNames(&boundNames);
        }
        for (const auto &name: boundNames) {
            Compiler::ExportEntry entry;
            entry.localName = name.id;
            entry.exportName = name.id;
            entry.location = location(vstmt->firstSourceLocation());
            _context->exportEntries << entry;
        }
    } else if (auto *classDecl = AST::cast<AST::ClassDeclaration*>(declaration->variableStatementOrDeclaration)) {
        QString name = classDecl->name.toString();
        if (!name.isEmpty()) {
            Compiler::ExportEntry entry;
            entry.localName = name;
            entry.exportName = name;
            entry.location = location(classDecl->firstSourceLocation());
            _context->exportEntries << entry;
            if (declaration->exportDefault)
                localNameForDefaultExport = entry.localName;
        }
    } else if (auto *fdef = declaration->variableStatementOrDeclaration->asFunctionDefinition()) {
        QString functionName;

        // Only function definitions for which we enter their name into the local environment
        // can result in exports. Nested expressions such as (function foo() {}) are not accessible
        // as locals and can only be exported as default exports (further down).
        auto ast = declaration->variableStatementOrDeclaration;
        if (AST::cast<AST::ExpressionStatement*>(ast) || AST::cast<AST::FunctionDeclaration*>(ast))
            functionName = fdef->name.toString();

        if (!functionName.isEmpty()) {
            Compiler::ExportEntry entry;
            entry.localName = functionName;
            entry.exportName = functionName;
            entry.location = location(fdef->firstSourceLocation());
            _context->exportEntries << entry;
            if (declaration->exportDefault)
                localNameForDefaultExport = entry.localName;
        }
    }

    if (declaration->exportDefault) {
        Compiler::ExportEntry entry;
        entry.localName = localNameForDefaultExport;
        _context->localNameForDefaultExport = localNameForDefaultExport;
        entry.exportName = QStringLiteral("default");
        entry.location = location(declaration->firstSourceLocation());
        _context->exportEntries << entry;
    }

    return true; // scan through potential assignment expression code, etc.
}

bool ScanFunctions::visit(ImportDeclaration *declaration)
{
    QString module;
    if (declaration->fromClause) {
        module = declaration->fromClause->moduleSpecifier.toString();
        if (!module.isEmpty())
            _context->moduleRequests << module;
    }

    if (!declaration->moduleSpecifier.isEmpty())
        _context->moduleRequests << declaration->moduleSpecifier.toString();

    if (ImportClause *import = declaration->importClause) {
        if (!import->importedDefaultBinding.isEmpty()) {
            Compiler::ImportEntry entry;
            entry.moduleRequest = module;
            entry.importName = QStringLiteral("default");
            entry.localName = import->importedDefaultBinding.toString();
            entry.location = location(declaration->firstSourceLocation());
            _context->importEntries << entry;
        }

        if (import->nameSpaceImport) {
            Compiler::ImportEntry entry;
            entry.moduleRequest = module;
            entry.importName = QStringLiteral("*");
            entry.localName = import->nameSpaceImport->importedBinding.toString();
            entry.location = location(declaration->firstSourceLocation());
            _context->importEntries << entry;
        }

        if (import->namedImports) {
            for (ImportsList *it = import->namedImports->importsList; it; it = it->next) {
                Compiler::ImportEntry entry;
                entry.moduleRequest = module;
                entry.localName = it->importSpecifier->importedBinding.toString();
                if (!it->importSpecifier->identifier.isEmpty())
                    entry.importName = it->importSpecifier->identifier.toString();
                else
                    entry.importName = entry.localName;
                entry.location = location(declaration->firstSourceLocation());
                _context->importEntries << entry;
            }
        }
    }
    return false;
}

bool ScanFunctions::visit(CallExpression *ast)
{
    if (!_context->hasDirectEval) {
        if (IdentifierExpression *id = cast<IdentifierExpression *>(ast->base)) {
            if (id->name == QLatin1String("eval")) {
                if (_context->usesArgumentsObject == Context::ArgumentsObjectUnknown)
                    _context->usesArgumentsObject = Context::ArgumentsObjectUsed;
                _context->hasDirectEval = true;
            }
        }
    }
    return true;
}

bool ScanFunctions::visit(PatternElement *ast)
{
    if (!ast->isVariableDeclaration())
        return true;

    BoundNames names;
    ast->boundNames(&names);

    QQmlJS::SourceLocation lastInitializerLocation = ast->lastSourceLocation();
    if (_context->lastBlockInitializerLocation.isValid())
        lastInitializerLocation = _context->lastBlockInitializerLocation;

    for (const auto &name : qAsConst(names)) {
        if (_context->isStrict && (name.id == QLatin1String("eval") || name.id == QLatin1String("arguments")))
            _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
        checkName(QStringRef(&name.id), ast->identifierToken);
        if (name.id == QLatin1String("arguments"))
            _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
        if (ast->scope == VariableScope::Const && !ast->initializer && !ast->isForDeclaration && !ast->destructuringPattern()) {
            _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Missing initializer in const declaration"));
            return false;
        }
        if (!_context->addLocalVar(name.id, ast->initializer ? Context::VariableDefinition : Context::VariableDeclaration, ast->scope,
                                   /*function*/nullptr, lastInitializerLocation)) {
            _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name.id));
            return false;
        }
    }
    return true;
}

bool ScanFunctions::visit(IdentifierExpression *ast)
{
    checkName(ast->name, ast->identifierToken);
    if (_context->usesArgumentsObject == Context::ArgumentsObjectUnknown && ast->name == QLatin1String("arguments"))
        _context->usesArgumentsObject = Context::ArgumentsObjectUsed;
    _context->addUsedVariable(ast->name.toString());
    return true;
}

bool ScanFunctions::visit(ExpressionStatement *ast)
{
    if (FunctionExpression* expr = AST::cast<AST::FunctionExpression*>(ast->expression)) {
        if (!_allowFuncDecls)
            _cg->throwSyntaxError(expr->functionToken, QStringLiteral("conditional function or closure declaration"));

        if (!enterFunction(expr, /*enterName*/ true))
            return false;
        Node::accept(expr->formals, this);
        Node::accept(expr->body, this);
        leaveEnvironment();
        return false;
    } else {
        SourceLocation firstToken = ast->firstSourceLocation();
        if (_sourceCode.midRef(firstToken.offset, firstToken.length) == QLatin1String("function")) {
            _cg->throwSyntaxError(firstToken, QStringLiteral("unexpected token"));
        }
    }
    return true;
}

bool ScanFunctions::visit(FunctionExpression *ast)
{
    return enterFunction(ast, /*enterName*/ false);
}

bool ScanFunctions::visit(ClassExpression *ast)
{
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Class"));
    _context->isStrict = true;
    _context->hasNestedFunctions = true;
    if (!ast->name.isEmpty())
        _context->addLocalVar(ast->name.toString(), Context::VariableDefinition, AST::VariableScope::Const);
    return true;
}

void ScanFunctions::endVisit(ClassExpression *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ClassDeclaration *ast)
{
    if (!ast->name.isEmpty())
        _context->addLocalVar(ast->name.toString(), Context::VariableDeclaration, AST::VariableScope::Let);

    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Class"));
    _context->isStrict = true;
    _context->hasNestedFunctions = true;
    if (!ast->name.isEmpty())
        _context->addLocalVar(ast->name.toString(), Context::VariableDefinition, AST::VariableScope::Const);
    return true;
}

void ScanFunctions::endVisit(ClassDeclaration *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(TemplateLiteral *ast)
{
    while (ast) {
        if (ast->expression)
            Node::accept(ast->expression, this);
        ast = ast->next;
    }
    return true;

}

bool ScanFunctions::visit(SuperLiteral *)
{
    Context *c = _context;
    bool needContext = false;
    while (c && (c->contextType == ContextType::Block || c->isArrowFunction)) {
        needContext |= c->isArrowFunction;
        c = c->parent;
    }

    c->requiresExecutionContext |= needContext;

    return false;
}

bool ScanFunctions::visit(FieldMemberExpression *ast)
{
    if (AST::IdentifierExpression *id = AST::cast<AST::IdentifierExpression *>(ast->base)) {
        if (id->name == QLatin1String("new")) {
            // new.target
            if (ast->name != QLatin1String("target")) {
                _cg->throwSyntaxError(ast->identifierToken, QLatin1String("Expected 'target' after 'new.'."));
                return false;
            }
            Context *c = _context;
            bool needContext = false;
            while (c->contextType == ContextType::Block || c->isArrowFunction) {
                needContext |= c->isArrowFunction;
                c = c->parent;
            }
            c->requiresExecutionContext |= needContext;
            c->innerFunctionAccessesNewTarget |= needContext;

            return false;
        }
    }

    return true;
}

bool ScanFunctions::visit(ArrayPattern *ast)
{
    for (PatternElementList *it = ast->elements; it; it = it->next)
        Node::accept(it->element, this);

    return false;
}

bool ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
{
    if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
        _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode"));
    return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName);
}

void ScanFunctions::endVisit(FunctionExpression *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ObjectPattern *ast)
{
    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
    Node::accept(ast->properties, this);
    return false;
}

bool ScanFunctions::visit(PatternProperty *ast)
{
    Q_UNUSED(ast);
    // ### Shouldn't be required anymore
//    if (ast->type == PatternProperty::Getter || ast->type == PatternProperty::Setter) {
//        TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
//        return enterFunction(ast, QString(), ast->formals, ast->functionBody, /*enterName */ false);
//    }
    return true;
}

void ScanFunctions::endVisit(PatternProperty *)
{
    // ###
//    if (ast->type == PatternProperty::Getter || ast->type == PatternProperty::Setter)
//        leaveEnvironment();
}

bool ScanFunctions::visit(FunctionDeclaration *ast)
{
    return enterFunction(ast, /*enterName*/ true);
}

void ScanFunctions::endVisit(FunctionDeclaration *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(DoWhileStatement *ast) {
    {
        TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
        Node::accept(ast->statement, this);
    }
    Node::accept(ast->expression, this);
    return false;
}

bool ScanFunctions::visit(ForStatement *ast) {
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%For"));
    Node::accept(ast->initialiser, this);
    Node::accept(ast->declarations, this);
    Node::accept(ast->condition, this);
    Node::accept(ast->expression, this);

    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
    Node::accept(ast->statement, this);

    return false;
}

void ScanFunctions::endVisit(ForStatement *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ForEachStatement *ast) {
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Foreach"));
    if (ast->expression)
        _context->lastBlockInitializerLocation = ast->expression->lastSourceLocation();
    Node::accept(ast->lhs, this);
    Node::accept(ast->expression, this);

    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
    Node::accept(ast->statement, this);

    return false;
}

void ScanFunctions::endVisit(ForEachStatement *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ThisExpression *)
{
    _context->usesThis = true;
    return false;
}

bool ScanFunctions::visit(Block *ast)
{
    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls);
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Block"));
    Node::accept(ast->statements, this);
    return false;
}

void ScanFunctions::endVisit(Block *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(CaseBlock *ast)
{
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%CaseBlock"));
    return true;
}

void ScanFunctions::endVisit(CaseBlock *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(Catch *ast)
{
    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls);
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%CatchBlock"));
    _context->isCatchBlock = true;
    QString caughtVar = ast->patternElement->bindingIdentifier.toString();
    if (caughtVar.isEmpty())
        caughtVar = QStringLiteral("@caught");
    _context->addLocalVar(caughtVar, Context::MemberType::VariableDefinition, VariableScope::Let);

    _context->caughtVariable = caughtVar;
    if (_context->isStrict &&
        (caughtVar == QLatin1String("eval") || caughtVar == QLatin1String("arguments"))) {
        _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Catch variable name may not be eval or arguments in strict mode"));
        return false;
    }
    Node::accept(ast->patternElement, this);
    // skip the block statement
    Node::accept(ast->statement->statements, this);
    return false;
}

void ScanFunctions::endVisit(Catch *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(WithStatement *ast)
{
    Node::accept(ast->expression, this);

    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls);
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%WithBlock"));
    _context->isWithBlock = true;

    if (_context->isStrict) {
        _cg->throwSyntaxError(ast->withToken, QStringLiteral("'with' statement is not allowed in strict mode"));
        return false;
    }
    Node::accept(ast->statement, this);

    return false;
}

void ScanFunctions::endVisit(WithStatement *)
{
    leaveEnvironment();
}

bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, bool enterName)
{
    Context *outerContext = _context;
    enterEnvironment(ast, ContextType::Function, name);

    FunctionExpression *expr = AST::cast<FunctionExpression *>(ast);
    if (!expr)
        expr = AST::cast<FunctionDeclaration *>(ast);
    if (outerContext) {
        outerContext->hasNestedFunctions = true;
        // The identifier of a function expression cannot be referenced from the enclosing environment.
        if (enterName) {
            if (!outerContext->addLocalVar(name, Context::FunctionDefinition, VariableScope::Var, expr)) {
                _cg->throwSyntaxError(ast->firstSourceLocation(), QStringLiteral("Identifier %1 has already been declared").arg(name));
                return false;
            }
            outerContext->addLocalVar(name, Context::FunctionDefinition, VariableScope::Var, expr);
        }
        if (name == QLatin1String("arguments"))
            outerContext->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
    }

    _context->name = name;
    if (formals && formals->containsName(QStringLiteral("arguments")))
        _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
    if (expr) {
        if (expr->isArrowFunction)
            _context->isArrowFunction = true;
        else if (expr->isGenerator)
            _context->isGenerator = true;

        if (expr->typeAnnotation)
            _context->returnType = expr->typeAnnotation->type->toString();
    }


    if (!enterName && (!name.isEmpty() && (!formals || !formals->containsName(name))))
        _context->addLocalVar(name, Context::ThisFunctionName, VariableScope::Var);
    _context->formals = formals;

    if (body && !_context->isStrict)
        checkDirectivePrologue(body);

    bool isSimpleParameterList = formals && formals->isSimpleParameterList();

    _context->arguments = formals ? formals->formals() : BoundNames();

    const BoundNames boundNames = formals ? formals->boundNames() : BoundNames();
    for (int i = 0; i < boundNames.size(); ++i) {
        const QString &arg = boundNames.at(i).id;
        if (_context->isStrict || !isSimpleParameterList) {
            bool duplicate = (boundNames.indexOf(arg, i + 1) != -1);
            if (duplicate) {
                _cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("Duplicate parameter name '%1' is not allowed.").arg(arg));
                return false;
            }
        }
        if (_context->isStrict) {
            if (arg == QLatin1String("eval") || arg == QLatin1String("arguments")) {
                _cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("'%1' cannot be used as parameter name in strict mode").arg(arg));
                return false;
            }
        }
        if (!_context->arguments.contains(arg))
            _context->addLocalVar(arg, Context::VariableDefinition, VariableScope::Var);
    }

    return true;
}

void ScanFunctions::calcEscapingVariables()
{
    Module *m = _cg->_module;

    for (Context *inner : qAsConst(m->contextMap)) {
        if (inner->usesArgumentsObject != Context::ArgumentsObjectUsed)
            continue;
        if (inner->contextType != ContextType::Block && !inner->isArrowFunction)
            continue;
        Context *c = inner->parent;
        while (c && (c->contextType == ContextType::Block || c->isArrowFunction))
            c = c->parent;
        if (c)
            c->usesArgumentsObject = Context::ArgumentsObjectUsed;
        inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
    }
    for (Context *inner : qAsConst(m->contextMap)) {
        if (!inner->parent || inner->usesArgumentsObject == Context::ArgumentsObjectUnknown)
            inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
        if (inner->usesArgumentsObject == Context::ArgumentsObjectUsed) {
            QString arguments = QStringLiteral("arguments");
            inner->addLocalVar(arguments, Context::VariableDeclaration, AST::VariableScope::Var);
            if (!inner->isStrict) {
                inner->argumentsCanEscape = true;
                inner->requiresExecutionContext = true;
            }
        }
    }

    for (Context *c : qAsConst(m->contextMap)) {
        if (c->contextType != ContextType::ESModule)
            continue;
        for (const auto &entry: c->exportEntries) {
            auto mIt = c->members.constFind(entry.localName);
            if (mIt != c->members.constEnd())
                mIt->canEscape = true;
        }
        break;
    }

    for (Context *inner : qAsConst(m->contextMap)) {
        for (const QString &var : qAsConst(inner->usedVariables)) {
            Context *c = inner;
            while (c) {
                Context *current = c;
                c = c->parent;
                if (current->isWithBlock || current->contextType != ContextType::Block)
                    break;
            }
            Q_ASSERT(c != inner);
            while (c) {
                Context::MemberMap::const_iterator it = c->members.constFind(var);
                if (it != c->members.constEnd()) {
                    if (c->parent || it->isLexicallyScoped()) {
                        it->canEscape = true;
                        c->requiresExecutionContext = true;
                    } else if (c->contextType == ContextType::ESModule) {
                        // Module instantiation provides a context, but vars used from inner
                        // scopes need to be stored in its locals[].
                        it->canEscape = true;
                    }
                    break;
                }
                if (c->findArgument(var) != -1) {
                    c->argumentsCanEscape = true;
                    c->requiresExecutionContext = true;
                    break;
                }
                c = c->parent;
            }
        }
        if (inner->hasDirectEval) {
            inner->hasDirectEval = false;
            inner->innerFunctionAccessesNewTarget = true;
            if (!inner->isStrict) {
                Context *c = inner;
                while (c->contextType == ContextType::Block) {
                    c = c->parent;
                }
                Q_ASSERT(c);
                c->hasDirectEval = true;
                c->innerFunctionAccessesThis = true;
            }
            Context *c = inner;
            while (c) {
                c->allVarsEscape = true;
                c = c->parent;
            }
        }
        if (inner->usesThis) {
            inner->usesThis = false;
            bool innerFunctionAccessesThis = false;
            Context *c = inner;
            while (c->contextType == ContextType::Block || c->isArrowFunction) {
                innerFunctionAccessesThis |= c->isArrowFunction;
                c = c->parent;
            }
            Q_ASSERT(c);
            if (!inner->isStrict)
                c->usesThis = true;
            c->innerFunctionAccessesThis |= innerFunctionAccessesThis;
        }
    }
    for (Context *c : qAsConst(m->contextMap)) {
        if (c->innerFunctionAccessesThis) {
            // add an escaping 'this' variable
            c->addLocalVar(QStringLiteral("this"), Context::VariableDefinition, VariableScope::Let);
            c->requiresExecutionContext = true;
            auto mIt = c->members.constFind(QStringLiteral("this"));
            Q_ASSERT(mIt != c->members.constEnd());
            mIt->canEscape = true;
        }
        if (c->innerFunctionAccessesNewTarget) {
            // add an escaping 'new.target' variable
            c->addLocalVar(QStringLiteral("new.target"), Context::VariableDefinition, VariableScope::Let);
            c->requiresExecutionContext = true;
            auto mIt = c->members.constFind(QStringLiteral("new.target"));
            Q_ASSERT(mIt != c->members.constEnd());
            mIt->canEscape = true;
        }
        if (c->allVarsEscape && c->contextType == ContextType::Block && c->members.isEmpty())
            c->allVarsEscape = false;
        if (c->contextType == ContextType::Global || c->contextType == ContextType::ScriptImportedByQML || (!c->isStrict && c->contextType == ContextType::Eval) || m->debugMode)
            c->allVarsEscape = true;
        if (c->allVarsEscape) {
            if (c->parent) {
                c->requiresExecutionContext = true;
                c->argumentsCanEscape = true;
            } else {
                for (const auto &m : qAsConst(c->members)) {
                    if (m.isLexicallyScoped()) {
                        c->requiresExecutionContext = true;
                        break;
                    }
                }
            }
        }
        if (c->contextType == ContextType::Block && c->isCatchBlock) {
            c->requiresExecutionContext = true;
            auto mIt = c->members.constFind(c->caughtVariable);
            Q_ASSERT(mIt != c->members.constEnd());
            mIt->canEscape = true;
        }
        const QLatin1String exprForOn("expression for on");
        if (c->contextType == ContextType::Binding && c->name.length() > exprForOn.size() &&
            c->name.startsWith(exprForOn) && c->name.at(exprForOn.size()).isUpper())
            // we don't really need this for bindings, but we do for signal handlers, and in this case,
            // we don't know if the code is a signal handler or not.
            c->requiresExecutionContext = true;
        if (c->allVarsEscape) {
            for (const auto &m : qAsConst(c->members))
                m.canEscape = true;
        }
    }

    static const bool showEscapingVars = qEnvironmentVariableIsSet("QV4_SHOW_ESCAPING_VARS");
    if (showEscapingVars) {
        qDebug() << "==== escaping variables ====";
        for (Context *c : qAsConst(m->contextMap)) {
            qDebug() << "Context" << c << c->name << "requiresExecutionContext" << c->requiresExecutionContext << "isStrict" << c->isStrict;
            qDebug() << "    isArrowFunction" << c->isArrowFunction << "innerFunctionAccessesThis" << c->innerFunctionAccessesThis;
            qDebug() << "    parent:" << c->parent;
            if (c->argumentsCanEscape)
                qDebug() << "    Arguments escape";
            for (auto it = c->members.constBegin(); it != c->members.constEnd(); ++it) {
                qDebug() << "    " << it.key() << it.value().index << it.value().canEscape << "isLexicallyScoped:" << it.value().isLexicallyScoped();
            }
        }
    }
}

void ScanFunctions::throwRecursionDepthError()
{
    _cg->throwRecursionDepthError();
}
