fix(compiler): report better error on interpolation in an expression (#30300)
Compiler results in weird error message when encounters interpolation inside existing expression context, e.g. *ngIf="name {{ name }}" PR Close #30300
This commit is contained in:
parent
23c36a24ed
commit
94e790d4ee
|
@ -974,7 +974,8 @@ export class _ParseAST {
|
||||||
} else {
|
} else {
|
||||||
// Otherwise the key must be a directive keyword, like "of". Transform
|
// Otherwise the key must be a directive keyword, like "of". Transform
|
||||||
// the key to actual key. Eg. of -> ngForOf, trackBy -> ngForTrackBy
|
// the key to actual key. Eg. of -> ngForOf, trackBy -> ngForTrackBy
|
||||||
key.source = templateKey.source + key.source[0].toUpperCase() + key.source.substring(1);
|
key.source =
|
||||||
|
templateKey.source + key.source.charAt(0).toUpperCase() + key.source.substring(1);
|
||||||
bindings.push(...this.parseDirectiveKeywordBindings(key));
|
bindings.push(...this.parseDirectiveKeywordBindings(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -779,6 +779,14 @@ describe('parser', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should report unexpected token when encountering interpolation', () => {
|
||||||
|
const attr = '*ngIf="name && {{name}}"';
|
||||||
|
|
||||||
|
expectParseTemplateBindingsError(
|
||||||
|
attr,
|
||||||
|
'Parser Error: Unexpected token {, expected identifier, keyword, or string at column 10 in [name && {{name}}] in foo.html');
|
||||||
|
});
|
||||||
|
|
||||||
it('should map variable declaration via "as"', () => {
|
it('should map variable declaration via "as"', () => {
|
||||||
const attr =
|
const attr =
|
||||||
'*ngFor="let item; of items | slice:0:1 as collection, trackBy: func; index as i"';
|
'*ngFor="let item; of items | slice:0:1 as collection, trackBy: func; index as i"';
|
||||||
|
@ -1026,17 +1034,25 @@ function parseBinding(text: string, location: any = null, offset: number = 0): A
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTemplateBindings(attribute: string, templateUrl = 'foo.html'): TemplateBinding[] {
|
function parseTemplateBindings(attribute: string, templateUrl = 'foo.html'): TemplateBinding[] {
|
||||||
|
const result = _parseTemplateBindings(attribute, templateUrl);
|
||||||
|
expect(result.errors).toEqual([]);
|
||||||
|
expect(result.warnings).toEqual([]);
|
||||||
|
return result.templateBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectParseTemplateBindingsError(attribute: string, error: string) {
|
||||||
|
const result = _parseTemplateBindings(attribute, 'foo.html');
|
||||||
|
expect(result.errors[0].message).toEqual(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _parseTemplateBindings(attribute: string, templateUrl: string) {
|
||||||
const match = attribute.match(/^\*(.+)="(.*)"$/);
|
const match = attribute.match(/^\*(.+)="(.*)"$/);
|
||||||
expect(match).toBeTruthy(`failed to extract key and value from ${attribute}`);
|
expect(match).toBeTruthy(`failed to extract key and value from ${attribute}`);
|
||||||
const [_, key, value] = match;
|
const [_, key, value] = match;
|
||||||
const absKeyOffset = 1; // skip the * prefix
|
const absKeyOffset = 1; // skip the * prefix
|
||||||
const absValueOffset = attribute.indexOf('=') + '="'.length;
|
const absValueOffset = attribute.indexOf('=') + '="'.length;
|
||||||
const parser = createParser();
|
const parser = createParser();
|
||||||
const result =
|
return parser.parseTemplateBindings(key, value, templateUrl, absKeyOffset, absValueOffset);
|
||||||
parser.parseTemplateBindings(key, value, templateUrl, absKeyOffset, absValueOffset);
|
|
||||||
expect(result.errors).toEqual([]);
|
|
||||||
expect(result.warnings).toEqual([]);
|
|
||||||
return result.templateBindings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseInterpolation(text: string, location: any = null, offset: number = 0): ASTWithSource|
|
function parseInterpolation(text: string, location: any = null, offset: number = 0): ASTWithSource|
|
||||||
|
|
Loading…
Reference in New Issue