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 https://github.com/angular/vscode-ng-language-service/issues/15

PR Close #33860
This commit is contained in:
Keen Yee Liau 2019-11-15 12:06:00 -08:00 committed by Miško Hevery
parent c60d7563a8
commit dd944ef73f
4 changed files with 102 additions and 44 deletions

View File

@ -12,222 +12,266 @@
{
"name": "anchor",
"kind": "method",
"sortText": "anchor"
"sortText": "anchor",
"insertText": "anchor()"
},
{
"name": "big",
"kind": "method",
"sortText": "big"
"sortText": "big",
"insertText": "big()"
},
{
"name": "blink",
"kind": "method",
"sortText": "blink"
"sortText": "blink",
"insertText": "blink()"
},
{
"name": "bold",
"kind": "method",
"sortText": "bold"
"sortText": "bold",
"insertText": "bold()"
},
{
"name": "charAt",
"kind": "method",
"sortText": "charAt"
"sortText": "charAt",
"insertText": "charAt()"
},
{
"name": "charCodeAt",
"kind": "method",
"sortText": "charCodeAt"
"sortText": "charCodeAt",
"insertText": "charCodeAt()"
},
{
"name": "codePointAt",
"kind": "method",
"sortText": "codePointAt"
"sortText": "codePointAt",
"insertText": "codePointAt()"
},
{
"name": "concat",
"kind": "method",
"sortText": "concat"
"sortText": "concat",
"insertText": "concat()"
},
{
"name": "endsWith",
"kind": "method",
"sortText": "endsWith"
"sortText": "endsWith",
"insertText": "endsWith()"
},
{
"name": "fixed",
"kind": "method",
"sortText": "fixed"
"sortText": "fixed",
"insertText": "fixed()"
},
{
"name": "fontcolor",
"kind": "method",
"sortText": "fontcolor"
"sortText": "fontcolor",
"insertText": "fontcolor()"
},
{
"name": "fontsize",
"kind": "method",
"sortText": "fontsize"
"sortText": "fontsize",
"insertText": "fontsize()"
},
{
"name": "includes",
"kind": "method",
"sortText": "includes"
"sortText": "includes",
"insertText": "includes()"
},
{
"name": "indexOf",
"kind": "method",
"sortText": "indexOf"
"sortText": "indexOf",
"insertText": "indexOf()"
},
{
"name": "italics",
"kind": "method",
"sortText": "italics"
"sortText": "italics",
"insertText": "italics()"
},
{
"name": "lastIndexOf",
"kind": "method",
"sortText": "lastIndexOf"
"sortText": "lastIndexOf",
"insertText": "lastIndexOf()"
},
{
"name": "length",
"kind": "property",
"sortText": "length"
"sortText": "length",
"insertText": "length"
},
{
"name": "link",
"kind": "method",
"sortText": "link"
"sortText": "link",
"insertText": "link()"
},
{
"name": "localeCompare",
"kind": "method",
"sortText": "localeCompare"
"sortText": "localeCompare",
"insertText": "localeCompare()"
},
{
"name": "match",
"kind": "method",
"sortText": "match"
"sortText": "match",
"insertText": "match()"
},
{
"name": "normalize",
"kind": "method",
"sortText": "normalize"
"sortText": "normalize",
"insertText": "normalize()"
},
{
"name": "padEnd",
"kind": "method",
"sortText": "padEnd"
"sortText": "padEnd",
"insertText": "padEnd()"
},
{
"name": "padStart",
"kind": "method",
"sortText": "padStart"
"sortText": "padStart",
"insertText": "padStart()"
},
{
"name": "repeat",
"kind": "method",
"sortText": "repeat"
"sortText": "repeat",
"insertText": "repeat()"
},
{
"name": "replace",
"kind": "method",
"sortText": "replace"
"sortText": "replace",
"insertText": "replace()"
},
{
"name": "search",
"kind": "method",
"sortText": "search"
"sortText": "search",
"insertText": "search()"
},
{
"name": "slice",
"kind": "method",
"sortText": "slice"
"sortText": "slice",
"insertText": "slice()"
},
{
"name": "small",
"kind": "method",
"sortText": "small"
"sortText": "small",
"insertText": "small()"
},
{
"name": "split",
"kind": "method",
"sortText": "split"
"sortText": "split",
"insertText": "split()"
},
{
"name": "startsWith",
"kind": "method",
"sortText": "startsWith"
"sortText": "startsWith",
"insertText": "startsWith()"
},
{
"name": "strike",
"kind": "method",
"sortText": "strike"
"sortText": "strike",
"insertText": "strike()"
},
{
"name": "sub",
"kind": "method",
"sortText": "sub"
"sortText": "sub",
"insertText": "sub()"
},
{
"name": "substr",
"kind": "method",
"sortText": "substr"
"sortText": "substr",
"insertText": "substr()"
},
{
"name": "substring",
"kind": "method",
"sortText": "substring"
"sortText": "substring",
"insertText": "substring()"
},
{
"name": "sup",
"kind": "method",
"sortText": "sup"
"sortText": "sup",
"insertText": "sup()"
},
{
"name": "toLocaleLowerCase",
"kind": "method",
"sortText": "toLocaleLowerCase"
"sortText": "toLocaleLowerCase",
"insertText": "toLocaleLowerCase()"
},
{
"name": "toLocaleUpperCase",
"kind": "method",
"sortText": "toLocaleUpperCase"
"sortText": "toLocaleUpperCase",
"insertText": "toLocaleUpperCase()"
},
{
"name": "toLowerCase",
"kind": "method",
"sortText": "toLowerCase"
"sortText": "toLowerCase",
"insertText": "toLowerCase()"
},
{
"name": "toString",
"kind": "method",
"sortText": "toString"
"sortText": "toString",
"insertText": "toString()"
},
{
"name": "toUpperCase",
"kind": "method",
"sortText": "toUpperCase"
"sortText": "toUpperCase",
"insertText": "toUpperCase()"
},
{
"name": "trim",
"kind": "method",
"sortText": "trim"
"sortText": "trim",
"insertText": "trim()"
},
{
"name": "trimLeft",
"kind": "method",
"sortText": "trimLeft"
"sortText": "trimLeft",
"insertText": "trimLeft()"
},
{
"name": "trimRight",
"kind": "method",
"sortText": "trimRight"
"sortText": "trimRight",
"insertText": "trimRight()"
},
{
"name": "valueOf",
"kind": "method",
"sortText": "valueOf"
"sortText": "valueOf",
"insertText": "valueOf()"
}
]
}

