Skip to content

Commit fb22f18

Browse files
Keen Yee Liaumhevery
authored andcommitted
fix(language-service): Insert parentheses for method completion (#33860)
This commit leverages the `insertText` field in `ts.CompletionEntry` to return a completion text for class methods that includes parentheses. PR closes angular/vscode-ng-language-service#15 PR Close #33860
1 parent db4789b commit fb22f18

File tree

4 files changed

+102
-44
lines changed

4 files changed

+102
-44
lines changed

integration/language_service_plugin/goldens/completionInfo.json

Lines changed: 88 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,222 +12,266 @@
1212
{
1313
"name": "anchor",
1414
"kind": "method",
15-
"sortText": "anchor"
15+
"sortText": "anchor",
16+
"insertText": "anchor()"
1617
},
1718
{
1819
"name": "big",
1920
"kind": "method",
20-
"sortText": "big"
21+
"sortText": "big",
22+
"insertText": "big()"
2123
},
2224
{
2325
"name": "blink",
2426
"kind": "method",
25-
"sortText": "blink"
27+
"sortText": "blink",
28+
"insertText": "blink()"
2629
},
2730
{
2831
"name": "bold",
2932
"kind": "method",
30-
"sortText": "bold"
33+
"sortText": "bold",
34+
"insertText": "bold()"
3135
},
3236
{
3337
"name": "charAt",
3438
"kind": "method",
35-
"sortText": "charAt"
39+
"sortText": "charAt",
40+
"insertText": "charAt()"
3641
},
3742
{
3843
"name": "charCodeAt",
3944
"kind": "method",
40-
"sortText": "charCodeAt"
45+
"sortText": "charCodeAt",
46+
"insertText": "charCodeAt()"
4147
},
4248
{
4349
"name": "codePointAt",
4450
"kind": "method",
45-
"sortText": "codePointAt"
51+
"sortText": "codePointAt",
52+
"insertText": "codePointAt()"
4653
},
4754
{
4855
"name": "concat",
4956
"kind": "method",
50-
"sortText": "concat"
57+
"sortText": "concat",
58+
"insertText": "concat()"
5159
},
5260
{
5361
"name": "endsWith",
5462
"kind": "method",
55-
"sortText": "endsWith"
63+
"sortText": "endsWith",
64+
"insertText": "endsWith()"
5665
},
5766
{
5867
"name": "fixed",
5968
"kind": "method",
60-
"sortText": "fixed"
69+
"sortText": "fixed",
70+
"insertText": "fixed()"
6171
},
6272
{
6373
"name": "fontcolor",
6474
"kind": "method",
65-
"sortText": "fontcolor"
75+
"sortText": "fontcolor",
76+
"insertText": "fontcolor()"
6677
},
6778
{
6879
"name": "fontsize",
6980
"kind": "method",
70-
"sortText": "fontsize"
81+
"sortText": "fontsize",
82+
"insertText": "fontsize()"
7183
},
7284
{
7385
"name": "includes",
7486
"kind": "method",
75-
"sortText": "includes"
87+
"sortText": "includes",
88+
"insertText": "includes()"
7689
},
7790
{
7891
"name": "indexOf",
7992
"kind": "method",
80-
"sortText": "indexOf"
93+
"sortText": "indexOf",
94+
"insertText": "indexOf()"
8195
},
8296
{
8397
"name": "italics",
8498
"kind": "method",
85-
"sortText": "italics"
99+
"sortText": "italics",
100+
"insertText": "italics()"
86101
},
87102
{
88103
"name": "lastIndexOf",
89104
"kind": "method",
90-
"sortText": "lastIndexOf"
105+
"sortText": "lastIndexOf",
106+
"insertText": "lastIndexOf()"
91107
},
92108
{
93109
"name": "length",
94110
"kind": "property",
95-
"sortText": "length"
111+
"sortText": "length",
112+
"insertText": "length"
96113
},
97114
{
98115
"name": "link",
99116
"kind": "method",
100-
"sortText": "link"
117+
"sortText": "link",
118+
"insertText": "link()"
101119
},
102120
{
103121
"name": "localeCompare",
104122
"kind": "method",
105-
"sortText": "localeCompare"
123+
"sortText": "localeCompare",
124+
"insertText": "localeCompare()"
106125
},
107126
{
108127
"name": "match",
109128
"kind": "method",
110-
"sortText": "match"
129+
"sortText": "match",
130+
"insertText": "match()"
111131
},
112132
{
113133
"name": "normalize",
114134
"kind": "method",
115-
"sortText": "normalize"
135+
"sortText": "normalize",
136+
"insertText": "normalize()"
116137
},
117138
{
118139
"name": "padEnd",
119140
"kind": "method",
120-
"sortText": "padEnd"
141+
"sortText": "padEnd",
142+
"insertText": "padEnd()"
121143
},
122144
{
123145
"name": "padStart",
124146
"kind": "method",
125-
"sortText": "padStart"
147+
"sortText": "padStart",
148+
"insertText": "padStart()"
126149
},
127150
{
128151
"name": "repeat",
129152
"kind": "method",
130-
"sortText": "repeat"
153+
"sortText": "repeat",
154+
"insertText": "repeat()"
131155
},
132156
{
133157
"name": "replace",
134158
"kind": "method",
135-
"sortText": "replace"
159+
"sortText": "replace",
160+
"insertText": "replace()"
136161
},
137162
{
138163
"name": "search",
139164
"kind": "method",
140-
"sortText": "search"
165+
"sortText": "search",
166+
"insertText": "search()"
141167
},
142168
{
143169
"name": "slice",
144170
"kind": "method",
145-
"sortText": "slice"
171+
"sortText": "slice",
172+
"insertText": "slice()"
146173
},
147174
{
148175
"name": "small",
149176
"kind": "method",
150-
"sortText": "small"
177+
"sortText": "small",
178+
"insertText": "small()"
151179
},
152180
{
153181
"name": "split",
154182
"kind": "method",
155-
"sortText": "split"
183+
"sortText": "split",
184+
"insertText": "split()"
156185
},
157186
{
158187
"name": "startsWith",
159188
"kind": "method",
160-
"sortText": "startsWith"
189+
"sortText": "startsWith",
190+
"insertText": "startsWith()"
161191
},
162192
{
163193
"name": "strike",
164194
"kind": "method",
165-
"sortText": "strike"
195+
"sortText": "strike",
196+
"insertText": "strike()"
166197
},
167198
{
168199
"name": "sub",
169200
"kind": "method",
170-
"sortText": "sub"
201+
"sortText": "sub",
202+
"insertText": "sub()"
171203
},
172204
{
173205
"name": "substr",
174206
"kind": "method",
175-
"sortText": "substr"
207+
"sortText": "substr",
208+
"insertText": "substr()"
176209
},
177210
{
178211
"name": "substring",
179212
"kind": "method",
180-
"sortText": "substring"
213+
"sortText": "substring",
214+
"insertText": "substring()"
181215
},
182216
{
183217
"name": "sup",
184218
"kind": "method",
185-
"sortText": "sup"
219+
"sortText": "sup",
220+
"insertText": "sup()"
186221
},
187222
{
188223
"name": "toLocaleLowerCase",
189224
"kind": "method",
190-
"sortText": "toLocaleLowerCase"
225+
"sortText": "toLocaleLowerCase",
226+
"insertText": "toLocaleLowerCase()"
191227
},
192228
{
193229
"name": "toLocaleUpperCase",
194230
"kind": "method",
195-
"sortText": "toLocaleUpperCase"
231+
"sortText": "toLocaleUpperCase",
232+
"insertText": "toLocaleUpperCase()"
196233
},
197234
{
198235
"name": "toLowerCase",
199236
"kind": "method",
200-
"sortText": "toLowerCase"
237+
"sortText": "toLowerCase",
238+
"insertText": "toLowerCase()"
201239
},
202240
{
203241
"name": "toString",
204242
"kind": "method",
205-
"sortText": "toString"
243+
"sortText": "toString",
244+
"insertText": "toString()"
206245
},
207246
{
208247
"name": "toUpperCase",
209248
"kind": "method",
210-
"sortText": "toUpperCase"
249+
"sortText": "toUpperCase",
250+
"insertText": "toUpperCase()"
211251
},
212252
{
213253
"name": "trim",
214254
"kind": "method",
215-
"sortText": "trim"
255+
"sortText": "trim",
256+
"insertText": "trim()"
216257
},
217258
{
218259
"name": "trimLeft",
219260
"kind": "method",
220-
"sortText": "trimLeft"
261+
"sortText": "trimLeft",
262+
"insertText": "trimLeft()"
221263
},
222264
{
223265
"name": "trimRight",
224266
"kind": "method",
225-
"sortText": "trimRight"
267+
"sortText": "trimRight",
268+
"insertText": "trimRight()"
226269
},
227270
{
228271
"name": "valueOf",
229272
"kind": "method",
230-
"sortText": "valueOf"
273+
"sortText": "valueOf",
274+
"insertText": "valueOf()"
231275
}
232276
]
233277
}

