fix(compiler): throw error for duplicate template references (#40538)

Adds an error if a reference is used more than once on the same element (e.g. `<div #a #a>`).
We used to have this error in ViewEngine, but it wasn't ported over to Ivy.

Fixes #40536.

PR Close #40538
This commit is contained in:
Kristiyan Kostadinov 2021-01-23 22:10:12 +01:00 committed by Alex Rickabaugh
parent 03f0b157c1
commit 9478cda83b
2 changed files with 12 additions and 0 deletions

View File

@ -458,6 +458,8 @@ class HtmlAstToIvyAst implements html.Visitor {
this.reportError(`"-" is not allowed in reference names`, sourceSpan); this.reportError(`"-" is not allowed in reference names`, sourceSpan);
} else if (identifier.length === 0) { } else if (identifier.length === 0) {
this.reportError(`Reference does not have a name`, sourceSpan); this.reportError(`Reference does not have a name`, sourceSpan);
} else if (references.some(reference => reference.name === identifier)) {
this.reportError(`Reference "#${identifier}" is defined more than once`, sourceSpan);
} }
references.push(new t.Reference(identifier, value, sourceSpan, keySpan, valueSpan)); references.push(new t.Reference(identifier, value, sourceSpan, keySpan, valueSpan));

View File

@ -273,6 +273,11 @@ describe('R3 template transform', () => {
]); ]);
}); });
it('should report an error if a reference is used multiple times on the same template', () => {
expect(() => parse('<ng-template #a #a></ng-template>'))
.toThrowError(/Reference "#a" is defined more than once/);
});
it('should parse variables via let-...', () => { it('should parse variables via let-...', () => {
expectFromHtml('<ng-template let-a="b"></ng-template>').toEqual([ expectFromHtml('<ng-template let-a="b"></ng-template>').toEqual([
['Template'], ['Template'],
@ -463,6 +468,11 @@ describe('R3 template transform', () => {
it('should report missing reference names', () => { it('should report missing reference names', () => {
expect(() => parse('<div #></div>')).toThrowError(/Reference does not have a name/); expect(() => parse('<div #></div>')).toThrowError(/Reference does not have a name/);
}); });
it('should report an error if a reference is used multiple times on the same element', () => {
expect(() => parse('<div #a #a></div>'))
.toThrowError(/Reference "#a" is defined more than once/);
});
}); });
describe('literal attribute', () => { describe('literal attribute', () => {