Skip to content

Commit 2fff618

Browse files
committed
adding test cases
1 parent 87b09f8 commit 2fff618

11 files changed

+360
-28
lines changed

src/compiler/diagnosticMessages.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7644,7 +7644,7 @@
76447644
"category": "Message",
76457645
"code": 95186
76467646
},
7647-
"Add missing comma for an object member completion '{0}'.": {
7647+
"Add missing comma for object member completion '{0}'.": {
76487648
"category": "Message",
76497649
"code": 95187
76507650
},

src/services/completions.ts

+25-14
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ import {
6565
find,
6666
findAncestor,
6767
findChildOfKind,
68-
findNextToken,
6968
findPrecedingToken,
7069
first,
7170
firstDefined,
@@ -1683,14 +1682,15 @@ function createCompletionEntry(
16831682
}
16841683
}
16851684

1686-
if ((origin?.kind === SymbolOriginInfoKind.TypeOnlyAlias)) {
1685+
if (origin?.kind === SymbolOriginInfoKind.TypeOnlyAlias) {
16871686
hasAction = true;
16881687
}
16891688

16901689
if (completionKind === CompletionKind.ObjectPropertyDeclaration && contextToken &&
16911690
findPrecedingToken(contextToken.pos, sourceFile, contextToken)?.kind !== SyntaxKind.CommaToken &&
1692-
findNextToken(contextToken, contextToken.parent, sourceFile)?.kind !== SyntaxKind.CommaToken &&
1693-
(findAncestor(contextToken.parent, (node: Node) => isPropertyAssignment(node))?.getLastToken() === contextToken || isMethodDeclaration(contextToken.parent.parent))) {
1691+
(isMethodDeclaration(contextToken.parent.parent) || isSpreadAssignment(contextToken.parent) || findAncestor(contextToken.parent, (node: Node) => isPropertyAssignment(node))?.getLastToken() === contextToken ||
1692+
isShorthandPropertyAssignment(contextToken.parent) && getLineAndCharacterOfPosition(contextToken.getSourceFile(), contextToken.getEnd()).line !== getLineAndCharacterOfPosition(contextToken.getSourceFile(), position).line)) {
1693+
16941694
source = CompletionSource.ObjectLiteralMemberWithComma;
16951695
hasAction = true;
16961696
}
@@ -2882,7 +2882,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay(
28822882
sourceDisplay: undefined,
28832883
codeActions: [{
28842884
changes,
2885-
description: diagnosticToString([Diagnostics.Add_missing_comma_for_an_object_member_completion_0, name]),
2885+
description: diagnosticToString([Diagnostics.Add_missing_comma_for_object_member_completion_0, name]),
28862886
}],
28872887
};
28882888
}
@@ -4184,7 +4184,7 @@ function getCompletionData(
41844184
*/
41854185
function tryGetObjectLikeCompletionSymbols(): GlobalsSearch | undefined {
41864186
const symbolsStartIndex = symbols.length;
4187-
const objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken);
4187+
const objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken, position);
41884188
if (!objectLikeContainer) return GlobalsSearch.Continue;
41894189

41904190
// We're looking up possible property names from contextual/inferred/declared type.
@@ -4912,7 +4912,7 @@ function getCompletionData(
49124912
* Returns the immediate owning object literal or binding pattern of a context token,
49134913
* on the condition that one exists and that the context implies completion should be given.
49144914
*/
4915-
function tryGetObjectLikeCompletionContainer(contextToken: Node | undefined): ObjectLiteralExpression | ObjectBindingPattern | undefined {
4915+
function tryGetObjectLikeCompletionContainer(contextToken: Node | undefined, position: number): ObjectLiteralExpression | ObjectBindingPattern | undefined {
49164916
if (contextToken) {
49174917
const { parent } = contextToken;
49184918
switch (contextToken.kind) {
@@ -4922,19 +4922,30 @@ function tryGetObjectLikeCompletionContainer(contextToken: Node | undefined): Ob
49224922
return parent;
49234923
}
49244924
break;
4925-
case SyntaxKind.CloseBraceToken: // const x = { } |
4926-
if (parent.parent && parent.parent.parent && isMethodDeclaration(parent.parent) && isObjectLiteralExpression(parent.parent.parent)) {
4927-
return parent.parent.parent;
4928-
}
4929-
break;
49304925
case SyntaxKind.AsteriskToken:
49314926
return isMethodDeclaration(parent) ? tryCast(parent.parent, isObjectLiteralExpression) : undefined;
49324927
case SyntaxKind.AsyncKeyword:
49334928
return tryCast(parent.parent, isObjectLiteralExpression);
49344929
case SyntaxKind.Identifier:
4935-
return (contextToken as Identifier).text === "async" && isShorthandPropertyAssignment(contextToken.parent)
4936-
? contextToken.parent.parent : undefined;
4930+
if ((contextToken as Identifier).text === "async" && isShorthandPropertyAssignment(contextToken.parent)) {
4931+
return contextToken.parent.parent;
4932+
}
4933+
else {
4934+
if (isObjectLiteralExpression(contextToken.parent.parent) &&
4935+
(isSpreadAssignment(contextToken.parent) || isShorthandPropertyAssignment(contextToken.parent) &&
4936+
(getLineAndCharacterOfPosition(contextToken.getSourceFile(), contextToken.getEnd()).line !== getLineAndCharacterOfPosition(contextToken.getSourceFile(), position).line))) {
4937+
return contextToken.parent.parent;
4938+
}
4939+
const ancestorNode = findAncestor(parent, (node: Node) => isPropertyAssignment(node));
4940+
if (ancestorNode && ancestorNode.getLastToken() === contextToken && isObjectLiteralExpression(ancestorNode.parent)) {
4941+
return ancestorNode.parent;
4942+
}
4943+
}
4944+
break;
49374945
default:
4946+
if (parent.parent && parent.parent.parent && isMethodDeclaration(parent.parent) && isObjectLiteralExpression(parent.parent.parent)) {
4947+
return parent.parent.parent;
4948+
}
49384949
const ancestorNode = findAncestor(parent, (node: Node) => isPropertyAssignment(node));
49394950
if (contextToken.kind !== SyntaxKind.ColonToken && ancestorNode && ancestorNode.getLastToken() === contextToken &&
49404951
isObjectLiteralExpression(ancestorNode.parent)) {

tests/cases/fourslash/completionsObjectLiteralExpressions1.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ verify.completions({
2525

2626
verify.applyCodeActionFromCompletion("", {
2727
name: "secondary",
28-
description: `Add missing comma for an object member completion 'secondary'.`,
28+
description: `Add missing comma for object member completion 'secondary'.`,
2929
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
3030
newFileContent:
3131
`interface ColorPalette {

tests/cases/fourslash/completionsObjectLiteralExpressions2.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ verify.completions({
2828

2929
verify.applyCodeActionFromCompletion("", {
3030
name: "secondary",
31-
description: `Add missing comma for an object member completion 'secondary'.`,
31+
description: `Add missing comma for object member completion 'secondary'.`,
3232
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
3333
newFileContent:
3434
`interface ColorPalette {

tests/cases/fourslash/completionsObjectLiteralExpressions3.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
//// /**/
1111
//// }
1212

13-
14-
1513
verify.completions({
1614
marker: "",
1715
includes: [{
@@ -24,11 +22,11 @@ verify.completions({
2422
allowIncompleteCompletions: true,
2523
includeInsertTextCompletions: true,
2624
},
27-
});
25+
});
2826

29-
verify.applyCodeActionFromCompletion("", {
27+
verify.applyCodeActionFromCompletion("", {
3028
name: "aaa",
31-
description: `Add missing comma for an object member completion 'aaa'.`,
29+
description: `Add missing comma for object member completion 'aaa'.`,
3230
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
3331
newFileContent:
3432
`interface T {

tests/cases/fourslash/completionsObjectLiteralExpressions4.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
//// /**/
99
//// }
1010

11-
12-
1311
verify.completions({
1412
marker: "",
1513
includes: [{
@@ -22,11 +20,11 @@ verify.completions({
2220
allowIncompleteCompletions: true,
2321
includeInsertTextCompletions: true,
2422
},
25-
});
23+
});
2624

27-
verify.applyCodeActionFromCompletion("", {
25+
verify.applyCodeActionFromCompletion("", {
2826
name: "bbb",
29-
description: `Add missing comma for an object member completion 'bbb'.`,
27+
description: `Add missing comma for object member completion 'bbb'.`,
3028
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
3129
newFileContent:
3230
`interface T {
@@ -41,4 +39,4 @@ verify.completions({
4139
allowIncompleteCompletions: true,
4240
includeInsertTextCompletions: true,
4341
},
44-
});
42+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
//// type E = {}
4+
//// type F = string
5+
//// interface I { e: E, f?: F }
6+
//// const i: I = { e: {}
7+
//// /**/
8+
//// };
9+
10+
verify.completions({
11+
marker: "",
12+
includes: [{
13+
name: "f",
14+
sortText: completion.SortText.OptionalMember,
15+
hasAction: true,
16+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
17+
}],
18+
preferences: {
19+
allowIncompleteCompletions: true,
20+
includeInsertTextCompletions: true,
21+
},
22+
});
23+
24+
verify.applyCodeActionFromCompletion("", {
25+
name: "f",
26+
description: `Add missing comma for object member completion 'f'.`,
27+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
28+
newFileContent:
29+
`type E = {}
30+
type F = string
31+
interface I { e: E, f?: F }
32+
const i: I = { e: {},
33+
34+
};`,
35+
preferences: {
36+
allowIncompleteCompletions: true,
37+
includeInsertTextCompletions: true,
38+
},
39+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
3+
/// <reference path="fourslash.ts" />
4+
5+
//// type E = {}
6+
//// type F = string
7+
//// const i= { e: {} };
8+
//// interface I { e: E, f?: F }
9+
//// const k: I = {
10+
//// ["e"]: i
11+
//// /**/
12+
//// }
13+
14+
verify.completions({
15+
marker: "",
16+
includes: [{
17+
name: "f",
18+
sortText: completion.SortText.OptionalMember,
19+
hasAction: true,
20+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
21+
}],
22+
preferences: {
23+
allowIncompleteCompletions: true,
24+
includeInsertTextCompletions: true,
25+
},
26+
});
27+
28+
verify.applyCodeActionFromCompletion("", {
29+
name: "f",
30+
description: `Add missing comma for object member completion 'f'.`,
31+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
32+
newFileContent:
33+
`type E = {}
34+
type F = string
35+
const i= { e: {} };
36+
interface I { e: E, f?: F }
37+
const k: I = {
38+
["e"]: i,
39+
40+
}`,
41+
preferences: {
42+
allowIncompleteCompletions: true,
43+
includeInsertTextCompletions: true,
44+
},
45+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
3+
/// <reference path="fourslash.ts" />
4+
5+
//// interface pp {
6+
//// aaa: string;
7+
//// bbb: number;
8+
//// }
9+
////
10+
//// const abc: pp = {
11+
//// aaa: "",
12+
//// bbb: 1,
13+
//// }
14+
////
15+
//// const cab: pp = {
16+
//// ...abc
17+
//// /**/
18+
//// }
19+
20+
verify.completions({
21+
marker: "",
22+
includes: [{
23+
name: "aaa",
24+
sortText: completion.SortText.MemberDeclaredBySpreadAssignment,
25+
hasAction: true,
26+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
27+
}],
28+
preferences: {
29+
allowIncompleteCompletions: true,
30+
includeInsertTextCompletions: true,
31+
},
32+
});
33+
34+
verify.applyCodeActionFromCompletion("", {
35+
name: "aaa",
36+
description: `Add missing comma for object member completion 'aaa'.`,
37+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
38+
newFileContent:
39+
`interface pp {
40+
aaa: string;
41+
bbb: number;
42+
}
43+
44+
const abc: pp = {
45+
aaa: "",
46+
bbb: 1,
47+
}
48+
49+
const cab: pp = {
50+
...abc,
51+
52+
}`,
53+
preferences: {
54+
allowIncompleteCompletions: true,
55+
includeInsertTextCompletions: true,
56+
},
57+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
//// interface A {
4+
//// b: string,
5+
//// c?: number,
6+
//// }
7+
//// const b = ""
8+
//// const a: A = {
9+
//// b
10+
//// /**/
11+
//// }
12+
13+
verify.completions({
14+
marker: "",
15+
includes: [{
16+
name: "c",
17+
sortText: completion.SortText.OptionalMember,
18+
hasAction: true,
19+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
20+
}],
21+
preferences: {
22+
allowIncompleteCompletions: true,
23+
includeInsertTextCompletions: true,
24+
},
25+
});
26+
27+
verify.applyCodeActionFromCompletion("", {
28+
name: "c",
29+
description: `Add missing comma for object member completion 'c'.`,
30+
source: completion.CompletionSource.ObjectLiteralMemberWithComma,
31+
newFileContent:
32+
`interface A {
33+
b: string,
34+
c?: number,
35+
}
36+
const b = ""
37+
const a: A = {
38+
b,
39+
40+
}`,
41+
preferences: {
42+
allowIncompleteCompletions: true,
43+
includeInsertTextCompletions: true,
44+
},
45+
});

0 commit comments

Comments
 (0)