Skip to content

Commit 6927c19

Browse files
committed
remove addFunctionDeclarationFromSignature. fix formatting
1 parent 305baeb commit 6927c19

File tree

3 files changed

+61
-32
lines changed

3 files changed

+61
-32
lines changed

src/services/codefixes/fixAddMissingMember.ts

+30-29
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ namespace ts.codefix {
1515
Diagnostics.Cannot_find_name_0.code
1616
];
1717

18+
enum InfoKind {
19+
TypeLikeDeclaration,
20+
Enum,
21+
Function,
22+
ObjectLiteral,
23+
JsxAttributes,
24+
Signature,
25+
}
26+
1827
registerCodeFix({
1928
errorCodes,
2029
getCodeActions(context) {
@@ -32,8 +41,7 @@ namespace ts.codefix {
3241
return [createCodeFixAction(fixMissingAttributes, changes, Diagnostics.Add_missing_attributes, fixMissingAttributes, Diagnostics.Add_all_missing_attributes)];
3342
}
3443
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));
3745
return [createCodeFixAction(fixMissingFunctionDeclaration, changes, [Diagnostics.Add_missing_function_declaration_0, info.token.text], fixMissingFunctionDeclaration, Diagnostics.Add_all_missing_function_declarations)];
3846
}
3947
if (info.kind === InfoKind.Enum) {
@@ -56,12 +64,7 @@ namespace ts.codefix {
5664
return;
5765
}
5866
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);
6568
}
6669
else if (fixId === fixMissingProperties && info.kind === InfoKind.ObjectLiteral) {
6770
addObjectLiteralProperties(changes, context, info);
@@ -112,7 +115,6 @@ namespace ts.codefix {
112115
},
113116
});
114117

115-
const enum InfoKind { TypeLikeDeclaration, Enum, Function, ObjectLiteral, JsxAttributes, Signature }
116118
type Info = TypeLikeDeclarationInfo | EnumInfo | FunctionInfo | ObjectLiteralInfo | JsxAttributesInfo | SignatureInfo;
117119

118120
interface EnumInfo {
@@ -137,7 +139,7 @@ namespace ts.codefix {
137139
readonly token: Identifier;
138140
readonly sourceFile: SourceFile;
139141
readonly modifierFlags: ModifierFlags;
140-
readonly parentDeclaration: SourceFile | ModuleDeclaration;
142+
readonly parentDeclaration: SourceFile | ModuleDeclaration | ReturnStatement;
141143
}
142144

143145
interface ObjectLiteralInfo {
@@ -208,10 +210,10 @@ namespace ts.codefix {
208210
if (type && getObjectFlags(type) & ObjectFlags.Anonymous) {
209211
const signature = firstOrUndefined(checker.getSignaturesOfType(type, SignatureKind.Call));
210212
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) };
212214
}
213215
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) };
215217
}
216218
}
217219

@@ -472,28 +474,19 @@ namespace ts.codefix {
472474
});
473475
}
474476

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) {
483478
const quotePreference = getQuotePreference(context.sourceFile, context.preferences);
484479
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);
487483
if (functionDeclaration === undefined) {
488484
Debug.fail("fixMissingFunctionDeclaration codefix got unexpected error.");
489485
}
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);
497490
importAdder.writeFixes(changes);
498491
}
499492

@@ -657,4 +650,12 @@ namespace ts.codefix {
657650
}
658651
return createPropertyNameNodeForIdentifierOrLiteral(symbol.name, target, quotePreference === QuotePreference.Single);
659652
}
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+
}
660661
}

src/services/codefixes/helpers.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,17 @@ namespace ts.codefix {
169169
}
170170

171171
function outputMethod(quotePreference: QuotePreference, signature: Signature, modifiers: NodeArray<Modifier> | undefined, name: PropertyName, body?: Block): void {
172-
const method = createSignatureDeclarationFromSignature(SyntaxKind.MethodDeclaration, context, quotePreference, signature, body, name, modifiers, optional && !!(preserveOptional & PreserveOptionalFlags.Method), enclosingDeclaration, importAdder);
172+
const method = createSignatureDeclarationFromSignature(SyntaxKind.MethodDeclaration, context, quotePreference, signature, body, name, modifiers, optional && !!(preserveOptional & PreserveOptionalFlags.Method), enclosingDeclaration, importAdder) as MethodDeclaration;
173173
if (method) addClassElement(method);
174174
}
175175
}
176176

177177
export function createSignatureDeclarationFromSignature(
178-
kind: SyntaxKind.MethodDeclaration | SyntaxKind.FunctionExpression | SyntaxKind.ArrowFunction,
178+
kind:
179+
| SyntaxKind.MethodDeclaration
180+
| SyntaxKind.FunctionExpression
181+
| SyntaxKind.ArrowFunction
182+
| SyntaxKind.FunctionDeclaration,
179183
context: TypeConstructionContext,
180184
quotePreference: QuotePreference,
181185
signature: Signature,
@@ -194,7 +198,7 @@ namespace ts.codefix {
194198
| NodeBuilderFlags.SuppressAnyReturnType
195199
| NodeBuilderFlags.AllowEmptyTuple
196200
| (quotePreference === QuotePreference.Single ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : NodeBuilderFlags.None);
197-
const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags, getNoopSymbolTrackerWithResolver(context)) as ArrowFunction | FunctionExpression | MethodDeclaration;
201+
const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags, getNoopSymbolTrackerWithResolver(context)) as ArrowFunction | FunctionExpression | MethodDeclaration | FunctionDeclaration;
198202
if (!signatureDeclaration) {
199203
return undefined;
200204
}
@@ -273,6 +277,9 @@ namespace ts.codefix {
273277
if (isMethodDeclaration(signatureDeclaration)) {
274278
return factory.updateMethodDeclaration(signatureDeclaration, modifiers, asteriskToken, name ?? factory.createIdentifier(""), questionToken, typeParameters, parameters, type, body);
275279
}
280+
if (isFunctionDeclaration(signatureDeclaration)) {
281+
return factory.updateFunctionDeclaration(signatureDeclaration, modifiers, signatureDeclaration.asteriskToken, tryCast(name, isIdentifier), typeParameters, parameters, type, body ?? signatureDeclaration.body);
282+
}
276283
return undefined;
277284
}
278285

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @jsx: preserve
4+
// @filename: foo.tsx
5+
6+
////const A = () => {
7+
//// return (<div onClick={() => handleClick()}></div>);
8+
////}
9+
10+
verify.codeFix({
11+
index: 0,
12+
description: [ts.Diagnostics.Add_missing_function_declaration_0.message, "handleClick"],
13+
newFileContent:
14+
`const A = () => {
15+
function handleClick() {
16+
throw new Error("Function not implemented.");
17+
}
18+
19+
return (<div onClick={() => handleClick()}></div>);
20+
}`
21+
});

0 commit comments

Comments
 (0)