Skip to content

Commit 33f6825

Browse files
rbucktonJack-Works
authored andcommitted
Leverage syntax cursor as part of reparse (microsoft#39216)
1 parent 3ccc4ab commit 33f6825

File tree

95 files changed

+815
-966
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+815
-966
lines changed

src/compiler/binder.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,20 +2109,39 @@ namespace ts {
21092109
}
21102110

21112111
// The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
2112-
// check for reserved words used as identifiers in strict mode code.
2113-
function checkStrictModeIdentifier(node: Identifier) {
2114-
if (inStrictMode &&
2115-
node.originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord &&
2116-
node.originalKeywordKind! <= SyntaxKind.LastFutureReservedWord &&
2117-
!isIdentifierName(node) &&
2112+
// check for reserved words used as identifiers in strict mode code, as well as `yield` or `await` in
2113+
// [Yield] or [Await] contexts, respectively.
2114+
function checkContextualIdentifier(node: Identifier) {
2115+
// Report error only if there are no parse errors in file
2116+
if (!file.parseDiagnostics.length &&
21182117
!(node.flags & NodeFlags.Ambient) &&
2119-
!(node.flags & NodeFlags.JSDoc)) {
2118+
!(node.flags & NodeFlags.JSDoc) &&
2119+
!isIdentifierName(node)) {
21202120

2121-
// Report error only if there are no parse errors in file
2122-
if (!file.parseDiagnostics.length) {
2121+
// strict mode identifiers
2122+
if (inStrictMode &&
2123+
node.originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord &&
2124+
node.originalKeywordKind! <= SyntaxKind.LastFutureReservedWord) {
21232125
file.bindDiagnostics.push(createDiagnosticForNode(node,
21242126
getStrictModeIdentifierMessage(node), declarationNameToString(node)));
21252127
}
2128+
else if (node.originalKeywordKind === SyntaxKind.AwaitKeyword) {
2129+
if (isExternalModule(file) && isInTopLevelContext(node)) {
2130+
file.bindDiagnostics.push(createDiagnosticForNode(node,
2131+
Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module,
2132+
declarationNameToString(node)));
2133+
}
2134+
else if (node.flags & NodeFlags.AwaitContext) {
2135+
file.bindDiagnostics.push(createDiagnosticForNode(node,
2136+
Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here,
2137+
declarationNameToString(node)));
2138+
}
2139+
}
2140+
else if (node.originalKeywordKind === SyntaxKind.YieldKeyword && node.flags & NodeFlags.YieldContext) {
2141+
file.bindDiagnostics.push(createDiagnosticForNode(node,
2142+
Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here,
2143+
declarationNameToString(node)));
2144+
}
21262145
}
21272146
}
21282147

@@ -2423,7 +2442,7 @@ namespace ts {
24232442
if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) {
24242443
node.flowNode = currentFlow;
24252444
}
2426-
return checkStrictModeIdentifier(<Identifier>node);
2445+
return checkContextualIdentifier(<Identifier>node);
24272446
case SyntaxKind.SuperKeyword:
24282447
node.flowNode = currentFlow;
24292448
break;

src/compiler/checker.ts

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28572,11 +28572,6 @@ namespace ts {
2857228572
return undefinedWideningType;
2857328573
}
2857428574

28575-
function isInTopLevelContext(node: Node) {
28576-
const container = getThisContainer(node, /*includeArrowFunctions*/ true);
28577-
return isSourceFile(container);
28578-
}
28579-
2858028575
function checkAwaitExpression(node: AwaitExpression): Type {
2858128576
// Grammar checking
2858228577
if (produceDiagnostics) {
@@ -35222,7 +35217,6 @@ namespace ts {
3522235217
}
3522335218

3522435219
function checkImportBinding(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier) {
35225-
checkGrammarAwaitIdentifier(node.name);
3522635220
checkCollisionWithRequireExportsInGeneratedCode(node, node.name!);
3522735221
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name!);
3522835222
checkAliasSymbol(node);
@@ -37988,31 +37982,19 @@ namespace ts {
3798837982
return false;
3798937983
}
3799037984

37991-
function checkGrammarAwaitIdentifier(name: Identifier | undefined): boolean {
37992-
if (name && isIdentifier(name) && name.originalKeywordKind === SyntaxKind.AwaitKeyword && isInTopLevelContext(name.parent)) {
37993-
const file = getSourceFileOfNode(name);
37994-
if (!file.isDeclarationFile && isExternalModule(file)) {
37995-
return grammarErrorOnNode(name, Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module, idText(name));
37996-
}
37997-
}
37998-
return false;
37999-
}
38000-
3800137985
function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration | MethodSignature): boolean {
3800237986
// Prevent cascading error by short-circuit
3800337987
const file = getSourceFileOfNode(node);
3800437988
return checkGrammarDecoratorsAndModifiers(node) ||
3800537989
checkGrammarTypeParameterList(node.typeParameters, file) ||
38006-
(isFunctionDeclaration(node) && checkGrammarAwaitIdentifier(node.name)) ||
3800737990
checkGrammarParameterList(node.parameters) ||
3800837991
checkGrammarArrowFunction(node, file) ||
3800937992
(isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node));
3801037993
}
3801137994

3801237995
function checkGrammarClassLikeDeclaration(node: ClassLikeDeclaration): boolean {
3801337996
const file = getSourceFileOfNode(node);
38014-
return (isClassDeclaration(node) && checkGrammarAwaitIdentifier(node.name)) ||
38015-
checkGrammarClassDeclarationHeritageClauses(node) ||
37997+
return checkGrammarClassDeclarationHeritageClauses(node) ||
3801637998
checkGrammarTypeParameterList(node.typeParameters, file);
3801737999
}
3801838000

@@ -38655,10 +38637,6 @@ namespace ts {
3865538637
}
3865638638
}
3865738639

38658-
if (isIdentifier(node.name) && checkGrammarAwaitIdentifier(node.name)) {
38659-
return true;
38660-
}
38661-
3866238640
if (node.dotDotDotToken && node.initializer) {
3866338641
// Error on equals token which immediately precedes the initializer
3866438642
return grammarErrorAtPos(node, node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
@@ -38722,9 +38700,6 @@ namespace ts {
3872238700
}
3872338701
}
3872438702
}
38725-
if (isIdentifier(node.name) && checkGrammarAwaitIdentifier(node.name)) {
38726-
return true;
38727-
}
3872838703

3872938704
if (node.exclamationToken && (node.parent.parent.kind !== SyntaxKind.VariableStatement || !node.type || node.initializer || node.flags & NodeFlags.Ambient)) {
3873038705
return grammarErrorOnNode(node.exclamationToken, Diagnostics.Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation);

0 commit comments

Comments
 (0)