Skip to content

Commit 749501e

Browse files
Simplify how type members are represented in the tree.
Conflicts: src/services/syntax/SyntaxGenerator.js.map
1 parent aaaa078 commit 749501e

9 files changed

Lines changed: 121 additions & 107 deletions

src/services/syntax/SyntaxGenerator.js

Lines changed: 8 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/services/syntax/SyntaxGenerator.js.map

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/services/syntax/parser.ts

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,14 +1269,14 @@ module TypeScript.Parser {
12691269
function parseGetAccessor(modifiers: ISyntaxToken[], getKeyword: ISyntaxToken): GetAccessorSyntax {
12701270
return new GetAccessorSyntax(contextFlags,
12711271
modifiers, consumeToken(getKeyword), parsePropertyName(),
1272-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
1272+
parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
12731273
parseFunctionBody(/*isGenerator:*/ false, /*asyncContext:*/ false));
12741274
}
12751275

12761276
function parseSetAccessor(modifiers: ISyntaxToken[], setKeyword: ISyntaxToken): SetAccessorSyntax {
12771277
return new SetAccessorSyntax(contextFlags,
12781278
modifiers, consumeToken(setKeyword), parsePropertyName(),
1279-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
1279+
parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
12801280
parseFunctionBody(/*isGenerator:*/ false, /*asyncContext:*/ false));
12811281
}
12821282

@@ -1401,7 +1401,7 @@ module TypeScript.Parser {
14011401
return new ConstructorDeclarationSyntax(contextFlags,
14021402
modifiers,
14031403
eatToken(SyntaxKind.ConstructorKeyword),
1404-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
1404+
parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false),
14051405
parseFunctionBody(/*isGenerator:*/ false, /*asyncContext:*/ false));
14061406
}
14071407

@@ -1415,7 +1415,7 @@ module TypeScript.Parser {
14151415
modifiers,
14161416
asteriskToken,
14171417
propertyName,
1418-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ isGenerator, /*asyncContext:*/ asyncContext),
1418+
parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ isGenerator, /*asyncContext:*/ asyncContext),
14191419
parseFunctionBody(isGenerator, asyncContext));
14201420
}
14211421

@@ -1445,8 +1445,7 @@ module TypeScript.Parser {
14451445
function parseIndexMemberDeclaration(modifiers: ISyntaxToken[]): IndexMemberDeclarationSyntax {
14461446
return new IndexMemberDeclarationSyntax(contextFlags,
14471447
modifiers,
1448-
parseIndexSignature(),
1449-
eatExplicitOrAutomaticSemicolon(/*allowWithoutNewLine:*/ false));
1448+
parseIndexSignature());
14501449
}
14511450

14521451
function isFunctionDeclaration(modifierCount: number): boolean {
@@ -1471,7 +1470,7 @@ module TypeScript.Parser {
14711470
functionKeyword,
14721471
asteriskToken,
14731472
eatIdentifierToken(),
1474-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ isGenerator, /*asyncContext:*/ asyncContext),
1473+
parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ isGenerator, /*asyncContext:*/ asyncContext),
14751474
parseFunctionBody(isGenerator, asyncContext));
14761475
}
14771476

@@ -1523,7 +1522,7 @@ module TypeScript.Parser {
15231522

15241523
return new ObjectTypeSyntax(contextFlags,
15251524
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
1526-
openBraceToken.fullWidth() > 0 ? parseSeparatedSyntaxList<ITypeMemberSyntax>(ListParsingState.ObjectType_TypeMembers) : [],
1525+
openBraceToken.fullWidth() > 0 ? parseSyntaxList<ITypeMemberSyntax>(ListParsingState.ObjectType_TypeMembers) : [],
15271526
eatToken(SyntaxKind.CloseBraceToken));
15281527
}
15291528

@@ -1585,7 +1584,10 @@ module TypeScript.Parser {
15851584
// A call signature for a type member can both use 'yield' as a parameter name, and
15861585
// does not have parameter initializers. So we can pass 'false' for both [Yield]
15871586
// and [GeneratorParameter].
1588-
return parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false);
1587+
//
1588+
// Also, when this is a call signature used as a type member, then a semicolon is
1589+
// required.
1590+
return parseCallSignatureWithSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false);
15891591
}
15901592
else if (isConstructSignature()) {
15911593
return parseConstructSignature();
@@ -1613,14 +1615,16 @@ module TypeScript.Parser {
16131615
// Construct signatures have no [Yield] or [GeneratorParameter] restrictions.
16141616
return new ConstructSignatureSyntax(contextFlags,
16151617
eatToken(SyntaxKind.NewKeyword),
1616-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false));
1618+
parseCallSignatureWithSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false));
16171619
}
16181620

16191621
function parseIndexSignature(): IndexSignatureSyntax {
16201622
return new IndexSignatureSyntax(contextFlags,
16211623
eatToken(SyntaxKind.OpenBracketToken),
16221624
parseSeparatedSyntaxList<ParameterSyntax>(ListParsingState.IndexSignature_Parameters),
1623-
eatToken(SyntaxKind.CloseBracketToken), parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false));
1625+
eatToken(SyntaxKind.CloseBracketToken),
1626+
parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false),
1627+
eatExplicitOrAutomaticSemicolonOrComma());
16241628
}
16251629

