@@ -15,6 +15,15 @@ namespace ts.codefix {
15
15
Diagnostics . Cannot_find_name_0 . code
16
16
] ;
17
17
18
+ enum InfoKind {
19
+ TypeLikeDeclaration ,
20
+ Enum ,
21
+ Function ,
22
+ ObjectLiteral ,
23
+ JsxAttributes ,
24
+ Signature ,
25
+ }
26
+
18
27
registerCodeFix ( {
19
28
errorCodes,
20
29
getCodeActions ( context ) {
@@ -32,8 +41,7 @@ namespace ts.codefix {
32
41
return [ createCodeFixAction ( fixMissingAttributes , changes , Diagnostics . Add_missing_attributes , fixMissingAttributes , Diagnostics . Add_all_missing_attributes ) ] ;
33
42
}
34
43
if ( info . kind === InfoKind . Function || info . kind === InfoKind . Signature ) {
35
- const changes = textChanges . ChangeTracker . with ( context , t =>
36
- info . kind === InfoKind . Signature ? addFunctionDeclarationFromSignature ( t , context , info ) : addFunctionDeclaration ( t , context , info ) ) ;
44
+ const changes = textChanges . ChangeTracker . with ( context , t => addFunctionDeclaration ( t , context , info ) ) ;
37
45
return [ createCodeFixAction ( fixMissingFunctionDeclaration , changes , [ Diagnostics . Add_missing_function_declaration_0 , info . token . text ] , fixMissingFunctionDeclaration , Diagnostics . Add_all_missing_function_declarations ) ] ;
38
46
}
39
47
if ( info . kind === InfoKind . Enum ) {
@@ -56,12 +64,7 @@ namespace ts.codefix {
56
64
return ;
57
65
}
58
66
if ( fixId === fixMissingFunctionDeclaration && ( info . kind === InfoKind . Function || info . kind === InfoKind . Signature ) ) {
59
- if ( info . kind === InfoKind . Signature ) {
60
- addFunctionDeclarationFromSignature ( changes , context , info ) ;
61
- }
62
- else {
63
- addFunctionDeclaration ( changes , context , info ) ;
64
- }
67
+ addFunctionDeclaration ( changes , context , info ) ;
65
68
}
66
69
else if ( fixId === fixMissingProperties && info . kind === InfoKind . ObjectLiteral ) {
67
70
addObjectLiteralProperties ( changes , context , info ) ;
@@ -112,7 +115,6 @@ namespace ts.codefix {
112
115
} ,
113
116
} ) ;
114
117
115
- const enum InfoKind { TypeLikeDeclaration , Enum , Function , ObjectLiteral , JsxAttributes , Signature }
116
118
type Info = TypeLikeDeclarationInfo | EnumInfo | FunctionInfo | ObjectLiteralInfo | JsxAttributesInfo | SignatureInfo ;
117
119
118
120
interface EnumInfo {
@@ -137,7 +139,7 @@ namespace ts.codefix {
137
139
readonly token : Identifier ;
138
140
readonly sourceFile : SourceFile ;
139
141
readonly modifierFlags : ModifierFlags ;
140
- readonly parentDeclaration : SourceFile | ModuleDeclaration ;
142
+ readonly parentDeclaration : SourceFile | ModuleDeclaration | ReturnStatement ;
141
143
}
142
144
143
145
interface ObjectLiteralInfo {
@@ -208,10 +210,10 @@ namespace ts.codefix {
208
210
if ( type && getObjectFlags ( type ) & ObjectFlags . Anonymous ) {
209
211
const signature = firstOrUndefined ( checker . getSignaturesOfType ( type , SignatureKind . Call ) ) ;
210
212
if ( signature === undefined ) return undefined ;
211
- return { kind : InfoKind . Signature , token, signature, sourceFile, parentDeclaration : token . parent } ;
213
+ return { kind : InfoKind . Signature , token, signature, sourceFile, parentDeclaration : findScope ( token ) } ;
212
214
}
213
215
if ( isCallExpression ( parent ) ) {
214
- return { kind : InfoKind . Function , token, call : parent , sourceFile, modifierFlags : ModifierFlags . None , parentDeclaration : sourceFile } ;
216
+ return { kind : InfoKind . Function , token, call : parent , sourceFile, modifierFlags : ModifierFlags . None , parentDeclaration : findScope ( token ) } ;
215
217
}
216
218
}
217
219
@@ -472,28 +474,19 @@ namespace ts.codefix {
472
474
} ) ;
473
475
}
474
476
475
- function addFunctionDeclaration ( changes : textChanges . ChangeTracker , context : CodeFixContextBase , info : FunctionInfo ) {
476
- const importAdder = createImportAdder ( context . sourceFile , context . program , context . preferences , context . host ) ;
477
- const functionDeclaration = createSignatureDeclarationFromCallExpression ( SyntaxKind . FunctionDeclaration , context , importAdder , info . call , idText ( info . token ) , info . modifierFlags , info . parentDeclaration ) as FunctionDeclaration ;
478
- changes . insertNodeAtEndOfScope ( info . sourceFile , info . parentDeclaration , functionDeclaration ) ;
479
- importAdder . writeFixes ( changes ) ;
480
- }
481
-
482
- function addFunctionDeclarationFromSignature ( changes : textChanges . ChangeTracker , context : CodeFixContextBase , info : SignatureInfo ) {
477
+ function addFunctionDeclaration ( changes : textChanges . ChangeTracker , context : CodeFixContextBase , info : FunctionInfo | SignatureInfo ) {
483
478
const quotePreference = getQuotePreference ( context . sourceFile , context . preferences ) ;
484
479
const importAdder = createImportAdder ( context . sourceFile , context . program , context . preferences , context . host ) ;
485
- const functionDeclaration = createSignatureDeclarationFromSignature ( SyntaxKind . FunctionExpression , context , quotePreference , info . signature ,
486
- createStubbedBody ( Diagnostics . Function_not_implemented . message , quotePreference ) , info . token , /*modifiers*/ undefined , /*optional*/ undefined , /*enclosingDeclaration*/ undefined , importAdder ) ;
480
+ const functionDeclaration = info . kind === InfoKind . Function
481
+ ? createSignatureDeclarationFromCallExpression ( SyntaxKind . FunctionDeclaration , context , importAdder , info . call , idText ( info . token ) , info . modifierFlags , info . parentDeclaration )
482
+ : createSignatureDeclarationFromSignature ( SyntaxKind . FunctionDeclaration , context , quotePreference , info . signature , createStubbedBody ( Diagnostics . Function_not_implemented . message , quotePreference ) , info . token , /*modifiers*/ undefined , /*optional*/ undefined , /*enclosingDeclaration*/ undefined , importAdder ) ;
487
483
if ( functionDeclaration === undefined ) {
488
484
Debug . fail ( "fixMissingFunctionDeclaration codefix got unexpected error." ) ;
489
485
}
490
- const returnStatement = isJsxExpression ( info . parentDeclaration ) ? findAncestor ( info . parentDeclaration , isReturnStatement ) : undefined ;
491
- if ( returnStatement ) {
492
- changes . insertNodeBefore ( info . sourceFile , returnStatement , functionDeclaration , /*blankLineBetween*/ true ) ;
493
- }
494
- else {
495
- changes . insertNodeAtEndOfScope ( info . sourceFile , info . sourceFile , functionDeclaration ) ;
496
- }
486
+
487
+ isReturnStatement ( info . parentDeclaration )
488
+ ? changes . insertNodeBefore ( info . sourceFile , info . parentDeclaration , functionDeclaration , /*blankLineBetween*/ true )
489
+ : changes . insertNodeAtEndOfScope ( info . sourceFile , info . parentDeclaration , functionDeclaration ) ;
497
490
importAdder . writeFixes ( changes ) ;
498
491
}
499
492
@@ -657,4 +650,12 @@ namespace ts.codefix {
657
650
}
658
651
return createPropertyNameNodeForIdentifierOrLiteral ( symbol . name , target , quotePreference === QuotePreference . Single ) ;
659
652
}
653
+
654
+ function findScope ( node : Node ) {
655
+ if ( findAncestor ( node , isJsxExpression ) ) {
656
+ const returnStatement = findAncestor ( node . parent , isReturnStatement ) ;
657
+ if ( returnStatement ) return returnStatement ;
658
+ }
659
+ return getSourceFileOfNode ( node ) ;
660
+ }
660
661
}
0 commit comments