Skip to content

Commit e68d48b

Browse files
a-tarasyuktypescript-bot
authored andcommitted
Cherry-pick PR microsoft#46594 into release-4.5
Component commits: cd33fc8 fix(46589): omit ? in method signature completion for optional methods
1 parent 9b80232 commit e68d48b

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

src/services/codefixes/helpers.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ namespace ts.codefix {
3737

3838
type AddNode = PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction;
3939

40+
export const enum PreserveOptionalFlags {
41+
Method = 1 << 0,
42+
Property = 1 << 1,
43+
All = Method | Property
44+
}
45+
4046
/**
4147
* `addClassElement` will not be called if we can't figure out a representation for `symbol` in `enclosingDeclaration`.
4248
* @param body If defined, this will be the body of the member node passed to `addClassElement`. Otherwise, the body will default to a stub.
@@ -50,6 +56,7 @@ namespace ts.codefix {
5056
importAdder: ImportAdder | undefined,
5157
addClassElement: (node: AddNode) => void,
5258
body: Block | undefined,
59+
preserveOptional = PreserveOptionalFlags.All,
5360
isAmbient = false,
5461
): void {
5562
const declarations = symbol.getDeclarations();
@@ -83,7 +90,7 @@ namespace ts.codefix {
8390
/*decorators*/ undefined,
8491
modifiers,
8592
name,
86-
optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
93+
optional && (preserveOptional & PreserveOptionalFlags.Property) ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
8794
typeNode,
8895
/*initializer*/ undefined));
8996
break;
@@ -158,14 +165,14 @@ namespace ts.codefix {
158165
}
159166
else {
160167
Debug.assert(declarations.length === signatures.length, "Declarations and signatures should match count");
161-
addClassElement(createMethodImplementingSignatures(checker, context, enclosingDeclaration, signatures, name, optional, modifiers, quotePreference, body));
168+
addClassElement(createMethodImplementingSignatures(checker, context, enclosingDeclaration, signatures, name, optional && !!(preserveOptional & PreserveOptionalFlags.Method), modifiers, quotePreference, body));
162169
}
163170
}
164171
break;
165172
}
166173

167174
function outputMethod(quotePreference: QuotePreference, signature: Signature, modifiers: NodeArray<Modifier> | undefined, name: PropertyName, body?: Block): void {
168-
const method = createSignatureDeclarationFromSignature(SyntaxKind.MethodDeclaration, context, quotePreference, signature, body, name, modifiers, optional, enclosingDeclaration, importAdder);
175+
const method = createSignatureDeclarationFromSignature(SyntaxKind.MethodDeclaration, context, quotePreference, signature, body, name, modifiers, optional && !!(preserveOptional & PreserveOptionalFlags.Method), enclosingDeclaration, importAdder);
169176
if (method) addClassElement(method);
170177
}
171178
}

src/services/completions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ namespace ts.Completions {
895895
node => {
896896
let requiredModifiers = ModifierFlags.None;
897897
if (isAbstract) {
898-
requiredModifiers |= ModifierFlags.Abstract;
898+
requiredModifiers |= ModifierFlags.Abstract;
899899
}
900900
if (isClassElement(node)
901901
&& checker.getMemberOverrideModifierStatus(classLikeDeclaration, node) === MemberOverrideStatus.NeedsOverride) {
@@ -919,6 +919,7 @@ namespace ts.Completions {
919919
completionNodes.push(node);
920920
},
921921
body,
922+
codefix.PreserveOptionalFlags.Property,
922923
isAbstract);
923924

924925
if (completionNodes.length) {
@@ -3888,5 +3889,6 @@ namespace ts.Completions {
38883889
}
38893890
return charCode;
38903891
}
3892+
38913893
}
38923894

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: a.ts
4+
// @newline: LF
5+
6+
////interface IFoo {
7+
//// a?: number;
8+
//// b?(x: number): void;
9+
////}
10+
////class Foo implements IFoo {
11+
//// /**/
12+
////}
13+
14+
verify.completions({
15+
marker: "",
16+
isNewIdentifierLocation: true,
17+
preferences: {
18+
includeCompletionsWithInsertText: true,
19+
includeCompletionsWithSnippetText: false,
20+
includeCompletionsWithClassMemberSnippets: true,
21+
},
22+
includes: [
23+
{
24+
name: "a",
25+
sortText: completion.SortText.LocationPriority,
26+
replacementSpan: {
27+
fileName: "",
28+
pos: 0,
29+
end: 0,
30+
},
31+
insertText: "a?: number;\n"
32+
},
33+
{
34+
name: "b",
35+
sortText: completion.SortText.LocationPriority,
36+
replacementSpan: {
37+
fileName: "",
38+
pos: 0,
39+
end: 0,
40+
},
41+
insertText: "b(x: number): void {\n}\n"
42+
},
43+
],
44+
});

0 commit comments

Comments
 (0)