16261630
function parseMethodSignature(propertyName: IPropertyNameSyntax, questionToken: ISyntaxToken): MethodSignatureSyntax {
@@ -1629,12 +1633,15 @@ module TypeScript.Parser {
16291633
return new MethodSignatureSyntax(contextFlags,
16301634
propertyName,
16311635
questionToken,
1632-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false));
1636+
parseCallSignatureWithSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ false, /*asyncContext:*/ false));
16331637
}
16341638

16351639
function parsePropertySignature(propertyName: IPropertyNameSyntax, questionToken: ISyntaxToken): PropertySignatureSyntax {
16361640
return new PropertySignatureSyntax(contextFlags,
1637-
propertyName, questionToken, parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false));
1641+
propertyName,
1642+
questionToken,
1643+
parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false),
1644+
eatExplicitOrAutomaticSemicolonOrComma());
16381645
}
16391646

16401647
function isCallSignature(peekIndex: number): boolean {
@@ -3250,7 +3257,7 @@ module TypeScript.Parser {
32503257
eatToken(SyntaxKind.FunctionKeyword),
32513258
asteriskToken = tryEatToken(SyntaxKind.AsteriskToken),
32523259
tryEatFunctionExpressionIdentifier(!!asteriskToken, !!asyncKeyword),
3253-
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken, /*asyncContext:*/ !!asyncKeyword),
3260+
parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken, /*asyncContext:*/ !!asyncKeyword),
32543261
parseFunctionBody(!!asteriskToken, !!asyncKeyword));
32553262
}
32563263

@@ -3386,7 +3393,7 @@ module TypeScript.Parser {
33863393
// 2.If the [Yield] grammar parameter is not present for CoverParenthesizedExpressionAndArrowParameterList[Yield]
33873394
// return the result of parsing the lexical token stream matched by CoverParenthesizedExpressionAndArrowParameterList
33883395
// using ArrowFormalParameters as the goal symbol.
3389-
var callSignature = parseCallSignature(/*requireCompleteTypeParameterList:*/ true, /*yieldAndGeneratorParameterContext:*/ inYieldContext(), /*asyncContext:*/ !!asyncKeyword);
3396+
var callSignature = parseCallSignatureWithoutSemicolonOrComma(/*requireCompleteTypeParameterList:*/ true, /*yieldAndGeneratorParameterContext:*/ inYieldContext(), /*asyncContext:*/ !!asyncKeyword);
33903397

33913398
if (requireArrow && currentToken().kind !== SyntaxKind.EqualsGreaterThanToken) {
33923399
return undefined;
@@ -3874,11 +3881,29 @@ module TypeScript.Parser {
38743881
return statements;
38753882
}
38763883

3877-
function parseCallSignature(requireCompleteTypeParameterList: boolean, yieldAndGeneratorParameterContext: boolean, asyncContext: boolean): CallSignatureSyntax {
3884+
function parseCallSignatureWithoutSemicolonOrComma(requireCompleteTypeParameterList: boolean, yieldAndGeneratorParameterContext: boolean, asyncContext: boolean): CallSignatureSyntax {
3885+
return parseCallSignatureWorker(requireCompleteTypeParameterList, yieldAndGeneratorParameterContext, asyncContext, /*withSemicolon:*/ false);
3886+
}
3887+
3888+
function parseCallSignatureWithSemicolonOrComma(requireCompleteTypeParameterList: boolean, yieldAndGeneratorParameterContext: boolean, asyncContext: boolean): CallSignatureSyntax {
3889+
return parseCallSignatureWorker(requireCompleteTypeParameterList, yieldAndGeneratorParameterContext, asyncContext, /*withSemicolon:*/ true);
3890+
}
3891+
3892+
function parseCallSignatureWorker(requireCompleteTypeParameterList: boolean, yieldAndGeneratorParameterContext: boolean, asyncContext: boolean, withSemicolonOrComma: boolean): CallSignatureSyntax {
38783893
return new CallSignatureSyntax(contextFlags,
38793894
tryParseTypeParameterList(requireCompleteTypeParameterList),
38803895
parseParameterList(yieldAndGeneratorParameterContext, asyncContext),
3881-
parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false));
3896+
parseOptionalTypeAnnotation(/*allowStringLiteral:*/ false),
3897+
withSemicolonOrComma ? eatExplicitOrAutomaticSemicolonOrComma() : undefined);
3898+
}
3899+
3900+
function eatExplicitOrAutomaticSemicolonOrComma() {
3901+
var _currentToken = currentToken();
3902+
if (_currentToken.kind === SyntaxKind.CommaToken) {
3903+
return consumeToken(_currentToken);
3904+
}
3905+
3906+
return eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false);
38823907
}
38833908

