@@ -2240,7 +2240,7 @@ namespace ts {
22402240 isStartOfType ( /*inStartOfParameter*/ true ) ;
22412241 }
22422242
2243- function parseParameter ( ) : ParameterDeclaration {
2243+ function parseParameter ( requireEqualsToken ?: boolean ) : ParameterDeclaration {
22442244 const node = < ParameterDeclaration > createNode ( SyntaxKind . Parameter ) ;
22452245 if ( token ( ) === SyntaxKind . ThisKeyword ) {
22462246 node . name = createIdentifier ( /*isIdentifier*/ true ) ;
@@ -2269,19 +2269,11 @@ namespace ts {
22692269
22702270 node . questionToken = parseOptionalToken ( SyntaxKind . QuestionToken ) ;
22712271 node . type = parseParameterType ( ) ;
2272- node . initializer = parseBindingElementInitializer ( /*inParameter*/ true ) ;
2272+ node . initializer = parseInitializer ( /*inParameter*/ true , requireEqualsToken ) ;
22732273
22742274 return addJSDocComment ( finishNode ( node ) ) ;
22752275 }
22762276
2277- function parseBindingElementInitializer ( inParameter : boolean ) {
2278- return inParameter ? parseParameterInitializer ( ) : parseNonParameterInitializer ( ) ;
2279- }
2280-
2281- function parseParameterInitializer ( ) {
2282- return parseInitializer ( /*inParameter*/ true ) ;
2283- }
2284-
22852277 function fillSignature (
22862278 returnToken : SyntaxKind . ColonToken | SyntaxKind . EqualsGreaterThanToken ,
22872279 flags : SignatureFlags ,
@@ -2334,7 +2326,8 @@ namespace ts {
23342326 setYieldContext ( ! ! ( flags & SignatureFlags . Yield ) ) ;
23352327 setAwaitContext ( ! ! ( flags & SignatureFlags . Await ) ) ;
23362328
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 ) ) ) ;
23382331
23392332 setYieldContext ( savedYieldContext ) ;
23402333 setAwaitContext ( savedAwaitContext ) ;
@@ -3011,7 +3004,7 @@ namespace ts {
30113004 return expr ;
30123005 }
30133006
3014- function parseInitializer ( inParameter : boolean ) : Expression {
3007+ function parseInitializer ( inParameter : boolean , requireEqualsToken ?: boolean ) : Expression {
30153008 if ( token ( ) !== SyntaxKind . EqualsToken ) {
30163009 // It's not uncommon during typing for the user to miss writing the '=' token. Check if
30173010 // there is no newline after the last token and if we're on an expression. If so, parse
@@ -3026,11 +3019,17 @@ namespace ts {
30263019 // do not try to parse initializer
30273020 return undefined ;
30283021 }
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+ }
30293029 }
30303030
30313031 // Initializer[In, Yield] :
30323032 // = AssignmentExpression[?In, ?Yield]
3033-
30343033 parseExpected ( SyntaxKind . EqualsToken ) ;
30353034 return parseAssignmentExpressionOrHigher ( ) ;
30363035 }
@@ -3345,8 +3344,7 @@ namespace ts {
33453344 function tryParseAsyncSimpleArrowFunctionExpression ( ) : ArrowFunction | undefined {
33463345 // We do a check here so that we won't be doing unnecessarily call to "lookAhead"
33473346 if ( token ( ) === SyntaxKind . AsyncKeyword ) {
3348- const isUnParenthesizedAsyncArrowFunction = lookAhead ( isUnParenthesizedAsyncArrowFunctionWorker ) ;
3349- if ( isUnParenthesizedAsyncArrowFunction === Tristate . True ) {
3347+ if ( lookAhead ( isUnParenthesizedAsyncArrowFunctionWorker ) === Tristate . True ) {
33503348 const asyncModifier = parseModifiersForArrowFunction ( ) ;
33513349 const expr = parseBinaryExpressionOrHigher ( /*precedence*/ 0 ) ;
33523350 return parseSimpleArrowFunctionExpression ( < Identifier > expr , asyncModifier ) ;
@@ -3380,7 +3378,6 @@ namespace ts {
33803378 const node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction ) ;
33813379 node . modifiers = parseModifiersForArrowFunction ( ) ;
33823380 const isAsync = hasModifier ( node , ModifierFlags . Async ) ? SignatureFlags . Await : SignatureFlags . None ;
3383-
33843381 // Arrow functions are never generators.
33853382 //
33863383 // If we're speculatively parsing a signature for a parenthesized arrow function, then
@@ -3403,7 +3400,8 @@ namespace ts {
34033400 // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
34043401 //
34053402 // 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" ) ) ) {
34073405 // Returning undefined here will cause our caller to rewind to where we started from.
34083406 return undefined ;
34093407 }
@@ -5152,7 +5150,7 @@ namespace ts {
51525150 const node = < BindingElement > createNode ( SyntaxKind . BindingElement ) ;
51535151 node . dotDotDotToken = parseOptionalToken ( SyntaxKind . DotDotDotToken ) ;
51545152 node . name = parseIdentifierOrPattern ( ) ;
5155- node . initializer = parseBindingElementInitializer ( /*inParameter*/ false ) ;
5153+ node . initializer = parseInitializer ( /*inParameter*/ false ) ;
51565154 return finishNode ( node ) ;
51575155 }
51585156
@@ -5169,7 +5167,7 @@ namespace ts {
51695167 node . propertyName = propertyName ;
51705168 node . name = parseIdentifierOrPattern ( ) ;
51715169 }
5172- node . initializer = parseBindingElementInitializer ( /*inParameter*/ false ) ;
5170+ node . initializer = parseInitializer ( /*inParameter*/ false ) ;
51735171 return finishNode ( node ) ;
51745172 }
51755173
@@ -5208,7 +5206,7 @@ namespace ts {
52085206 node . name = parseIdentifierOrPattern ( ) ;
52095207 node . type = parseTypeAnnotation ( ) ;
52105208 if ( ! isInOrOfKeyword ( token ( ) ) ) {
5211- node . initializer = parseInitializer ( /*inParameter*/ false ) ;
5209+ node . initializer = parseNonParameterInitializer ( ) ;
52125210 }
52135211 return finishNode ( node ) ;
52145212 }
0 commit comments