"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const variable_1 = require("../variable");
const reference_1 = require("../reference");
const estraverse_1 = require("estraverse");
function isStrictScope(scope, block, isMethodDefinition, useDirective) {
    let body;
    if (scope.upper && scope.upper.isStrict) {
        return true;
    }
    if (block.type === estraverse_1.Syntax.ArrowFunctionExpression) {
        return true;
    }
    if (isMethodDefinition) {
        return true;
    }
    if (scope.type === "class" || scope.type === "module") {
        return true;
    }
    if (scope.type === "block" || scope.type === "switch") {
        return false;
    }
    if (scope.type === "function") {
        if (block.type === estraverse_1.Syntax.Program) {
            body = block;
        }
        else {
            body = block.body;
        }
        if (!body) {
            return false;
        }
    }
    else if (scope.type === "global") {
        body = block;
    }
    else {
        return false;
    }
    if (useDirective) {
        for (let i = 0, iz = body.body.length; i < iz; ++i) {
            const stmt = body.body[i];
            if (stmt.type !== estraverse_1.Syntax.DirectiveStatement) {
                break;
            }
            if (stmt.raw === '"use strict"' ||
                stmt.raw === "'use strict'") {
                return true;
            }
        }
    }
    else {
        for (let i = 0, iz = body.body.length; i < iz; ++i) {
            const stmt = body.body[i];
            if (stmt.type !== estraverse_1.Syntax.ExpressionStatement) {
                break;
            }
            const expr = stmt.expression;
            if (expr.type !== estraverse_1.Syntax.Literal ||
                typeof expr.value !== "string") {
                break;
            }
            if (expr.raw !== null && expr.raw !== undefined) {
                if (expr.raw === '"use strict"' ||
                    expr.raw === "'use strict'") {
                    return true;
                }
            }
            else {
                if (expr.value === "use strict") {
                    return true;
                }
            }
        }
    }
    return false;
}
function registerScope(scopeManager, scope) {
    scopeManager.scopes.push(scope);
    const scopes = scopeManager.__nodeToScope.get(scope.block);
    if (scopes) {
        scopes.push(scope);
    }
    else {
        scopeManager.__nodeToScope.set(scope.block, [scope]);
    }
}
function shouldBeStatically(def) {
    return (def.type === variable_1.VariableType.ClassName ||
        (def.type === variable_1.VariableType.Variable &&
            def.parent.kind !== "var"));
}
class Scope {
    constructor(scopeManager, type, upper = null, block, isMethodDefinition) {
        this.type = type;
        this.upper = upper;
        this.block = block;
        this.functionExpressionScope = false;
        this.directCallToEvalScope = false;
        this.thisFound = false;
        this.__left = [];
        this.set = new Map();
        this.taints = new Map();
        this.through = [];
        this.variables = [];
        this.references = [];
        this.childScopes = [];
        this.dynamic =
            this.type === "global" || this.type === "with";
        this.variableScope =
            this.type === "global" ||
                this.type === "function" ||
                this.type === "module"
                ? this
                : this.upper.variableScope;
        this.isStrict = isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective());
        if (this.upper) {
            this.upper.childScopes.push(this);
        }
        this.__declaredVariables = scopeManager.__declaredVariables;
        registerScope(scopeManager, this);
    }
    __shouldStaticallyClose(scopeManager) {
        return !this.dynamic || scopeManager.__isOptimistic();
    }
    __shouldStaticallyCloseForGlobal(ref) {
        const name = ref.identifier.name;
        if (!this.set.has(name)) {
            return false;
        }
        const variable = this.set.get(name);
        const defs = variable.defs;
        return defs.length > 0 && defs.every(shouldBeStatically);
    }
    __staticCloseRef(ref) {
        if (!this.__resolve(ref)) {
            this.__delegateToUpperScope(ref);
        }
    }
    __dynamicCloseRef(ref) {
        let current = this;
        do {
            current.through.push(ref);
            current = current.upper;
        } while (current);
    }
    __globalCloseRef(ref) {
        if (this.__shouldStaticallyCloseForGlobal(ref)) {
            this.__staticCloseRef(ref);
        }
        else {
            this.__dynamicCloseRef(ref);
        }
    }
    __close(scopeManager) {
        let closeRef;
        if (this.__shouldStaticallyClose(scopeManager)) {
            closeRef = this.__staticCloseRef;
        }
        else if (this.type !== "global") {
            closeRef = this.__dynamicCloseRef;
        }
        else {
            closeRef = this.__globalCloseRef;
        }
        for (let i = 0, iz = this.__left.length; i < iz; ++i) {
            const ref = this.__left[i];
            closeRef.call(this, ref);
        }
        this.__left = null;
        return this.upper;
    }
    __isValidResolution(ref, variable) {
        return true;
    }
    __resolve(ref) {
        const name = ref.identifier.name;
        if (!this.set.has(name)) {
            return false;
        }
        const variable = this.set.get(name);
        if (!this.__isValidResolution(ref, variable)) {
            return false;
        }
        variable.references.push(ref);
        variable.stack =
            variable.stack &&
                ref.from.variableScope === this.variableScope;
        if (ref.tainted) {
            variable.tainted = true;
            this.taints.set(variable.name, true);
        }
        ref.resolved = variable;
        return true;
    }
    __delegateToUpperScope(ref) {
        if (this.upper) {
            this.upper.__left.push(ref);
        }
        this.through.push(ref);
    }
    __addDeclaredVariablesOfNode(variable, node) {
        if (node === null || node === undefined) {
            return;
        }
        let variables = this.__declaredVariables.get(node);
        if (variables === null || variables === undefined) {
            variables = [];
            this.__declaredVariables.set(node, variables);
        }
        if (variables.indexOf(variable) === -1) {
            variables.push(variable);
        }
    }
    __defineGeneric(name, set, variables, node, def) {
        let variable;
        variable = set.get(name);
        if (!variable) {
            variable = new variable_1.Variable(name, this);
            set.set(name, variable);
            variables.push(variable);
        }
        if (def) {
            variable.defs.push(def);
            if (def.type !== variable_1.VariableType.TDZ) {
                this.__addDeclaredVariablesOfNode(variable, def.node);
                this.__addDeclaredVariablesOfNode(variable, def.parent);
            }
        }
        if (node) {
            variable.identifiers.push(node);
        }
        return variable;
    }
    __define(node, def) {
        if (node && node.type === estraverse_1.Syntax.Identifier) {
            return this.__defineGeneric(node.name, this.set, this.variables, node, def);
        }
        return null;
    }
    __referencing(node, assign, writeExpr, maybeImplicitGlobal, partial, init, isExportingFromLocal = false) {
        if (!node || node.type !== estraverse_1.Syntax.Identifier) {
            return;
        }
        if (node.name === "super") {
            return;
        }
        const ref = new reference_1.Reference(node, this, isExportingFromLocal
            ? reference_1.Reference.EXPORT
            : assign || reference_1.Reference.READ, writeExpr, maybeImplicitGlobal, !!partial, !!init);
        this.references.push(ref);
        this.__left.push(ref);
        return ref;
    }
    __detectEval() {
        let current = this;
        this.directCallToEvalScope = true;
        do {
            current.dynamic = true;
            current = current.upper;
        } while (current);
    }
    __detectThis() {
        this.thisFound = true;
    }
    __isClosed() {
        return this.__left === null;
    }
    resolve(ident) {
        let ref, i, iz;
        assert(this.__isClosed(), "Scope should be closed.");
        assert(ident.type === estraverse_1.Syntax.Identifier, "Target should be identifier.");
        for (i = 0, iz = this.references.length; i < iz; ++i) {
            ref = this.references[i];
            if (ref.identifier === ident) {
                return ref;
            }
        }
        return null;
    }
    isStatic() {
        return !this.dynamic;
    }
    isArgumentsMaterialized() {
        return true;
    }
    isThisMaterialized() {
        return true;
    }
    isUsedName(name) {
        if (this.set.has(name)) {
            return true;
        }
        for (let i = 0, iz = this.through.length; i < iz; ++i) {
            if (this.through[i].identifier.name === name) {
                return true;
            }
        }
        return false;
    }
}
exports.Scope = Scope;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NvcGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NvcGUvc2NvcGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBaUM7QUFDakMsMENBQXFEO0FBQ3JELDRDQUF5RDtBQUd6RCwyQ0FBb0M7QUFvQnBDLHVCQUNFLEtBQVksRUFDWixLQUFrQixFQUNsQixrQkFBMkIsRUFDM0IsWUFBcUI7SUFFckIsSUFBSSxJQUFJLENBQUM7SUFHVCxJQUFJLEtBQUssQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7UUFDdkMsT0FBTyxJQUFJLENBQUM7S0FDYjtJQUdELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxtQkFBTSxDQUFDLHVCQUF1QixFQUFFO1FBQ2pELE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFFRCxJQUFJLGtCQUFrQixFQUFFO1FBQ3RCLE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1FBQ3JELE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1FBQ3JELE9BQU8sS0FBSyxDQUFDO0tBQ2Q7SUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO1FBQzdCLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxtQkFBTSxDQUFDLE9BQU8sRUFBRTtZQUNqQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1NBQ2Q7YUFBTTtZQUNMLElBQUksR0FBSSxLQUFhLENBQUMsSUFBSSxDQUFDO1NBQzVCO1FBRUQsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNULE9BQU8sS0FBSyxDQUFDO1NBQ2Q7S0FDRjtTQUFNLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxRQUFR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