Skip to content

Commit 58d52df

Browse files
committed
feat(language-service): Complete inside @switch
We now visit the unknown nodes inside a `@switch` block, enabling completions in that context.
1 parent fcc000e commit 58d52df

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

packages/language-service/src/completions.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {AST, ASTWithSource, BindingPipe, BindingType, Call, EmptyExpr, ImplicitReceiver, LiteralPrimitive, ParsedEventType, ParseSourceSpan, PropertyRead, PropertyWrite, SafePropertyRead, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstElement, TmplAstNode, TmplAstReference, TmplAstTemplate, TmplAstText, TmplAstTextAttribute, TmplAstVariable} from '@angular/compiler';
1010
import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core';
1111
import {CompletionKind, PotentialDirective, SymbolKind, TemplateDeclarationSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
12-
import {BoundEvent, DeferredBlock, TextAttribute, UnknownBlock} from '@angular/compiler/src/render3/r3_ast';
12+
import {BoundEvent, DeferredBlock, SwitchBlock, TextAttribute, UnknownBlock} from '@angular/compiler/src/render3/r3_ast';
1313
import ts from 'typescript';
1414

1515
import {addAttributeCompletionEntries, AsciiSortPriority, AttributeCompletionKind, buildAnimationCompletionEntries, buildAttributeCompletionTable, getAttributeCompletionSymbol} from './attribute_completions';
@@ -130,15 +130,18 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
130130
length: this.node.name.length,
131131
}
132132
};
133-
const completionEntries: ts.CompletionEntry[] = [
134-
...blocksWithParens, ...blocksWithoutParens
135-
].map(name => ({
136-
name,
137-
sortText: `${AsciiSortPriority.First}${name}`,
138-
insertText: buildBlockSnippet(useSnippet, name, blocksWithParens.includes(name)),
139-
isSnippet: useSnippet || undefined,
140-
...partialCompletionEntryWholeBlock,
141-
}));
133+
let competionKeywords: string[] = [...blocksWithParens, ...blocksWithoutParens];
134+
if (this.nodeParent instanceof SwitchBlock) {
135+
competionKeywords = ['case', 'default'];
136+
}
137+
const completionEntries: ts.CompletionEntry[] = competionKeywords.map(
138+
name => ({
139+
name,
140+
sortText: `${AsciiSortPriority.First}${name}`,
141+
insertText: buildBlockSnippet(useSnippet, name, blocksWithParens.includes(name)),
142+
isSnippet: useSnippet || undefined,
143+
...partialCompletionEntryWholeBlock,
144+
}));
142145

143146
// Return the completions.
144147
const completionInfo: ts.CompletionInfo = {

packages/language-service/src/template_target.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ class TemplateTargetVisitor implements t.Visitor {
499499
visitSwitchBlock(block: t.SwitchBlock) {
500500
this.visitBinding(block.expression);
501501
this.visitAll(block.cases);
502+
this.visitAll(block.unknownBlocks);
502503
}
503504

504505
visitSwitchBlockCase(block: t.SwitchBlockCase) {

packages/language-service/test/completions_spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,15 @@ describe('completions', () => {
298298
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.BLOCK),
299299
['switch']);
300300
});
301+
302+
it('inside switch', () => {
303+
const {templateFile} = setup(`@switch (1) { @c }`, ``);
304+
templateFile.moveCursorToText('@c¦');
305+
const completions = templateFile.getCompletionsAtPosition();
306+
expectContain(
307+
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.BLOCK),
308+
['case']);
309+
});
301310
});
302311

303312
describe('in an expression scope', () => {

0 commit comments

Comments
 (0)