"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const scope_1 = require("./scope");
const assert = require("assert");
class ScopeManager {
    constructor(__options) {
        this.__options = __options;
        this.globalScope = null;
        this.__currentScope = null;
        this.scopes = [];
        this.__nodeToScope = new WeakMap();
        this.__declaredVariables = new WeakMap();
    }
    __useDirective() {
        return this.__options.directive;
    }
    __isOptimistic() {
        return this.__options.optimistic;
    }
    __ignoreEval() {
        return this.__options.ignoreEval;
    }
    __isNodejsScope() {
        return this.__options.nodejsScope;
    }
    isModule() {
        return this.__options.sourceType === "module";
    }
    isImpliedStrict() {
        return this.__options.impliedStrict;
    }
    isStrictModeSupported() {
        return this.__options.ecmaVersion >= 5;
    }
    __get(node) {
        return this.__nodeToScope.get(node);
    }
    getDeclaredVariables(node) {
        return this.__declaredVariables.get(node) || [];
    }
    acquire(node, inner) {
        function predicate(testScope) {
            if (testScope.type === "function" &&
                testScope.functionExpressionScope) {
                return false;
            }
            if (testScope.type === "TDZ") {
                return false;
            }
            return true;
        }
        const scopes = this.__get(node);
        if (!scopes || scopes.length === 0) {
            return null;
        }
        if (scopes.length === 1) {
            return scopes[0];
        }
        if (inner) {
            for (let i = scopes.length - 1; i >= 0; --i) {
                const scope = scopes[i];
                if (predicate(scope)) {
                    return scope;
                }
            }
        }
        else {
            for (let i = 0, iz = scopes.length; i < iz; ++i) {
                const scope = scopes[i];
                if (predicate(scope)) {
                    return scope;
                }
            }
        }
        return null;
    }
    acquireAll(node) {
        return this.__get(node);
    }
    release(node, inner) {
        const scopes = this.__get(node);
        if (scopes && scopes.length) {
            const scope = scopes[0].upper;
            if (!scope) {
                return null;
            }
            return this.acquire(scope.block, inner);
        }
        return null;
    }
    attach() { }
    detach() { }
    __nestScope(scope) {
        if (scope instanceof scope_1.GlobalScope) {
            assert(this.__currentScope === null);
            this.globalScope = scope;
        }
        this.__currentScope = scope;
        return scope;
    }
    __nestGlobalScope(node) {
        return this.__nestScope(new scope_1.GlobalScope(this, node));
    }
    __nestBlockScope(node) {
        return this.__nestScope(new scope_1.BlockScope(this, this.__currentScope, node));
    }
    __nestFunctionScope(node, isMethodDefinition) {
        return this.__nestScope(new scope_1.FunctionScope(this, this.__currentScope, node, isMethodDefinition));
    }
    __nestForScope(node) {
        return this.__nestScope(new scope_1.ForScope(this, this.__currentScope, node));
    }
    __nestCatchScope(node) {
        return this.__nestScope(new scope_1.CatchScope(this, this.__currentScope, node));
    }
    __nestWithScope(node) {
        return this.__nestScope(new scope_1.WithScope(this, this.__currentScope, node));
    }
    __nestClassScope(node) {
        return this.__nestScope(new scope_1.ClassScope(this, this.__currentScope, node));
    }
    __nestSwitchScope(node) {
        return this.__nestScope(new scope_1.SwitchScope(this, this.__currentScope, node));
    }
    __nestModuleScope(node) {
        return this.__nestScope(new scope_1.ModuleScope(this, this.__currentScope, node));
    }
    __nestTDZScope(node) {
        return this.__nestScope(new scope_1.TDZScope(this, this.__currentScope, node));
    }
    __nestFunctionExpressionNameScope(node) {
        return this.__nestScope(new scope_1.FunctionExpressionNameScope(this, this.__currentScope, node));
    }
    __isES6() {
        return this.__options.ecmaVersion >= 6;
    }
}
exports.ScopeManager = ScopeManager;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NvcGVNYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Njb3BlTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG1DQWFpQjtBQUVqQixpQ0FBaUM7QUFHakM7SUFDRSxZQUFtQyxTQUFjO1FBQWQsY0FBUyxHQUFULFNBQVMsQ0FBSztRQUUxQyxnQkFBVyxHQUFpQixJQUFJLENBQUM7UUFDakMsbUJBQWMsR0FBaUIsSUFBSSxDQUFDO1FBQzNCLFdBQU0sR0FBWSxFQUFFLENBQUM7UUFDckIsa0JBQWEsR0FHekIsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNGLHdCQUFtQixHQUcvQixJQUFJLE9BQU8sRUFBRSxDQUFDO0lBWmtDLENBQUM7SUFjOUMsY0FBYztRQUNuQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO0lBQ2xDLENBQUM7SUFFTSxjQUFjO1FBQ25CLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUM7SUFDbkMsQ0FBQztJQUVNLFlBQVk7UUFDakIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQztJQUNuQyxDQUFDO0lBRU0sZUFBZTtRQUNwQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDO0lBQ3BDLENBQUM7SUFFTSxRQUFRO1FBQ2IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUM7SUFDaEQsQ0FBQztJQUVNLGVBQWU7UUFDcEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQztJQUN0QyxDQUFDO0lBRU0scUJBQXFCO1FBQzFCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFHTSxLQUFLLENBQUMsSUFBaUI7UUFDNUIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QyxDQUFD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