Merge pull request #6904 from webpack/performance/concat

avoid walking scopes multiple times for performance reasons
This commit is contained in:
Tobias Koppers 2018-04-04 11:29:42 +02:00 committed by GitHub
commit 1958784433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 18 deletions

View File

@ -168,17 +168,29 @@ const getFinalName = (
}
};
const getSymbolsFromScope = (s, untilScope) => {
const allUsedNames = new Set();
const addScopeSymbols1 = (s, nameSet, scopeSet) => {
let scope = s;
while (scope) {
if (scopeSet.has(scope)) break;
scopeSet.add(scope);
for (const variable of scope.variables) {
allUsedNames.add(variable.name);
nameSet.add(variable.name);
}
scope = scope.upper;
}
};
const addScopeSymbols2 = (s, nameSet, scopeSet1, scopeSet2) => {
let scope = s;
while (scope) {
if (scopeSet1.has(scope)) break;
if (scopeSet2.has(scope)) break;
scopeSet1.add(scope);
for (const variable of scope.variables) {
nameSet.add(variable.name);
}
if (untilScope === scope) break;
scope = scope.upper;
}
return allUsedNames;
};
const getAllReferences = variable => {
@ -196,11 +208,6 @@ const getAllReferences = variable => {
return set;
};
const reduceSet = (a, b) => {
for (const item of b) a.add(item);
return a;
};
const getPathInAst = (ast, node) => {
if (ast === node) {
return [];
@ -816,8 +823,31 @@ class ConcatenatedModule extends Module {
"onsubmit"
]);
// Set of already checked scopes
const alreadyCheckedScopes = new Set();
// get all global names
for (const info of modulesWithInfo) {
const superClassExpressions = [];
// ignore symbols from moduleScope
if (info.moduleScope) {
alreadyCheckedScopes.add(info.moduleScope);
// The super class expression in class scopes behaves weird
// We store ranges of all super class expressions to make
// renaming to work correctly
for (const childScope of info.moduleScope.childScopes) {
if (childScope.type !== "class") continue;
if (!childScope.block.superClass) continue;
superClassExpressions.push({
range: childScope.block.superClass.range,
variables: childScope.variables
});
}
}
// add global symbols
if (info.globalScope) {
for (const reference of info.globalScope.through) {
const name = reference.identifier.name;
@ -826,12 +856,21 @@ class ConcatenatedModule extends Module {
name
)
) {
for (const s of getSymbolsFromScope(
reference.from,
info.moduleScope
)) {
allUsedNames.add(s);
for (const expr of superClassExpressions) {
if (
expr.range[0] <= reference.identifier.range[0] &&
expr.range[1] >= reference.identifier.range[1]
) {
for (const variable of expr.variables) {
allUsedNames.add(variable.name);
}
}
}
addScopeSymbols1(
reference.from,
allUsedNames,
alreadyCheckedScopes
);
} else {
allUsedNames.add(name);
}
@ -856,9 +895,16 @@ class ConcatenatedModule extends Module {
const name = variable.name;
if (allUsedNames.has(name)) {
const references = getAllReferences(variable);
const symbolsInReferences = references
.map(ref => getSymbolsFromScope(ref.from, info.moduleScope))
.reduce(reduceSet, new Set());
const symbolsInReferences = new Set();
const alreadyCheckedInnerScopes = new Set();
for (const ref of references) {
addScopeSymbols2(
ref.from,
symbolsInReferences,
alreadyCheckedInnerScopes,
alreadyCheckedScopes
);
}
const newName = this.findNewName(
name,
allUsedNames,

View File

@ -6,5 +6,15 @@ export function test() {
function file1_js_a() {
return "fail";
}
function file1_a() {
return "fail";
}
return a();
}
function renaming_4967_file1_js_a() {
return "fail";
}
function renaming_4967_file1_a() {
return "fail";
}