More critical path optimization in binder
This commit is contained in:
parent
66e9f7dc21
commit
5b4dffc2d7
1 changed files with 37 additions and 49 deletions
|
@ -1556,15 +1556,9 @@ namespace ts {
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.parent = parent;
|
node.parent = parent;
|
||||||
|
|
||||||
const saveInStrictMode = inStrictMode;
|
const saveInStrictMode = inStrictMode;
|
||||||
if (!saveInStrictMode) {
|
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
|
||||||
updateStrictMode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
|
|
||||||
// and then potentially add the symbol to an appropriate symbol table. Possible
|
// and then potentially add the symbol to an appropriate symbol table. Possible
|
||||||
// destination symbol tables are:
|
// destination symbol tables are:
|
||||||
//
|
//
|
||||||
|
@ -1572,56 +1566,40 @@ namespace ts {
|
||||||
// 2) The 'members' table of the current container's symbol.
|
// 2) The 'members' table of the current container's symbol.
|
||||||
// 3) The 'locals' table of the current container.
|
// 3) The 'locals' table of the current container.
|
||||||
//
|
//
|
||||||
// However, not all symbols will end up in any of these tables. 'Anonymous' symbols
|
// However, not all symbols will end up in any of these tables. 'Anonymous' symbols
|
||||||
// (like TypeLiterals for example) will not be put in any table.
|
// (like TypeLiterals for example) will not be put in any table.
|
||||||
bindWorker(node);
|
bindWorker(node);
|
||||||
|
// Then we recurse into the children of the node to bind them as well. For certain
|
||||||
// Then we recurse into the children of the node to bind them as well. For certain
|
// symbols we do specialized work when we recurse. For example, we'll keep track of
|
||||||
// symbols we do specialized work when we recurse. For example, we'll keep track of
|
// the current 'container' node when it changes. This helps us know which symbol table
|
||||||
// the current 'container' node when it changes. This helps us know which symbol table
|
// a local should go into for example. Since terminal nodes are known not to have
|
||||||
// a local should go into for example.
|
// children, as an optimization we don't process those.
|
||||||
const saveParent = parent;
|
if (node.kind > SyntaxKind.LastToken) {
|
||||||
parent = node;
|
const saveParent = parent;
|
||||||
const containerFlags = getContainerFlags(node);
|
parent = node;
|
||||||
if (containerFlags === ContainerFlags.None) {
|
const containerFlags = getContainerFlags(node);
|
||||||
bindChildren(node);
|
if (containerFlags === ContainerFlags.None) {
|
||||||
|
bindChildren(node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bindContainer(node, containerFlags);
|
||||||
|
}
|
||||||
|
parent = saveParent;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
bindContainer(node, containerFlags);
|
|
||||||
}
|
|
||||||
parent = saveParent;
|
|
||||||
|
|
||||||
inStrictMode = saveInStrictMode;
|
inStrictMode = saveInStrictMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStrictMode(node: Node) {
|
|
||||||
switch (node.kind) {
|
|
||||||
case SyntaxKind.SourceFile:
|
|
||||||
case SyntaxKind.ModuleBlock:
|
|
||||||
updateStrictModeStatementList((<SourceFile | ModuleBlock>node).statements);
|
|
||||||
return;
|
|
||||||
case SyntaxKind.Block:
|
|
||||||
if (isFunctionLike(node.parent)) {
|
|
||||||
updateStrictModeStatementList((<Block>node).statements);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case SyntaxKind.ClassDeclaration:
|
|
||||||
case SyntaxKind.ClassExpression:
|
|
||||||
// All classes are automatically in strict mode in ES6.
|
|
||||||
inStrictMode = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
|
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
|
||||||
for (const statement of statements) {
|
if (!inStrictMode) {
|
||||||
if (!isPrologueDirective(statement)) {
|
for (const statement of statements) {
|
||||||
return;
|
if (!isPrologueDirective(statement)) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isUseStrictPrologueDirective(<ExpressionStatement>statement)) {
|
if (isUseStrictPrologueDirective(<ExpressionStatement>statement)) {
|
||||||
inStrictMode = true;
|
inStrictMode = true;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1753,6 +1731,8 @@ namespace ts {
|
||||||
// Members of classes, interfaces, and modules
|
// Members of classes, interfaces, and modules
|
||||||
case SyntaxKind.ClassExpression:
|
case SyntaxKind.ClassExpression:
|
||||||
case SyntaxKind.ClassDeclaration:
|
case SyntaxKind.ClassDeclaration:
|
||||||
|
// All classes are automatically in strict mode in ES6.
|
||||||
|
inStrictMode = true;
|
||||||
return bindClassLikeDeclaration(<ClassLikeDeclaration>node);
|
return bindClassLikeDeclaration(<ClassLikeDeclaration>node);
|
||||||
case SyntaxKind.InterfaceDeclaration:
|
case SyntaxKind.InterfaceDeclaration:
|
||||||
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
|
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
|
||||||
|
@ -1778,7 +1758,15 @@ namespace ts {
|
||||||
case SyntaxKind.ExportAssignment:
|
case SyntaxKind.ExportAssignment:
|
||||||
return bindExportAssignment(<ExportAssignment>node);
|
return bindExportAssignment(<ExportAssignment>node);
|
||||||
case SyntaxKind.SourceFile:
|
case SyntaxKind.SourceFile:
|
||||||
|
updateStrictModeStatementList((<SourceFile>node).statements);
|
||||||
return bindSourceFileIfExternalModule();
|
return bindSourceFileIfExternalModule();
|
||||||
|
case SyntaxKind.Block:
|
||||||
|
if (!isFunctionLike(node.parent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Fall through
|
||||||
|
case SyntaxKind.ModuleBlock:
|
||||||
|
return updateStrictModeStatementList((<Block | ModuleBlock>node).statements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue