Merge pull request #6904 from webpack/performance/concat
avoid walking scopes multiple times for performance reasons
This commit is contained in:
commit
1958784433
|
@ -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,
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue