fix(compiler): report errors for missing binding names (#34595)

Currently, would-be binding attributes that are missing binding names
are not parsed as bindings, and fall through as regular attributes. In
some cases, this can lead to a runtime error; trying to assign `#` as a
DOM attribute in an element like in `<div #></div>` fails because `#` is
not a valid attribute name.

Attributes composed of binding prefixes but not defining a binding
should be considered invalid, as this almost certainly indicates an
unintentional elision of a binding by the developer. This commit
introduces error reporting for attributes with a binding name prefix but
no actual binding name.

Closes https://github.com/angular/vscode-ng-language-service/issues/293.

PR Close #34595
This commit is contained in:
ayazhafiz
2019-12-28 18:02:09 -06:00
committed by Kara Erickson
parent e1160f19be
commit a92d97cda7
5 changed files with 92 additions and 2 deletions

View File

@ -658,6 +658,11 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
]);
});
it('should report missing property names in bind- syntax', () => {
expect(() => parse('<div bind-></div>', [])).toThrowError(`Template parse errors:
Property name is missing in binding ("<div [ERROR ->]bind-></div>"): TestComp@0:5`);
});
it('should parse bound properties via {{...}} and not report them as attributes', () => {
expect(humanizeTplAst(parse('<div prop="{{v}}">', []))).toEqual([
[ElementAst, 'div'],
@ -684,6 +689,11 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
/Assigning animation triggers via @prop="exp" attributes with an expression is invalid. Use property bindings \(e.g. \[@prop\]="exp"\) or use an attribute without a value \(e.g. @prop\) instead. \("<div \[ERROR ->\]@someAnimation="value2">"\): TestComp@0:5/);
});
it('should report missing animation trigger in @ syntax', () => {
expect(() => parse('<div @></div>', [])).toThrowError(`Template parse errors:
Animation trigger is missing ("<div [ERROR ->]@></div>"): TestComp@0:5`);
});
it('should not issue a warning when host attributes contain a valid property-bound animation trigger',
() => {
const animationEntries = ['prop'];
@ -804,6 +814,11 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
]))).toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', null, 'v']]);
});
it('should report missing event names in on- syntax', () => {
expect(() => parse('<div on-></div>', []))
.toThrowError(/Event name is missing in binding/);
});
it('should allow events on explicit embedded templates that are emitted by a directive',
() => {
const dirA =
@ -840,6 +855,10 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
]);
});
it('should report missing property names in bindon- syntax', () => {
expect(() => parse('<div bindon-></div>', []))
.toThrowError(/Property name is missing in binding/);
});
});
describe('directives', () => {
@ -1372,11 +1391,22 @@ There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA"><
"-" is not allowed in reference names ("<div [ERROR ->]#a-b></div>"): TestComp@0:5`);
});
it('should report missing reference names', () => {
expect(() => parse('<div #></div>', [])).toThrowError(`Template parse errors:
Reference does not have a name ("<div [ERROR ->]#></div>"): TestComp@0:5`);
});
it('should report variables as errors', () => {
expect(() => parse('<div let-a></div>', [])).toThrowError(`Template parse errors:
"let-" is only supported on ng-template elements. ("<div [ERROR ->]let-a></div>"): TestComp@0:5`);
});
it('should report missing variable names', () => {
expect(() => parse('<ng-template let-></ng-template>', []))
.toThrowError(`Template parse errors:
Variable does not have a name ("<ng-template [ERROR ->]let-></ng-template>"): TestComp@0:13`);
});
it('should report duplicate reference names', () => {
expect(() => parse('<div #a></div><div #a></div>', []))
.toThrowError(`Template parse errors: