From dd944ef73fa43dcc7339abeb806ba4624a38d045 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Fri, 15 Nov 2019 12:06:00 -0800 Subject: [PATCH] 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 --- .../goldens/completionInfo.json | 132 ++++++++++++------ packages/language-service/src/completions.ts | 1 + .../language-service/test/completions_spec.ts | 12 ++ .../language-service/test/ts_plugin_spec.ts | 1 + 4 files changed, 102 insertions(+), 44 deletions(-) diff --git a/integration/language_service_plugin/goldens/completionInfo.json b/integration/language_service_plugin/goldens/completionInfo.json index 546a51b552..bf8179fe96 100644 --- a/integration/language_service_plugin/goldens/completionInfo.json +++ b/integration/language_service_plugin/goldens/completionInfo.json @@ -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()" } ] } diff --git a/packages/language-service/src/completions.ts b/packages/language-service/src/completions.ts index 6553118851..d1944bb3d2 100644 --- a/packages/language-service/src/completions.ts +++ b/packages/language-service/src/completions.ts @@ -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, }); } } diff --git a/packages/language-service/test/completions_spec.ts b/packages/language-service/test/completions_spec.ts index 972cb3db66..feb378b82c 100644 --- a/packages/language-service/test/completions_spec.ts +++ b/packages/language-service/test/completions_spec.ts @@ -213,6 +213,18 @@ describe('completions', () => { expectContain(completions, CompletionKind.METHOD, ['myClick']); }); + it('for methods should include parentheses', () => { + mockHost.override(TEST_TEMPLATE, `
`); + 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'); diff --git a/packages/language-service/test/ts_plugin_spec.ts b/packages/language-service/test/ts_plugin_spec.ts index 740614af67..dbd068940e 100644 --- a/packages/language-service/test/ts_plugin_spec.ts +++ b/packages/language-service/test/ts_plugin_spec.ts @@ -128,6 +128,7 @@ describe('plugin', () => { kind: CompletionKind.PROPERTY as any, sortText: 'children', replacementSpan: {start: 182, length: 8}, + insertText: 'children', }, ]); });