Skip to content

Commit a0691da

Browse files
committed
Limit node flag to expressions to not mess up incremental parsing
1 parent 3514184 commit a0691da

File tree

3 files changed

+23
-42
lines changed

3 files changed

+23
-42
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,7 @@ namespace ts {
18651865
}
18661866

18671867
function checkSymbolUsageInExpressionContext(symbol: Symbol, name: __String, useSite: Node) {
1868-
if (!(useSite.flags & (NodeFlags.Ambient | NodeFlags.InNonEmittingNode)) && useSite.parent.kind !== SyntaxKind.ExportSpecifier) {
1868+
if (!(useSite.flags & (NodeFlags.Ambient | NodeFlags.InNonEmittingExpression)) && useSite.parent.kind !== SyntaxKind.ExportSpecifier) {
18691869
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(symbol);
18701870
if (typeOnlyDeclaration) {
18711871
const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier

src/compiler/parser.ts

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,13 +1444,16 @@ namespace ts {
14441444
token() === SyntaxKind.NumericLiteral;
14451445
}
14461446

1447-
function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName {
1447+
function parsePropertyNameWorker(allowComputedPropertyNames: boolean, computedNameIsNonEmitting: boolean): PropertyName {
14481448
if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) {
14491449
const node = <StringLiteral | NumericLiteral>parseLiteralNode();
14501450
node.text = internIdentifier(node.text);
14511451
return node;
14521452
}
14531453
if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) {
1454+
if (computedNameIsNonEmitting) {
1455+
return doInsideOfContext(NodeFlags.InNonEmittingExpression, parseComputedPropertyName);
1456+
}
14541457
return parseComputedPropertyName();
14551458
}
14561459
if (token() === SyntaxKind.PrivateIdentifier) {
@@ -1459,8 +1462,8 @@ namespace ts {
14591462
return parseIdentifierName();
14601463
}
14611464

1462-
function parsePropertyName(): PropertyName {
1463-
return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
1465+
function parsePropertyName(computedNameIsNonEmitting: boolean): PropertyName {
1466+
return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true, computedNameIsNonEmitting);
14641467
}
14651468

14661469
function parseComputedPropertyName(): ComputedPropertyName {
@@ -2563,7 +2566,7 @@ namespace ts {
25632566
function parseTypeQuery(): TypeQueryNode {
25642567
const node = <TypeQueryNode>createNode(SyntaxKind.TypeQuery);
25652568
parseExpected(SyntaxKind.TypeOfKeyword);
2566-
node.exprName = parseEntityName(/*allowReservedWords*/ true);
2569+
node.exprName = doInsideOfContext(NodeFlags.InNonEmittingExpression, () => parseEntityName(/*allowReservedWords*/ true));
25672570
return finishNode(node);
25682571
}
25692572

@@ -2814,7 +2817,7 @@ namespace ts {
28142817
}
28152818

28162819
function parsePropertyOrMethodSignature(node: PropertySignature | MethodSignature): PropertySignature | MethodSignature {
2817-
node.name = parsePropertyName();
2820+
node.name = parsePropertyName(/*computedNameIsNonEmitting*/ true);
28182821
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
28192822
if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) {
28202823
node.kind = SyntaxKind.MethodSignature;
@@ -3362,10 +3365,7 @@ namespace ts {
33623365
function parseType(): TypeNode {
33633366
// The rules about 'yield' only apply to actual code/expression contexts. They don't
33643367
// apply to 'type' contexts. So we disable these parameters here before moving on.
3365-
return doOutsideOfContext(
3366-
NodeFlags.TypeExcludesFlags,
3367-
() => doInsideOfContext(NodeFlags.InNonEmittingNode, parseTypeWorker)
3368-
);
3368+
return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseTypeWorker);
33693369
}
33703370

33713371
function parseTypeWorker(noConditionalTypes?: boolean): TypeNode {
@@ -5002,7 +5002,7 @@ namespace ts {
50025002

50035003
const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
50045004
const tokenIsIdentifier = isIdentifier();
5005-
node.name = parsePropertyName();
5005+
node.name = parsePropertyName(/*computedNameIsNonEmitting*/ false);
50065006
// Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker.
50075007
(<MethodDeclaration>node).questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
50085008
(<MethodDeclaration>node).exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken);
@@ -5712,9 +5712,9 @@ namespace ts {
57125712
case SyntaxKind.ClassKeyword:
57135713
return parseClassDeclaration(<ClassDeclaration>node);
57145714
case SyntaxKind.InterfaceKeyword:
5715-
return doInsideOfContext(NodeFlags.InNonEmittingNode, () => parseInterfaceDeclaration(<InterfaceDeclaration>node));
5715+
return parseInterfaceDeclaration(<InterfaceDeclaration>node);
57165716
case SyntaxKind.TypeKeyword:
5717-
return doInsideOfContext(NodeFlags.InNonEmittingNode, () => parseTypeAliasDeclaration(<TypeAliasDeclaration>node));
5717+
return parseTypeAliasDeclaration(<TypeAliasDeclaration>node);
57185718
case SyntaxKind.EnumKeyword:
57195719
return parseEnumDeclaration(<EnumDeclaration>node);
57205720
case SyntaxKind.GlobalKeyword:
@@ -5779,7 +5779,7 @@ namespace ts {
57795779
const node = <BindingElement>createNode(SyntaxKind.BindingElement);
57805780
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
57815781
const tokenIsIdentifier = isIdentifier();
5782-
const propertyName = parsePropertyName();
5782+
const propertyName = parsePropertyName(/*computedNameIsNonEmitting*/ false);
57835783
if (tokenIsIdentifier && token() !== SyntaxKind.ColonToken) {
57845784
node.name = <Identifier>propertyName;
57855785
}
@@ -5953,12 +5953,8 @@ namespace ts {
59535953

59545954
function parsePropertyOrMethodDeclaration(node: PropertyDeclaration | MethodDeclaration): PropertyDeclaration | MethodDeclaration {
59555955
const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
5956-
if (node.modifiers && some(node.modifiers, isAbstractModifier)) {
5957-
node.name = doInsideOfContext(NodeFlags.InNonEmittingNode, parsePropertyName);
5958-
}
5959-
else {
5960-
node.name = parsePropertyName();
5961-
}
5956+
const isAbstract = !!node.modifiers && some(node.modifiers, isAbstractModifier);
5957+
node.name = parsePropertyName(isAbstract);
59625958

59635959
// Note: this is not legal as per the grammar. But we allow it in the parser and
59645960
// report an error in the grammar checker.
@@ -5971,7 +5967,7 @@ namespace ts {
59715967

59725968
function parseAccessorDeclaration(node: AccessorDeclaration, kind: AccessorDeclaration["kind"]): AccessorDeclaration {
59735969
node.kind = kind;
5974-
node.name = parsePropertyName();
5970+
node.name = parsePropertyName(/*computedNameIsNonEmitting*/ false);
59755971
fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node);
59765972
node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None);
59775973
return finishNode(node);
@@ -6277,7 +6273,7 @@ namespace ts {
62776273
// or any time an integer literal initializer is encountered.
62786274
function parseEnumMember(): EnumMember {
62796275
const node = <EnumMember>createNodeWithJSDoc(SyntaxKind.EnumMember);
6280-
node.name = parsePropertyName();
6276+
node.name = parsePropertyName(/*computedNameIsNonEmitting*/ false);
62816277
node.initializer = allowInAnd(parseInitializer);
62826278
return finishNode(node);
62836279
}
@@ -6396,35 +6392,23 @@ namespace ts {
63966392
(isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration())
63976393
) {
63986394
isTypeOnly = true;
6399-
identifier = isIdentifier() ? doInsideOfContext(NodeFlags.InNonEmittingNode, parseIdentifier) : undefined;
6400-
node.flags |= NodeFlags.InNonEmittingNode;
6395+
identifier = isIdentifier() ? parseIdentifier() : undefined;
64016396
}
64026397

64036398
if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration()) {
64046399
return parseImportEqualsDeclaration(<ImportEqualsDeclaration>node, identifier, isTypeOnly);
64056400
}
64066401

64076402
// Import statement
6408-
if (isTypeOnly) {
6409-
return doInsideOfContext(
6410-
NodeFlags.InNonEmittingNode,
6411-
() => parseImportDeclarationRest(node as ImportDeclaration, afterImportPos, identifier, isTypeOnly)
6412-
);
6413-
}
6414-
6415-
return parseImportDeclarationRest(node as ImportDeclaration, afterImportPos, identifier, isTypeOnly);
6416-
}
6417-
6418-
function parseImportDeclarationRest(node: ImportDeclaration, afterImportPos: number, name: Identifier | undefined, isTypeOnly: boolean): ImportDeclaration {
64196403
node.kind = SyntaxKind.ImportDeclaration;
64206404
// ImportDeclaration:
64216405
// import ImportClause from ModuleSpecifier ;
64226406
// import ModuleSpecifier;
6423-
if (name || // import id
6407+
if (identifier || // import id
64246408
token() === SyntaxKind.AsteriskToken || // import *
64256409
token() === SyntaxKind.OpenBraceToken // import {
64266410
) {
6427-
(<ImportDeclaration>node).importClause = parseImportClause(name, afterImportPos, isTypeOnly);
6411+
(<ImportDeclaration>node).importClause = parseImportClause(identifier, afterImportPos, isTypeOnly);
64286412
parseExpected(SyntaxKind.FromKeyword);
64296413
}
64306414

@@ -6587,9 +6571,6 @@ namespace ts {
65876571
function parseExportDeclaration(node: ExportDeclaration): ExportDeclaration {
65886572
node.kind = SyntaxKind.ExportDeclaration;
65896573
node.isTypeOnly = parseOptional(SyntaxKind.TypeKeyword);
6590-
if (node.isTypeOnly) {
6591-
return doInsideOfContext(NodeFlags.InNonEmittingNode, () => parseExportDeclarationWorker(node));
6592-
}
65936574
return parseExportDeclarationWorker(node);
65946575
}
65956576

src/compiler/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,15 +574,15 @@ namespace ts {
574574
/* @internal */ InWithStatement = 1 << 24, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
575575
JsonFile = 1 << 25, // If node was parsed in a Json
576576
/* @internal */ TypeCached = 1 << 26, // If a type was cached for node at any point
577-
/* @internal */ InNonEmittingNode = 1 << 27, // If a node was in a context where expressions are never emitted: type queries, abstract members, computed property names of types.
577+
/* @internal */ InNonEmittingExpression = 1 << 27, // If a node was in a context where expressions are never emitted: type queries, abstract members, computed property names of types.
578578

579579
BlockScoped = Let | Const,
580580

581581
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn,
582582
ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions,
583583

584584
// Parsing context flags
585-
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement | Ambient,
585+
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement | Ambient | InNonEmittingExpression,
586586

587587
// Exclude these flags when parsing a Type
588588
TypeExcludesFlags = YieldContext | AwaitContext,

0 commit comments

Comments
 (0)