fix(compiler): report better error messages for `host` bindings

Closes #10346
This commit is contained in:
Tobias Bosch 2016-07-28 02:27:07 -07:00
parent 0a46f37444
commit fb3608aa5d
3 changed files with 21 additions and 4 deletions

View File

@ -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}`;
} }
} }

View File

@ -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;
} }

View File

@ -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`);