fix(compiler): do not throw away render3 AST on errors (#39413)
Currently render3's `parseTemplate` throws away the parsed AST and returns an empty list of HTML nodes if HTML->R3 translation failed. This is not preferrable in some contexts like that of a language service, where we would like a well-formed AST even if it is has errors. PR Close #39413
This commit is contained in:
parent
0a63eeaff1
commit
19b88cef71
|
@ -2046,6 +2046,8 @@ export function parseTemplate(
|
|||
{leadingTriviaChars: LEADING_TRIVIA_CHARS, ...options, tokenizeExpansionForms: true});
|
||||
|
||||
if (parseResult.errors && parseResult.errors.length > 0) {
|
||||
// TODO(ayazhafiz): we may not always want to bail out at this point (e.g. in
|
||||
// the context of a language service).
|
||||
return {
|
||||
interpolationConfig,
|
||||
preserveWhitespaces,
|
||||
|
@ -2084,23 +2086,11 @@ export function parseTemplate(
|
|||
|
||||
const {nodes, errors, styleUrls, styles, ngContentSelectors} =
|
||||
htmlAstToRender3Ast(rootNodes, bindingParser);
|
||||
if (errors && errors.length > 0) {
|
||||
return {
|
||||
interpolationConfig,
|
||||
preserveWhitespaces,
|
||||
template,
|
||||
errors,
|
||||
nodes: [],
|
||||
styleUrls: [],
|
||||
styles: [],
|
||||
ngContentSelectors: []
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
interpolationConfig,
|
||||
preserveWhitespaces,
|
||||
errors: null,
|
||||
errors: errors.length > 0 ? errors : null,
|
||||
template,
|
||||
nodes,
|
||||
styleUrls,
|
||||
|
@ -2265,6 +2255,8 @@ export interface ParsedTemplate {
|
|||
|
||||
/**
|
||||
* Any errors from parsing the template the first time.
|
||||
*
|
||||
* `null` if there are no errors. Otherwise, the array of errors is guaranteed to be non-empty.
|
||||
*/
|
||||
errors: ParseError[]|null;
|
||||
|
||||
|
|
|
@ -433,16 +433,17 @@ describe('findNodeAtPosition for expression AST', () => {
|
|||
expect(node).toBeInstanceOf(e.BindingPipe);
|
||||
});
|
||||
|
||||
it('should locate binding pipe without identifier',
|
||||
() => {
|
||||
// TODO: We are not able to locate pipe if identifier is missing because the
|
||||
// parser throws an error. This case is important for autocomplete.
|
||||
// const {errors, nodes, position} = parse(`{{ title | ¦ }}`);
|
||||
// expect(errors).toBe(null);
|
||||
// const node = findNodeAtPosition(nodes, position);
|
||||
// expect(isExpressionNode(node!)).toBe(true);
|
||||
// expect(node).toBeInstanceOf(e.BindingPipe);
|
||||
});
|
||||
it('should locate binding pipe without identifier', () => {
|
||||
const {errors, nodes, position} = parse(`{{ title | ¦ }}`);
|
||||
expect(errors?.length).toBe(1);
|
||||
expect(errors![0].toString())
|
||||
.toContain(
|
||||
'Unexpected end of input, expected identifier or keyword at the end of the expression');
|
||||
const node = findNodeAtPosition(nodes, position);
|
||||
expect(isExpressionNode(node!)).toBe(true);
|
||||
// TODO: We want this to be a BindingPipe.
|
||||
expect(node).toBeInstanceOf(e.Interpolation);
|
||||
});
|
||||
|
||||
it('should locate method call', () => {
|
||||
const {errors, nodes, position} = parse(`{{ title.toString(¦) }}`);
|
||||
|
|
Loading…
Reference in New Issue