Skip to content

Commit

Permalink
fix: Prevent excessive autocompletion in template JS files (#490)
Browse files Browse the repository at this point in the history
* fix: removed curly brace autocomplete in lwc js files (W-10832653)

We shouldn't be checking for curly braces yet in JS files, so this fix ignores them entirely until
we explicitly want to check for something. Updated tests to include JS files as well.

vscode #3902
  • Loading branch information
randi274 authored Mar 16, 2022
1 parent 71e0d34 commit 332082d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 18 deletions.
69 changes: 61 additions & 8 deletions packages/lwc-language-server/src/__tests__/lwc-server.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import Server, { Token, findDynamicContent } from '../lwc-server';
import { getLanguageService } from 'vscode-html-languageservice';
import { TextDocument, InitializeParams, TextDocumentPositionParams, Location, MarkupContent, Hover, CompletionParams } from 'vscode-languageserver';
import {
TextDocument,
InitializeParams,
TextDocumentPositionParams,
Location,
MarkupContent,
Hover,
CompletionParams,
CompletionTriggerKind,
} from 'vscode-languageserver';

import { URI } from 'vscode-uri';
import * as fsExtra from 'fs-extra';
Expand All @@ -10,6 +19,10 @@ const filename = path.resolve('../../test-workspaces/sfdx-workspace/force-app/ma
const uri = URI.file(filename).toString();
const document: TextDocument = TextDocument.create(uri, 'html', 0, fsExtra.readFileSync(filename).toString());

const jsFilename = path.resolve('../../test-workspaces/sfdx-workspace/force-app/main/default/lwc/todo/todo.js');
const jsUri = URI.file(jsFilename).toString();
const jsDocument: TextDocument = TextDocument.create(uri, 'javascript', 0, fsExtra.readFileSync(jsFilename).toString());

const auraFilename = path.resolve('../../test-workspaces/sfdx-workspace/force-app/main/default/aura/todoApp/todoApp.app');
const auraUri = URI.file(auraFilename).toString();
const auraDocument: TextDocument = TextDocument.create(auraFilename, 'html', 0, fsExtra.readFileSync(auraFilename).toString());
Expand Down Expand Up @@ -41,6 +54,7 @@ jest.mock('vscode-languageserver', () => {
get: (name: string): TextDocument => {
const docs = new Map([
[uri, document],
[jsUri, jsDocument],
[auraUri, auraDocument],
[hoverUri, hoverDocument],
]);
Expand Down Expand Up @@ -76,26 +90,44 @@ describe('handlers', () => {
describe('#onCompletion', () => {
it('should return a list of available completion items in a javascript file', async () => {
const params: CompletionParams = {
textDocument: { uri },
textDocument: { uri: jsUri },
position: {
line: 0,
character: 0,
},
context: {
triggerCharacter: '{',
triggerKind: 2,
triggerCharacter: '.',
triggerKind: CompletionTriggerKind.TriggerCharacter,
},
};

await server.onInitialize(initializeParams);
const completions = await server.onCompletion(params);
const labels = completions.items.map(item => item.label);
expect(labels).toBeArrayOfSize(19);
expect(labels).toInclude('handleToggleAll');
expect(labels).toInclude('handleClearCompleted');
expect(labels).toBeArrayOfSize(8);
expect(labels).toInclude('c/todo_util');
expect(labels).toInclude('c/todo_item');
});

it('should not return a list of completion items in a javascript file for open curly brace', async () => {
const params: CompletionParams = {
textDocument: { uri: jsUri },
position: {
line: 0,
character: 0,
},
context: {
triggerCharacter: '{',
triggerKind: CompletionTriggerKind.TriggerCharacter,
},
};

await server.onInitialize(initializeParams);
const completions = await server.onCompletion(params);
expect(completions).toBeUndefined();
});

it('returns a list of available completion items in a LWC template', async () => {
it('returns a list of available tag completion items in a LWC template', async () => {
const params: CompletionParams = {
textDocument: { uri },
position: {
Expand All @@ -114,6 +146,27 @@ describe('handlers', () => {
expect(labels).not.toInclude('lightning:icon'); // this is handled by the aura Lang. server
});

it('should return a list of available attribute completion items in a LWC template', async () => {
const params: CompletionParams = {
textDocument: { uri },
position: {
line: 0,
character: 0,
},
context: {
triggerCharacter: '{',
triggerKind: CompletionTriggerKind.TriggerCharacter,
},
};

await server.onInitialize(initializeParams);
const completions = await server.onCompletion(params);
const labels = completions.items.map(item => item.label);
expect(labels).toBeArrayOfSize(19);
expect(labels).toInclude('handleToggleAll');
expect(labels).toInclude('handleClearCompleted');
});

it('returns a list of available completion items in a Aura template', async () => {
const params: CompletionParams = {
textDocument: { uri: auraUri },
Expand Down
32 changes: 22 additions & 10 deletions packages/lwc-language-server/src/lwc-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export default class Server {
if (await this.context.isLWCTemplate(doc)) {
this.auraDataProvider.activated = false; // provide completions for lwc components in an Aura template
this.lwcDataProvider.activated = true;
if (params.context?.triggerCharacter === '{') {
if (this.shouldProvideBindingsInHTML(params)) {
const docBasename = utils.getBasename(doc);
const customTags: CompletionItem[] = this.findBindItems(docBasename);
return {
Expand All @@ -150,17 +150,21 @@ export default class Server {
};
}
} else if (await this.context.isLWCJavascript(doc)) {
const customTags = this.componentIndexer.customData.map(tag => {
if (this.shouldCompleteJavascript(params)) {
const customTags = this.componentIndexer.customData.map(tag => {
return {
label: tag.lwcTypingsName,
kind: CompletionItemKind.Folder,
};
});

return {
label: tag.lwcTypingsName,
kind: CompletionItemKind.Folder,
isIncomplete: false,
items: customTags,
};
});

return {
isIncomplete: false,
items: customTags,
};
} else {
return;
}
} else if (await this.context.isAuraMarkup(doc)) {
this.auraDataProvider.activated = true;
this.lwcDataProvider.activated = false;
Expand All @@ -170,6 +174,14 @@ export default class Server {
return this.languageService.doComplete(doc, position, htmlDoc);
}

private shouldProvideBindingsInHTML(params: CompletionParams): boolean {
return params.context?.triggerCharacter === '{';
}

private shouldCompleteJavascript(params: CompletionParams): boolean {
return params.context?.triggerCharacter !== '{';
}

private findBindItems(docBasename: string): CompletionItem[] {
const customTags: CompletionItem[] = [];
this.componentIndexer.customData.forEach(t => {
Expand Down

0 comments on commit 332082d

Please sign in to comment.