@@ -2240,7 +2240,7 @@ namespace ts {
2240
2240
isStartOfType ( /*inStartOfParameter*/ true ) ;
2241
2241
}
2242
2242
2243
- function parseParameter ( ) : ParameterDeclaration {
2243
+ function parseParameter ( requireEqualsToken ?: boolean ) : ParameterDeclaration {
2244
2244
const node = < ParameterDeclaration > createNode ( SyntaxKind . Parameter ) ;
2245
2245
if ( token ( ) === SyntaxKind . ThisKeyword ) {
2246
2246
node . name = createIdentifier ( /*isIdentifier*/ true ) ;
@@ -2269,19 +2269,11 @@ namespace ts {
2269
2269
2270
2270
node . questionToken = parseOptionalToken ( SyntaxKind . QuestionToken ) ;
2271
2271
node . type = parseParameterType ( ) ;
2272
- node . initializer = parseBindingElementInitializer ( /*inParameter*/ true ) ;
2272
+ node . initializer = parseInitializer ( /*inParameter*/ true , requireEqualsToken ) ;
2273
2273
2274
2274
return addJSDocComment ( finishNode ( node ) ) ;
2275
2275
}
2276
2276
2277
- function parseBindingElementInitializer ( inParameter : boolean ) {
2278
- return inParameter ? parseParameterInitializer ( ) : parseNonParameterInitializer ( ) ;
2279
- }
2280
-
2281
- function parseParameterInitializer ( ) {
2282
- return parseInitializer ( /*inParameter*/ true ) ;
2283
- }
2284
-
2285
2277
function fillSignature (
2286
2278
returnToken : SyntaxKind . ColonToken | SyntaxKind . EqualsGreaterThanToken ,
2287
2279
flags : SignatureFlags ,
@@ -2334,7 +2326,8 @@ namespace ts {
2334
2326
setYieldContext ( ! ! ( flags & SignatureFlags . Yield ) ) ;
2335
2327
setAwaitContext ( ! ! ( flags & SignatureFlags . Await ) ) ;
2336
2328
2337
- const result = parseDelimitedList ( ParsingContext . Parameters , flags & SignatureFlags . JSDoc ? parseJSDocParameter : parseParameter ) ;
2329
+ const result = parseDelimitedList ( ParsingContext . Parameters ,
2330
+ flags & SignatureFlags . JSDoc ? parseJSDocParameter : ( ) => parseParameter ( ! ! ( flags & SignatureFlags . RequireCompleteParameterList ) ) ) ;
2338
2331
2339
2332
setYieldContext ( savedYieldContext ) ;
2340
2333
setAwaitContext ( savedAwaitContext ) ;
@@ -3011,7 +3004,7 @@ namespace ts {
3011
3004
return expr ;
3012
3005
}
3013
3006
3014
- function parseInitializer ( inParameter : boolean ) : Expression {
3007
+ function parseInitializer ( inParameter : boolean , requireEqualsToken ?: boolean ) : Expression {
3015
3008
if ( token ( ) !== SyntaxKind . EqualsToken ) {
3016
3009
// It's not uncommon during typing for the user to miss writing the '=' token. Check if
3017
3010
// there is no newline after the last token and if we're on an expression. If so, parse
@@ -3026,11 +3019,17 @@ namespace ts {
3026
3019
// do not try to parse initializer
3027
3020
return undefined ;
3028
3021
}
3022
+ if ( inParameter && requireEqualsToken ) {
3023
+ // = is required when speculatively parsing arrow function parameters,
3024
+ // so return a fake initializer as a signal that the equals token was missing
3025
+ const result = createMissingNode ( SyntaxKind . Identifier , /*reportAtCurrentPosition*/ true , Diagnostics . _0_expected , "=" ) as Identifier ;
3026
+ result . escapedText = "= not found" as __String ;
3027
+ return result ;
3028
+ }
3029
3029
}
3030
3030
3031
3031
// Initializer[In, Yield] :
3032
3032
// = AssignmentExpression[?In, ?Yield]
3033
-
3034
3033
parseExpected ( SyntaxKind . EqualsToken ) ;
3035
3034
return parseAssignmentExpressionOrHigher ( ) ;
3036
3035
}
@@ -3345,8 +3344,7 @@ namespace ts {
3345
3344
function tryParseAsyncSimpleArrowFunctionExpression ( ) : ArrowFunction | undefined {
3346
3345
// We do a check here so that we won't be doing unnecessarily call to "lookAhead"
3347
3346
if ( token ( ) === SyntaxKind . AsyncKeyword ) {
3348
- const isUnParenthesizedAsyncArrowFunction = lookAhead ( isUnParenthesizedAsyncArrowFunctionWorker ) ;
3349
- if ( isUnParenthesizedAsyncArrowFunction === Tristate . True ) {
3347
+ if ( lookAhead ( isUnParenthesizedAsyncArrowFunctionWorker ) === Tristate . True ) {
3350
3348
const asyncModifier = parseModifiersForArrowFunction ( ) ;
3351
3349
const expr = parseBinaryExpressionOrHigher ( /*precedence*/ 0 ) ;
3352
3350
return parseSimpleArrowFunctionExpression ( < Identifier > expr , asyncModifier ) ;
@@ -3380,7 +3378,6 @@ namespace ts {
3380
3378
const node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction ) ;
3381
3379
node . modifiers = parseModifiersForArrowFunction ( ) ;
3382
3380
const isAsync = hasModifier ( node , ModifierFlags . Async ) ? SignatureFlags . Await : SignatureFlags . None ;
3383
-
3384
3381
// Arrow functions are never generators.
3385
3382
//
3386
3383
// If we're speculatively parsing a signature for a parenthesized arrow function, then
@@ -3403,7 +3400,8 @@ namespace ts {
3403
3400
// - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
3404
3401
//
3405
3402
// So we need just a bit of lookahead to ensure that it can only be a signature.
3406
- if ( ! allowAmbiguity && token ( ) !== SyntaxKind . EqualsGreaterThanToken && token ( ) !== SyntaxKind . OpenBraceToken ) {
3403
+ if ( ! allowAmbiguity && ( ( token ( ) !== SyntaxKind . EqualsGreaterThanToken && token ( ) !== SyntaxKind . OpenBraceToken ) ||
3404
+ find ( node . parameters , p => p . initializer && ts . isIdentifier ( p . initializer ) && p . initializer . escapedText === "= not found" ) ) ) {
3407
3405
// Returning undefined here will cause our caller to rewind to where we started from.
3408
3406
return undefined ;
3409
3407
}
@@ -5152,7 +5150,7 @@ namespace ts {
5152
5150
const node = < BindingElement > createNode ( SyntaxKind . BindingElement ) ;
5153
5151
node . dotDotDotToken = parseOptionalToken ( SyntaxKind . DotDotDotToken ) ;
5154
5152
node . name = parseIdentifierOrPattern ( ) ;
5155
- node . initializer = parseBindingElementInitializer ( /*inParameter*/ false ) ;
5153
+ node . initializer = parseInitializer ( /*inParameter*/ false ) ;
5156
5154
return finishNode ( node ) ;
5157
5155
}
5158
5156
@@ -5169,7 +5167,7 @@ namespace ts {
5169
5167
node . propertyName = propertyName ;
5170
5168
node . name = parseIdentifierOrPattern ( ) ;
5171
5169
}
5172
- node . initializer = parseBindingElementInitializer ( /*inParameter*/ false ) ;
5170
+ node . initializer = parseInitializer ( /*inParameter*/ false ) ;
5173
5171
return finishNode ( node ) ;
5174
5172
}
5175
5173
@@ -5208,7 +5206,7 @@ namespace ts {
5208
5206
node . name = parseIdentifierOrPattern ( ) ;
5209
5207
node . type = parseTypeAnnotation ( ) ;
5210
5208
if ( ! isInOrOfKeyword ( token ( ) ) ) {
5211
- node . initializer = parseInitializer ( /*inParameter*/ false ) ;
5209
+ node . initializer = parseNonParameterInitializer ( ) ;
5212
5210
}
5213
5211
return finishNode ( node ) ;
5214
5212
}
0 commit comments