View File

@ -442,6 +442,7 @@ class ExpressionVisitor extends NullTemplateVisitor {
name: s.name,
kind: s.kind as ng.CompletionKind,
sortText: s.name,
insertText: s.callable ? `${s.name}()` : s.name,
});
}
}

View File

@ -213,6 +213,18 @@ describe('completions', () => {
expectContain(completions, CompletionKind.METHOD, ['myClick']);
});
it('for methods should include parentheses', () => {
mockHost.override(TEST_TEMPLATE, `<div (click)="~{cursor}"></div>`);
const marker = mockHost.getLocationMarkerFor(TEST_TEMPLATE, 'cursor');
const completions = ngLS.getCompletionsAt(TEST_TEMPLATE, marker.start);
expect(completions).toBeDefined();
expect(completions !.entries).toContain(jasmine.objectContaining({
name: 'myClick',
kind: CompletionKind.METHOD as any,
insertText: 'myClick()',
}));
});
describe('in external template', () => {
it('should be able to get entity completions in external template', () => {
const marker = mockHost.getLocationMarkerFor(TEST_TEMPLATE, 'entity-amp');

View File

@ -128,6 +128,7 @@ describe('plugin', () => {
kind: CompletionKind.PROPERTY as any,
sortText: 'children',
replacementSpan: {start: 182, length: 8},
insertText: 'children',
},
]);
});