Skip to content

Commit

Permalink
fix(language-service): two-way binding completion should not remove t…
Browse files Browse the repository at this point in the history
…he trailing quote (#45582)

We allow the path to contain both the `t.BoundAttribute` and `t.BoundEvent` for two-way
bindings but do not want the path to contain both the `t.BoundAttribute` with its
children when the position is in the value span because we would then logically create a path
that also contains the `PropertyWrite` from the `t.BoundEvent`. This early return condition
ensures we target just `t.BoundAttribute` for this case and exclude `t.BoundEvent` children.

Fixes angular/vscode-ng-language-service#1626

PR Close #45582
  • Loading branch information
ivanwonder authored and dylhunn committed Apr 15, 2022
1 parent c6e0e3f commit f57e46c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/language-service/src/template_target.ts
Expand Up @@ -336,6 +336,15 @@ class TemplateTargetVisitor implements t.Visitor {
visitElementOrTemplate(element: t.Template|t.Element) {
this.visitAll(element.attributes);
this.visitAll(element.inputs);
// We allow the path to contain both the `t.BoundAttribute` and `t.BoundEvent` for two-way
// bindings but do not want the path to contain both the `t.BoundAttribute` with its
// children when the position is in the value span because we would then logically create a path
// that also contains the `PropertyWrite` from the `t.BoundEvent`. This early return condition
// ensures we target just `t.BoundAttribute` for this case and exclude `t.BoundEvent` children.
if (this.path[this.path.length - 1] !== element &&
!(this.path[this.path.length - 1] instanceof t.BoundAttribute)) {
return;
}
this.visitAll(element.outputs);
if (element instanceof t.Template) {
this.visitAll(element.templateAttrs);
Expand Down
8 changes: 8 additions & 0 deletions packages/language-service/test/completions_spec.ts
Expand Up @@ -241,6 +241,14 @@ describe('completions', () => {
expectContain(completions, ts.ScriptElementKind.memberVariableElement, ['title']);
});

it('should not include the trailing quote inside the RHS of a two-way binding', () => {
const {templateFile} = setup(`<h1 [(model)]="title."></h1>`, `title!: string;`);
templateFile.moveCursorToText('[(model)]="title.¦"');
const completions = templateFile.getCompletionsAtPosition();
expectContain(completions, ts.ScriptElementKind.memberFunctionElement, ['charAt']);
expectReplacementText(completions, templateFile.contents, '');
});

it('should return completions inside an empty RHS of a two-way binding', () => {
const {templateFile} = setup(`<h1 [(model)]=""></h1>`, `title!: string;`);
templateFile.moveCursorToText('[(model)]="¦"');
Expand Down

0 comments on commit f57e46c

Please sign in to comment.