packages/language-service/src/completions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ class ExpressionVisitor extends NullTemplateVisitor {
442442
name: s.name,
443443
kind: s.kind as ng.CompletionKind,
444444
sortText: s.name,
445+
insertText: s.callable ? `${s.name}()` : s.name,
445446
});
446447
}
447448
}

packages/language-service/test/completions_spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,18 @@ describe('completions', () => {
213213
expectContain(completions, CompletionKind.METHOD, ['myClick']);
214214
});
215215

216+
it('for methods should include parentheses', () => {
217+
mockHost.override(TEST_TEMPLATE, `<div (click)="~{cursor}"></div>`);
218+
const marker = mockHost.getLocationMarkerFor(TEST_TEMPLATE, 'cursor');
219+
const completions = ngLS.getCompletionsAt(TEST_TEMPLATE, marker.start);
220+
expect(completions).toBeDefined();
221+
expect(completions !.entries).toContain(jasmine.objectContaining({
222+
name: 'myClick',
223+
kind: CompletionKind.METHOD as any,
224+
insertText: 'myClick()',
225+
}));
226+
});
227+
216228
describe('in external template', () => {
217229
it('should be able to get entity completions in external template', () => {
218230
const marker = mockHost.getLocationMarkerFor(TEST_TEMPLATE, 'entity-amp');

packages/language-service/test/ts_plugin_spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ describe('plugin', () => {
128128
kind: CompletionKind.PROPERTY as any,
129129
sortText: 'children',
130130
replacementSpan: {start: 182, length: 8},
131+
insertText: 'children',
131132
},
132133
]);
133134
});

0 commit comments

Comments
 (0)