Skip to content

Commit 7e8851e

Browse files
author
Andy
authored
Always require '=' before parsing an initializer (#19979)
* Always require '=' before parsing an initializer * Fix fourslash tests
1 parent bee12e6 commit 7e8851e

File tree

99 files changed

+609
-455
lines changed

Some content is hidden

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

99 files changed

+609
-455
lines changed

src/compiler/parser.ts

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,7 +2271,7 @@ namespace ts {
22712271
isStartOfType(/*inStartOfParameter*/ true);
22722272
}
22732273

2274-
function parseParameter(requireEqualsToken?: boolean): ParameterDeclaration {
2274+
function parseParameter(): ParameterDeclaration {
22752275
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter);
22762276
if (token() === SyntaxKind.ThisKeyword) {
22772277
node.name = createIdentifier(/*isIdentifier*/ true);
@@ -2300,7 +2300,7 @@ namespace ts {
23002300

23012301
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
23022302
node.type = parseParameterType();
2303-
node.initializer = parseInitializer(/*inParameter*/ true, requireEqualsToken);
2303+
node.initializer = parseInitializer();
23042304

23052305
return addJSDocComment(finishNode(node));
23062306
}
@@ -2357,8 +2357,7 @@ namespace ts {
23572357
setYieldContext(!!(flags & SignatureFlags.Yield));
23582358
setAwaitContext(!!(flags & SignatureFlags.Await));
23592359

2360-
const result = parseDelimitedList(ParsingContext.Parameters,
2361-
flags & SignatureFlags.JSDoc ? parseJSDocParameter : () => parseParameter(!!(flags & SignatureFlags.RequireCompleteParameterList)));
2360+
const result = parseDelimitedList(ParsingContext.Parameters, flags & SignatureFlags.JSDoc ? parseJSDocParameter : parseParameter);
23622361

23632362
setYieldContext(savedYieldContext);
23642363
setAwaitContext(savedAwaitContext);
@@ -2499,7 +2498,7 @@ namespace ts {
24992498
// Although type literal properties cannot not have initializers, we attempt
25002499
// to parse an initializer so we can report in the checker that an interface
25012500
// property or type literal property cannot have an initializer.
2502-
property.initializer = parseNonParameterInitializer();
2501+
property.initializer = parseInitializer();
25032502
}
25042503

25052504
parseTypeMemberSemicolon();
@@ -3039,34 +3038,8 @@ namespace ts {
30393038
return expr;
30403039
}
30413040

3042-
function parseInitializer(inParameter: boolean, requireEqualsToken?: boolean): Expression {
3043-
if (token() !== SyntaxKind.EqualsToken) {
3044-
// It's not uncommon during typing for the user to miss writing the '=' token. Check if
3045-
// there is no newline after the last token and if we're on an expression. If so, parse
3046-
// this as an equals-value clause with a missing equals.
3047-
// NOTE: There are two places where we allow equals-value clauses. The first is in a
3048-
// variable declarator. The second is with a parameter. For variable declarators
3049-
// it's more likely that a { would be a allowed (as an object literal). While this
3050-
// is also allowed for parameters, the risk is that we consume the { as an object
3051-
// literal when it really will be for the block following the parameter.
3052-
if (scanner.hasPrecedingLineBreak() || (inParameter && token() === SyntaxKind.OpenBraceToken) || !isStartOfExpression()) {
3053-
// preceding line break, open brace in a parameter (likely a function body) or current token is not an expression -
3054-
// do not try to parse initializer
3055-
return undefined;
3056-
}
3057-
if (inParameter && requireEqualsToken) {
3058-
// = is required when speculatively parsing arrow function parameters,
3059-
// so return a fake initializer as a signal that the equals token was missing
3060-
const result = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics._0_expected, "=") as Identifier;
3061-
result.escapedText = "= not found" as __String;
3062-
return result;
3063-
}
3064-
}
3065-
3066-
// Initializer[In, Yield] :
3067-
// = AssignmentExpression[?In, ?Yield]
3068-
parseExpected(SyntaxKind.EqualsToken);
3069-
return parseAssignmentExpressionOrHigher();
3041+
function parseInitializer(): Expression | undefined {
3042+
return parseOptional(SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher() : undefined;
30703043
}
30713044

30723045
function parseAssignmentExpressionOrHigher(): Expression {
@@ -5234,7 +5207,7 @@ namespace ts {
52345207
const node = <BindingElement>createNode(SyntaxKind.BindingElement);
52355208
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
52365209
node.name = parseIdentifierOrPattern();
5237-
node.initializer = parseInitializer(/*inParameter*/ false);
5210+
node.initializer = parseInitializer();
52385211
return finishNode(node);
52395212
}
52405213

@@ -5251,7 +5224,7 @@ namespace ts {
52515224
node.propertyName = propertyName;
52525225
node.name = parseIdentifierOrPattern();
52535226
}
5254-
node.initializer = parseInitializer(/*inParameter*/ false);
5227+
node.initializer = parseInitializer();
52555228
return finishNode(node);
52565229
}
52575230

@@ -5290,7 +5263,7 @@ namespace ts {
52905263
node.name = parseIdentifierOrPattern();
52915264
node.type = parseTypeAnnotation();
52925265
if (!isInOrOfKeyword(token())) {
5293-
node.initializer = parseNonParameterInitializer();
5266+
node.initializer = parseInitializer();
52945267
}
52955268
return finishNode(node);
52965269
}
@@ -5406,8 +5379,8 @@ namespace ts {
54065379
//
54075380
// The checker may still error in the static case to explicitly disallow the yield expression.
54085381
property.initializer = hasModifier(property, ModifierFlags.Static)
5409-
? allowInAnd(parseNonParameterInitializer)
5410-
: doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.DisallowInContext, parseNonParameterInitializer);
5382+
? allowInAnd(parseInitializer)
5383+
: doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.DisallowInContext, parseInitializer);
54115384

54125385
parseSemicolon();
54135386
return addJSDocComment(finishNode(property));
@@ -5428,10 +5401,6 @@ namespace ts {
54285401
}
54295402
}
54305403

5431-
function parseNonParameterInitializer() {
5432-
return parseInitializer(/*inParameter*/ false);
5433-
}
5434-
54355404
function parseAccessorDeclaration(kind: SyntaxKind, fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): AccessorDeclaration {
54365405
const node = <AccessorDeclaration>createNode(kind, fullStart);
54375406
node.decorators = decorators;
@@ -5755,7 +5724,7 @@ namespace ts {
57555724
function parseEnumMember(): EnumMember {
57565725
const node = <EnumMember>createNode(SyntaxKind.EnumMember, scanner.getStartPos());
57575726
node.name = parsePropertyName();
5758-
node.initializer = allowInAnd(parseNonParameterInitializer);
5727+
node.initializer = allowInAnd(parseInitializer);
57595728
return addJSDocComment(finishNode(node));
57605729
}
57615730

tests/baselines/reference/ClassDeclaration26.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/compiler/ClassDeclaration26.ts(2,22): error TS1005: ';' expected.
22
tests/cases/compiler/ClassDeclaration26.ts(4,5): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected.
3-
tests/cases/compiler/ClassDeclaration26.ts(4,20): error TS1005: '=' expected.
3+
tests/cases/compiler/ClassDeclaration26.ts(4,20): error TS1005: ',' expected.
44
tests/cases/compiler/ClassDeclaration26.ts(4,23): error TS1005: '=>' expected.
55
tests/cases/compiler/ClassDeclaration26.ts(5,1): error TS1128: Declaration or statement expected.
66

@@ -15,7 +15,7 @@ tests/cases/compiler/ClassDeclaration26.ts(5,1): error TS1128: Declaration or st
1515
~~~
1616
!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected.
1717
~
18-
!!! error TS1005: '=' expected.
18+
!!! error TS1005: ',' expected.
1919
~
2020
!!! error TS1005: '=>' expected.
2121
}

tests/baselines/reference/ClassDeclaration26.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ var C = /** @class */ (function () {
1212
}
1313
return C;
1414
}());
15-
var constructor = function () { };
15+
var constructor;
16+
(function () { });

tests/baselines/reference/ClassDeclaration26.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ class C {
88
>10 : 10
99

1010
var constructor() { }
11-
>constructor : () => void
11+
>constructor : any
1212
>() { } : () => void
1313
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,20): error TS1005: '(' expected.
2-
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,25): error TS1005: '=' expected.
2+
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,25): error TS1005: ',' expected.
33
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,28): error TS1005: '=>' expected.
44

