"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const scopeManager_1 = require("../scopeManager");
const assert = require("assert");
const referencer_1 = require("../referencer");
const reference_1 = require("../reference");
const childScopesTraverser_1 = require("./childScopesTraverser");
const exportManager_1 = require("../exportManager");
const virtualScope_1 = require("./virtualScope");
const importManager_1 = require("../importManager");
Object.defineProperty(Array.prototype, "flatMap", {
    value(f) {
        return this.reduce((ys, x) => {
            return ys.concat(f.call(this, x));
        }, []);
    },
    enumerable: false,
});
class ModuleAnalyser {
    constructor(name, module, scopeManager = null) {
        this.name = name;
        this.module = module;
        this.scopeManager = scopeManager;
        this.extractorMap = new Map();
        this.virtualScopeMap = new WeakMap();
        this.virtualScopes = [];
        this.initVirtualScopes = [];
        this.comments = [];
        this.handleNotExportReferences = (refs) => {
            const moduleScopeRefs = refs.filter(ref => ref.resolved && ref.resolved.scope.type === "module");
            const pureVScopes = this.virtualScopes.filter(vs => vs.contentType === virtualScope_1.VScopeContentType.PureFunctionCall);
            const nodeContains = (node, [start, end]) => {
                return node.start >= start && node.end <= end;
            };
            moduleScopeRefs.forEach(ref => {
                for (const vs of pureVScopes) {
                    if (vs instanceof virtualScope_1.VariableVirtualScope) {
                        const range = vs.pureRange;
                        if (nodeContains(ref.identifier, range)) {
                            return;
                        }
                    }
                }
                const resolvedName = ref.resolved;
                const vs = this.virtualScopeMap.get(resolvedName);
                if (!ref.init) {
                    this.initVirtualScopes.push(vs);
                }
            });
        };
    }
    defaultOptions() {
        return {
            optimistic: false,
            directive: false,
            nodejsScope: false,
            impliedStrict: false,
            sourceType: "module",
            ecmaVersion: 6,
            childVisitorKeys: null,
            fallback: "iteration",
            comments: [],
        };
    }
    analyze(tree, providedOptions) {
        const options = this.updateDeeply(this.defaultOptions(), providedOptions);
        this.comments = options.comments;
        const scopeManager = new scopeManager_1.ScopeManager(options);
        const referencer = new referencer_1.Referencer(options, scopeManager);
        referencer.visit(tree);
        assert(scopeManager.__currentScope === null, "currentScope should be null.");
        this.scopeManager = scopeManager;
        const pureCommentEndsSet = this.processComments();
        const { moduleScope } = this;
        moduleScope.variables.forEach(variable => {
            let virtualScope;
            if (moduleScope.importManager.idMap.get(variable.name)) {
                virtualScope = new virtualScope_1.VariableVirtualScope(virtualScope_1.VScopeContentType.Import, variable);
            }
            else {
                const def = variable.defs[0];
                switch (def.node.type) {
                    case "FunctionDeclaration":
                        virtualScope = new virtualScope_1.VariableVirtualScope(virtualScope_1.VScopeContentType.FunctionDeclaration, variable);
                        break;
                    case "ClassDeclaration":
                        virtualScope = new virtualScope_1.VariableVirtualScope(virtualScope_1.VScopeContentType.ClassDeclaration, variable);
                        break;
                    case "VariableDeclarator":
                        let isChildrenDependent = true;
                        if (def.node.init) {
                            const { init } = def.node;
                            if (["let", "var", "const"].indexOf(def.kind) < 0) {
                                throw new TypeError("def.kind muse be in ['let', 'var', 'const']");
                            }
                            if (def.kind === "let" || def.kind === "var") {
                                for (let i = 1; i < variable.references.length; i++) {
                                    const ref = variable.references[i];
                                    if (ref.flag === reference_1.Reference.WRITE || ref.flag === reference_1.Reference.RW) {
                                        isChildrenDependent = false;
                                        break;
                                    }
                                }
                            }
                            let scopeType = virtualScope_1.VScopeContentType.Undefined;
                            switch (init.type) {
                                case "ClassExpression":
                                    scopeType = virtualScope_1.VScopeContentType.ClassExpression;
                                    break;
                                case "FunctionExpression":
                                    scopeType = virtualScope_1.VScopeContentType.FunctionExpression;
                                    break;
                                case "ArrowFunctionExpression":
                                    scopeType = virtualScope_1.VScopeContentType.ArrowFunction;
                                    break;
                                case "CallExpression":
                                    if (pureCommentEndsSet.has(init.range[0])) {
                                        scopeType = virtualScope_1.VScopeContentType.PureFunctionCall;
                                    }
                                    else {
                                        scopeType = virtualScope_1.VScopeContentType.NormalFunctionCall;
                                    }
                            }
                            virtualScope = new virtualScope_1.VariableVirtualScope(scopeType, variable, isChildrenDependent);
                        }
                        else {
                            virtualScope = new virtualScope_1.VariableVirtualScope(virtualScope_1.VScopeContentType.Undefined, variable, false);
                        }
                        break;
                    default:
                        virtualScope = new virtualScope_1.VariableVirtualScope(virtualScope_1.VScopeContentType.Undefined, variable, false);
                }
            }
            this.virtualScopeMap.set(variable, virtualScope);
            this.virtualScopes.push(virtualScope);
        });
        const visitedSet = new WeakSet();
        this.handleExportDefaultDeclaration();
        this.virtualScopes.forEach(vs => vs.findAllReferencesToVirtualScope(visitedSet, scopeManager, this.virtualScopeMap));
        const independentScopes = moduleScope.childScopes.filter(item => !visitedSet.has(item));
        this.traverseIndependentScopes(independentScopes);
        this.handleNotExportReferences(moduleScope.references.filter(ref => !ref.isExport));
    }
    processComments() {
        const pureCommentEndsSet = new Set();
        this.comments.forEach(comment => {
            if (comment.type === "Block" && /(@|#)__PURE__/.test(comment.value)) {
                pureCommentEndsSet.add(comment.end);
            }
        });
        return pureCommentEndsSet;
    }
    handleExportDefaultDeclaration() {
        const moduleScope = this.moduleScope;
        const { exportManager } = moduleScope;
        if (exportManager.exportDefaultDeclaration) {
            let vsType;
            switch (exportManager.exportDefaultDeclaration.type) {
                case "FunctionDeclaration":
                    vsType = virtualScope_1.VScopeContentType.FunctionDeclaration;
                    break;
                case "ArrowFunctionExpression":
                    vsType = virtualScope_1.VScopeContentType.ArrowFunction;
                    break;
                case "ClassDeclaration":
                    vsType = virtualScope_1.VScopeContentType.ClassDeclaration;
                    break;
                case "ClassExpression":
                    vsType = virtualScope_1.VScopeContentType.ClassExpression;
                    break;
                case "Identifier":
                    vsType = virtualScope_1.VScopeContentType.Reference;
                    break;
                default:
                    return;
            }
            this.virtualScopes.push(new virtualScope_1.ExportDefaultVirtualScope(vsType, exportManager.exportDefaultDeclaration, true));
        }
    }
    generateExportInfo(usedExports) {
        const { exportManager } = this.moduleScope;
        const resultList = [];
        const moduleScopeIds = [];
        for (let i = 0; i < usedExports.length; i++) {
            const usedExport = usedExports[i];
            const exportVar = exportManager.exportsMap.get(usedExport);
            if (typeof exportVar === "undefined") {
                continue;
            }
            switch (exportVar.type) {
                case exportManager_1.ExportVariableType.Local:
                    if (exportVar.localName !== null || exportVar.exportName === "default") {
                        moduleScopeIds.push(exportVar.localName || exportVar.exportName);
                    }
                    break;
                case exportManager_1.ExportVariableType.External:
                    if (exportVar.moduleType === exportManager_1.ExternalType.Identifier) {
                        resultList.push({
                            sourceName: exportVar.names.sourceName,
                            moduleName: exportVar.moduleName,
                        });
                    }
                    break;
            }
        }
        const visitedVScope = new WeakSet();
        const traverseVirtualScope = (vs) => {
            if (visitedVScope.has(vs))
                return;
            visitedVScope.add(vs);
            if (vs.type === virtualScope_1.VirtualScopeType.Variable) {
                const varVScope = vs;
                if (vs.contentType === virtualScope_1.VScopeContentType.Import) {
                    const name = varVScope.variable.name;
                    const importInfo = this.moduleScope.importManager.idMap.get(name);
                    if (importInfo.type === importManager_1.ImportType.Namespace) {
                        resultList.push({
                            sourceName: true,
                            moduleName: importInfo.moduleName,
                        });
                    }
                    else {
                        resultList.push({
                            sourceName: importInfo.sourceName,
                            moduleName: importInfo.moduleName,
                        });
                    }
                }
            }
            for (const child of vs.children) {
                traverseVirtualScope(child);
            }
        };
        this.initVirtualScopes.forEach(traverseVirtualScope);
        moduleScopeIds.forEach(id => {
            if (id === "default") {
                const defaultVs = this.virtualScopes.filter(vs => vs.type === virtualScope_1.VirtualScopeType.Default);
                defaultVs.forEach(vs => traverseVirtualScope(vs));
            }
            else {
                const variable = this.moduleScope.set.get(id);
                const vs = this.virtualScopeMap.get(variable);
                traverseVirtualScope(vs);
            }
        });
        const resultMap = {};
        for (const entity of resultList) {
            const { sourceName, moduleName } = entity;
            if (resultMap[moduleName] === true)
                continue;
            if (sourceName === true) {
                resultMap[moduleName] = true;
            }
            else if (moduleName in resultMap) {
                resultMap[moduleName].add(sourceName);
            }
            else {
                resultMap[moduleName] = new Set([sourceName]);
            }
        }
        for (const key in resultMap) {
            if (resultMap.hasOwnProperty(key)) {
                const value = resultMap[key];
                if (value !== true) {
                    resultMap[key] = [...value].sort();
                }
            }
        }
        return resultMap;
    }
    traverseIndependentScopes(scopes) {
        for (const scope of scopes) {
            const traverser = new childScopesTraverser_1.ChildScopesTraverser(scope);
            traverser.refsToModule.forEach(ref => {
                const variable = this.moduleScope.set.get(ref);
                const vs = this.virtualScopeMap.get(variable);
                this.initVirtualScopes.push(vs);
            });
        }
    }
    updateDeeply(target, override) {
        function isHashObject(value) {
            return (typeof value === "object" &&
                value instanceof Object &&
                !(value instanceof Array) &&
                !(value instanceof RegExp));
        }
        for (const key in override) {
            if (override.hasOwnProperty(key)) {
                const val = override[key];
                if (isHashObject(val)) {
                    if (isHashObject(target[key])) {
                        this.updateDeeply(target[key], val);
                    }
                    else {
                        target[key] = this.updateDeeply({}, val);
                    }
                }
                else {
                    target[key] = val;
                }
            }
        }
        return target;
    }
    get moduleScope() {
        return this.scopeManager.scopes[1];
    }
}
exports.ModuleAnalyser = ModuleAnalyser;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlQW5hbHlzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYW5hbHlzZXIvbW9kdWxlQW5hbHlzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxrREFBK0M7QUFFL0MsaUNBQWlDO0FBQ2pDLDhDQUEyQztBQUczQyw0Q0FBeUM7QUFFekMsaUVBQXFGO0FBQ3JGLG9EQUFvRTtBQUVwRSxpREFNd0I7QUFDeEIsb0RBQThDO0FBWTlDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUU7SUFDaEQsS0FBSyxDQUFjLENBQU07UUFDdkIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBTyxFQUFFLENBQU0sRUFBRSxFQUFFO1lBQ3JDLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNULENBQUM7SUFDRCxVQUFVLEVBQUUsS0FBSztDQUNsQixDQUFDLENBQUM7QUFFSDtJQVNFLFlBQ2tCLElBQVksRUFDWixNQUFXLEVBQ3BCLGVBQW9DLElBQUk7UUFGL0IsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUNaLFdBQU0sR0FBTixNQUFNLENBQUs7UUFDcEIsaUJBQVksR0FBWixZQUFZLENBQTRCO1FBWGpDLGlCQUFZLEdBQXVDLElBQUksR0FBRyxFQUFFLENBQUM7UUFFN0Qsb0JBQWUsR0FBb0MsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNqRSxrQkFBYSxHQUFtQixFQUFFLENBQUM7UUFDbkMsc0JBQWlCLEdBQW1CLEVBQUUsQ0FBQztRQUUvQyxhQUFRLEdBQWUsRUFBRSxDQUFDO1FBNFQxQiw4QkFBeUIsR0FBRyxDQUFDLElBQWlCLEVBQUUsRUFBRTtZQUN4RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUNqQyxH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