38843909
function tryParseTypeParameterList(requireCompleteTypeParameterList: boolean): TypeParameterListSyntax {
@@ -4411,17 +4436,6 @@ module TypeScript.Parser {
44114436

44124437
function parseSeparatedSyntaxListWorker<T extends ISyntaxNodeOrToken>(currentListType: ListParsingState): ISeparatedSyntaxList<T> {
44134438
var nodesAndSeparators: ISyntaxNodeOrToken[] = [];
4414-
4415-
// Debug.assert(nodes.length === 0);
4416-
// Debug.assert(separators.length === 0);
4417-
// Debug.assert(skippedTokens.length === 0);
4418-
// Debug.assert(<any>skippedTokens !== nodes);
4419-
// Debug.assert(skippedTokens !== separators);
4420-
// Debug.assert(<any>nodes !== separators);
4421-
4422-
var _separatorKind = currentListType === ListParsingState.ObjectType_TypeMembers ? SyntaxKind.SemicolonToken : SyntaxKind.CommaToken;
4423-
var allowAutomaticSemicolonInsertion = _separatorKind === SyntaxKind.SemicolonToken;
4424-
44254439
var inErrorRecovery = false;
44264440
while (true) {
44274441
// Try to parse an item of the list. If we fail then decide if we need to abort or
@@ -4465,8 +4479,7 @@ module TypeScript.Parser {
44654479
// allow 'comma' as a separator (for error tolerance). We will later do a post pass
44664480
// to report when a comma was used improperly in a list that needed semicolons.
44674481
var _currentToken = currentToken();
4468-
var tokenKind = _currentToken.kind;
4469-
if (tokenKind === _separatorKind || tokenKind === SyntaxKind.CommaToken) {
4482+
if (_currentToken.kind === SyntaxKind.CommaToken) {
44704483
// Consume the last separator and continue parsing list elements.
44714484
nodesAndSeparators.push(consumeToken(_currentToken));
44724485
continue;
@@ -4479,34 +4492,12 @@ module TypeScript.Parser {
44794492
break;
44804493
}
44814494

4482-
// Otherwise, it might be a case where we can parse out an implicit semicolon.
4483-
4484-
// Note: it's important that we check this *after* the check above for
4485-
// 'listIsTerminated'. Consider the following case:
4486-
//
4487-
// {
4488-
// a // <-- just finished parsing 'a'
4489-
// }
4490-
//
4491-
// Automatic semicolon insertion rules state: "When, as the program is parsed from
4492-
// left to right, a token (called the offending token) is encountered that is not
4493-
// allowed by any production of the grammar". So we should only ever insert a
4494-
// semicolon if we couldn't consume something normally. in the above case, we can
4495-
// consume the '}' just fine. So ASI doesn't apply.
4496-
4497-
if (allowAutomaticSemicolonInsertion && canEatAutomaticSemicolon(/*allowWithoutNewline:*/ false)) {
4498-
var semicolonToken = eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) || createEmptyToken(SyntaxKind.SemicolonToken);
4499-
nodesAndSeparators.push(semicolonToken);
4500-
// Debug.assert(items.length % 2 === 0);
4501-
continue;
4502-
}
4503-
45044495
// We weren't at the end of the list. And thre was no separator we could parse out.
45054496
// Try parse the separator we expected, and continue parsing more list elements.
45064497
// This time mark that we're in error recovery mode though.
45074498
//
45084499
// Note: trying to eat this token will emit the appropriate diagnostic.
4509-
nodesAndSeparators.push(eatToken(_separatorKind));
4500+
nodesAndSeparators.push(eatToken(SyntaxKind.CommaToken));
45104501

45114502
// Now that we're in 'error recovery' mode we cantweak some parsing rules as
45124503
// appropriate. For example, if we have:

src/services/syntax/prettyPrinter.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,12 +604,14 @@ module TypeScript.PrettyPrinter {
604604
this.appendSeparatorSpaceList(node.parameters)
605605
this.appendToken(node.closeBracketToken);
606606
this.appendNode(node.typeAnnotation);
607+
this.appendToken(node.semicolonOrCommaToken);
607608
}
608609

609610
public visitPropertySignature(node: PropertySignatureSyntax): void {
610611
visitNodeOrToken(this, node.propertyName);
611612
this.appendToken(node.questionToken);
612613
this.appendNode(node.typeAnnotation);
614+
this.appendToken(node.semicolonOrCommaToken);
613615
}
614616

615617
public visitParameterList(node: ParameterListSyntax): void {
@@ -622,6 +624,7 @@ module TypeScript.PrettyPrinter {
622624
this.appendNode(node.typeParameterList);
623625
visitNodeOrToken(this, node.parameterList);
624626
this.appendNode(node.typeAnnotation);
627+
this.appendToken(node.semicolonOrCommaToken);
625628
}
626629

627630
public visitTypeParameterList(node: TypeParameterListSyntax): void {
@@ -693,7 +696,6 @@ module TypeScript.PrettyPrinter {
693696
this.appendSpaceList(node.modifiers);
694697
this.ensureSpace();
695698
visitNodeOrToken(this, node.indexSignature);
696-
this.appendToken(node.semicolonToken);
697699
}
698700

699701
public visitMemberFunctionDeclaration(node: MemberFunctionDeclarationSyntax): void {

0 commit comments

Comments
 (0)