Skip to content

Commit

Permalink
fix(compiler): report better error on interpolation in an expression (#…
Browse files Browse the repository at this point in the history
…30300)

Compiler results in weird error message when encounters interpolation inside
existing expression context, e.g. *ngIf="name {{ name }}"

PR Close #30300
  • Loading branch information
krzysztof-grzybek authored and thePunderWoman committed Nov 25, 2020
1 parent 9dc0a4e commit 6dc74fd
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
3 changes: 2 additions & 1 deletion packages/compiler/src/expression_parser/parser.ts
Expand Up @@ -968,7 +968,8 @@ export class _ParseAST {
} else {
// Otherwise the key must be a directive keyword, like "of". Transform
// 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));
}
}
Expand Down
26 changes: 21 additions & 5 deletions packages/compiler/test/expression_parser/parser_spec.ts
Expand Up @@ -704,6 +704,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"', () => {
const attr =
'*ngFor="let item; of items | slice:0:1 as collection, trackBy: func; index as i"';
Expand Down Expand Up @@ -951,17 +959,25 @@ function parseBinding(text: string, location: any = null, offset: number = 0): A
}

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(/^\*(.+)="(.*)"$/);
expect(match).toBeTruthy(`failed to extract key and value from ${attribute}`);
const [_, key, value] = match;
const absKeyOffset = 1; // skip the * prefix
const absValueOffset = attribute.indexOf('=') + '="'.length;
const parser = createParser();
const result =
parser.parseTemplateBindings(key, value, templateUrl, absKeyOffset, absValueOffset);
expect(result.errors).toEqual([]);
expect(result.warnings).toEqual([]);
return result.templateBindings;
return parser.parseTemplateBindings(key, value, templateUrl, absKeyOffset, absValueOffset);
}

function parseInterpolation(text: string, location: any = null, offset: number = 0): ASTWithSource|
Expand Down

0 comments on commit 6dc74fd

Please sign in to comment.