55

@@ -8,6 +8,6 @@ tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,
88
~~~~~
99
!!! error TS1005: '(' expected.
1010
~
11-
!!! error TS1005: '=' expected.
11+
!!! error TS1005: ',' expected.
1212
~
1313
!!! error TS1005: '=>' expected.

tests/baselines/reference/FunctionDeclaration12_es6.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
var v = function * yield() { }
33

44
//// [FunctionDeclaration12_es6.js]
5-
var v = function* () { }, yield = () => { };
5+
var v = function* () { }, yield;
6+
() => { };

tests/baselines/reference/FunctionDeclaration12_es6.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
var v = function * yield() { }
33
>v : () => any
44
>function * : () => any
5-
>yield : () => void
5+
>yield : any
66
>() { } : () => void
77

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts(4,5): error TS1181: Array element destructuring pattern expected.
2-
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts(4,6): error TS1005: ',' expected.
3-
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts(4,8): error TS1134: Variable declaration expected.
4-
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts(4,10): error TS1134: Variable declaration expected.
2+
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts(4,6): error TS1005: ';' expected.
3+
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts(4,8): error TS1128: Declaration or statement expected.
54

65

7-
==== tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts (4 errors) ====
6+
==== tests/cases/conformance/es6/variableDeclarations/VariableDeclaration13_es6.ts (3 errors) ====
87
// An ExpressionStatement cannot start with the two token sequence `let [` because
98
// that would make it ambiguous with a `let` LexicalDeclaration whose first LexicalBinding was an ArrayBindingPattern.
109
var let: any;
1110
let[0] = 100;
1211
~
1312
!!! error TS1181: Array element destructuring pattern expected.
1413
~
15-
!!! error TS1005: ',' expected.
14+
!!! error TS1005: ';' expected.
1615
~
17-
!!! error TS1134: Variable declaration expected.
18-
~~~
19-
!!! error TS1134: Variable declaration expected.
16+
!!! error TS1128: Declaration or statement expected.

