fix(compiler): report better error messages for `host` bindings
Closes #10346
This commit is contained in:
parent
0a46f37444
commit
fb3608aa5d
|
@ -22,7 +22,8 @@ export class ParseSourceFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ParseSourceSpan {
|
export class ParseSourceSpan {
|
||||||
constructor(public start: ParseLocation, public end: ParseLocation) {}
|
constructor(
|
||||||
|
public start: ParseLocation, public end: ParseLocation, public details: string = null) {}
|
||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
return this.start.file.content.substring(this.start.offset, this.end.offset);
|
return this.start.file.content.substring(this.start.offset, this.end.offset);
|
||||||
|
@ -43,6 +44,7 @@ export abstract class ParseError {
|
||||||
var source = this.span.start.file.content;
|
var source = this.span.start.file.content;
|
||||||
var ctxStart = this.span.start.offset;
|
var ctxStart = this.span.start.offset;
|
||||||
var contextStr = '';
|
var contextStr = '';
|
||||||
|
var details = '';
|
||||||
if (isPresent(ctxStart)) {
|
if (isPresent(ctxStart)) {
|
||||||
if (ctxStart > source.length - 1) {
|
if (ctxStart > source.length - 1) {
|
||||||
ctxStart = source.length - 1;
|
ctxStart = source.length - 1;
|
||||||
|
@ -77,6 +79,9 @@ export abstract class ParseError {
|
||||||
source.substring(this.span.start.offset, ctxEnd + 1);
|
source.substring(this.span.start.offset, ctxEnd + 1);
|
||||||
contextStr = ` ("${context}")`;
|
contextStr = ` ("${context}")`;
|
||||||
}
|
}
|
||||||
return `${this.msg}${contextStr}: ${this.span.start}`;
|
if (this.span.details) {
|
||||||
|
details = `, ${this.span.details}`;
|
||||||
|
}
|
||||||
|
return `${this.msg}${contextStr}: ${this.span.start}${details}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -675,10 +675,12 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||||
private _createDirectiveAsts(
|
private _createDirectiveAsts(
|
||||||
isTemplateElement: boolean, elementName: string, directives: CompileDirectiveMetadata[],
|
isTemplateElement: boolean, elementName: string, directives: CompileDirectiveMetadata[],
|
||||||
props: BoundElementOrDirectiveProperty[], elementOrDirectiveRefs: ElementOrDirectiveRef[],
|
props: BoundElementOrDirectiveProperty[], elementOrDirectiveRefs: ElementOrDirectiveRef[],
|
||||||
sourceSpan: ParseSourceSpan, targetReferences: ReferenceAst[]): DirectiveAst[] {
|
elementSourceSpan: ParseSourceSpan, targetReferences: ReferenceAst[]): DirectiveAst[] {
|
||||||
const matchedReferences = new Set<string>();
|
const matchedReferences = new Set<string>();
|
||||||
let component: CompileDirectiveMetadata = null;
|
let component: CompileDirectiveMetadata = null;
|
||||||
const directiveAsts = directives.map((directive: CompileDirectiveMetadata) => {
|
const directiveAsts = directives.map((directive: CompileDirectiveMetadata) => {
|
||||||
|
const sourceSpan = new ParseSourceSpan(
|
||||||
|
elementSourceSpan.start, elementSourceSpan.end, `Directive ${directive.type.name}`);
|
||||||
if (directive.isComponent) {
|
if (directive.isComponent) {
|
||||||
component = directive;
|
component = directive;
|
||||||
}
|
}
|
||||||
|
|
|
@ -308,7 +308,7 @@ export function main() {
|
||||||
|
|
||||||
expect(console.warnings).toEqual([[
|
expect(console.warnings).toEqual([[
|
||||||
'Template parse warnings:',
|
'Template parse warnings:',
|
||||||
`Assigning animation triggers within host data as attributes such as "@prop": "exp" is deprecated. Use "[@prop]": "exp" instead! ("[ERROR ->]<div></div>"): TestComp@0:0`
|
`Assigning animation triggers within host data as attributes such as "@prop": "exp" is deprecated. Use "[@prop]": "exp" instead! ("[ERROR ->]<div></div>"): TestComp@0:0, Directive DirA`
|
||||||
].join('\n')]);
|
].join('\n')]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1235,6 +1235,16 @@ Can't have multiple template bindings on one element. Use only one attribute nam
|
||||||
Can't bind to 'invalidProp' since it isn't a known native property ("<div [ERROR ->][invalidProp]></div>"): TestComp@0:5`);
|
Can't bind to 'invalidProp' since it isn't a known native property ("<div [ERROR ->][invalidProp]></div>"): TestComp@0:5`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should report invalid host property names', () => {
|
||||||
|
var dirA = CompileDirectiveMetadata.create({
|
||||||
|
selector: 'div',
|
||||||
|
type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}),
|
||||||
|
host: {'[invalidProp]': 'someProp'}
|
||||||
|
});
|
||||||
|
expect(() => parse('<div></div>', [dirA])).toThrowError(`Template parse errors:
|
||||||
|
Can't bind to 'invalidProp' since it isn't a known native property ("[ERROR ->]<div></div>"): TestComp@0:0, Directive DirA`);
|
||||||
|
});
|
||||||
|
|
||||||
it('should report errors in expressions', () => {
|
it('should report errors in expressions', () => {
|
||||||
expect(() => parse('<div [prop]="a b"></div>', [])).toThrowError(`Template parse errors:
|
expect(() => parse('<div [prop]="a b"></div>', [])).toThrowError(`Template parse errors:
|
||||||
Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [ERROR ->][prop]="a b"></div>"): TestComp@0:5`);
|
Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [ERROR ->][prop]="a b"></div>"): TestComp@0:5`);
|
||||||
|
|
Loading…
Reference in New Issue