feat(compiler): support error reporting in I18nMetaVisitor (#39554)

Make it possible to report errors from the I18nMetaVisitor parser.

PR Close #39554
This commit is contained in:
Bjarki 2020-11-03 16:38:18 +00:00 committed by Andrew Kushnir
parent 358c50e226
commit bb70a9bda4
2 changed files with 28 additions and 1 deletions

View File

@ -9,8 +9,10 @@
import {computeDecimalDigest, computeDigest, decimalDigest} from '../../../i18n/digest'; import {computeDecimalDigest, computeDigest, decimalDigest} from '../../../i18n/digest';
import * as i18n from '../../../i18n/i18n_ast'; import * as i18n from '../../../i18n/i18n_ast';
import {createI18nMessageFactory, VisitNodeFn} from '../../../i18n/i18n_parser'; import {createI18nMessageFactory, VisitNodeFn} from '../../../i18n/i18n_parser';
import {I18nError} from '../../../i18n/parse_util';
import * as html from '../../../ml_parser/ast'; import * as html from '../../../ml_parser/ast';
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../../ml_parser/interpolation_config'; import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../../ml_parser/interpolation_config';
import {ParseTreeResult} from '../../../ml_parser/parser';
import * as o from '../../../output/output_ast'; import * as o from '../../../output/output_ast';
import {hasI18nAttrs, I18N_ATTR, I18N_ATTR_PREFIX, icuFromI18nMessage} from './util'; import {hasI18nAttrs, I18N_ATTR, I18N_ATTR_PREFIX, icuFromI18nMessage} from './util';
@ -46,6 +48,7 @@ const setI18nRefs: VisitNodeFn = (htmlNode, i18nNode) => {
export class I18nMetaVisitor implements html.Visitor { export class I18nMetaVisitor implements html.Visitor {
// whether visited nodes contain i18n information // whether visited nodes contain i18n information
public hasI18nMeta: boolean = false; public hasI18nMeta: boolean = false;
private _errors: I18nError[] = [];
// i18n message generation factory // i18n message generation factory
private _createI18nMessage = createI18nMessageFactory(this.interpolationConfig); private _createI18nMessage = createI18nMessageFactory(this.interpolationConfig);
@ -64,6 +67,11 @@ export class I18nMetaVisitor implements html.Visitor {
return message; return message;
} }
visitAllWithErrors(nodes: html.Node[]): ParseTreeResult {
const result = nodes.map(node => node.visit(this, null));
return new ParseTreeResult(result, this._errors);
}
visitElement(element: html.Element): any { visitElement(element: html.Element): any {
if (hasI18nAttrs(element)) { if (hasI18nAttrs(element)) {
this.hasI18nMeta = true; this.hasI18nMeta = true;
@ -193,6 +201,10 @@ export class I18nMetaVisitor implements html.Visitor {
message.legacyIds = previousMessage ? previousMessage.legacyIds : []; message.legacyIds = previousMessage ? previousMessage.legacyIds : [];
} }
} }
private _reportError(node: html.Node, msg: string): void {
this._errors.push(new I18nError(node.sourceSpan, msg));
}
} }
/** I18n separators for metadata **/ /** I18n separators for metadata **/

View File

@ -2073,7 +2073,22 @@ export function parseTemplate(
const i18nMetaVisitor = new I18nMetaVisitor( const i18nMetaVisitor = new I18nMetaVisitor(
interpolationConfig, /* keepI18nAttrs */ !preserveWhitespaces, interpolationConfig, /* keepI18nAttrs */ !preserveWhitespaces,
enableI18nLegacyMessageIdFormat); enableI18nLegacyMessageIdFormat);
rootNodes = html.visitAll(i18nMetaVisitor, rootNodes); const i18nMetaResult = i18nMetaVisitor.visitAllWithErrors(rootNodes);
if (i18nMetaResult.errors && i18nMetaResult.errors.length > 0) {
return {
interpolationConfig,
preserveWhitespaces,
template,
errors: i18nMetaResult.errors,
nodes: [],
styleUrls: [],
styles: [],
ngContentSelectors: []
};
}
rootNodes = i18nMetaResult.rootNodes;
if (!preserveWhitespaces) { if (!preserveWhitespaces) {
rootNodes = html.visitAll(new WhitespaceVisitor(), rootNodes); rootNodes = html.visitAll(new WhitespaceVisitor(), rootNodes);