tests/baselines/reference/VariableDeclaration13_es6.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ let[0] = 100;
88
// An ExpressionStatement cannot start with the two token sequence `let [` because
99
// that would make it ambiguous with a `let` LexicalDeclaration whose first LexicalBinding was an ArrayBindingPattern.
1010
var let;
11-
let [] = 0;
11+
let [];
12+
0;
1213
100;
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,22 @@
1-
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(6,5): error TS2322: Type 'number' is not assignable to type 'ArrayConstructor'.
2-
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(6,22): error TS1005: '=' expected.
1+
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(6,22): error TS1005: ',' expected.
32
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(6,30): error TS1109: Expression expected.
4-
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(7,5): error TS2322: Type 'number' is not assignable to type 'ArrayConstructor'.
5-
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(7,22): error TS1005: '=' expected.
3+
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(7,22): error TS1005: ',' expected.
64
tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(7,32): error TS1109: Expression expected.
75

86

9-
==== tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts (6 errors) ====
7+
==== tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts (4 errors) ====
108
// array type cannot use typeof.
119

1210
var x = 1;
1311
var xs: typeof x[]; // Not an error. This is equivalent to Array<typeof x>
1412
var xs2: typeof Array;
1513
var xs3: typeof Array<number>;
16-
~~~
17-
!!! error TS2322: Type 'number' is not assignable to type 'ArrayConstructor'.
1814
~
19-
!!! error TS1005: '=' expected.
15+
!!! error TS1005: ',' expected.
2016
~
2117
!!! error TS1109: Expression expected.
2218
var xs4: typeof Array<typeof x>;
23-
~~~
24-
!!! error TS2322: Type 'number' is not assignable to type 'ArrayConstructor'.
2519
~
26-
!!! error TS1005: '=' expected.
20+
!!! error TS1005: ',' expected.
2721
~
2822
!!! error TS1109: Expression expected.

0 commit comments

Comments
 (0)