fix(ivy): more descriptive errors for nested i18n sections (#33583)

This commit moves nested i18n section detection to an earlier stage where we convert HTML AST to Ivy AST. This also gives a chance to produce better diagnistic message for nested i18n sections, that also includes a file name and location.

PR Close #33583
This commit is contained in:
Andrew Kushnir
2019-08-03 12:24:48 -07:00
committed by atscott
parent 25aaff2ee1
commit d9a38928f5
3 changed files with 61 additions and 9 deletions

View File

@ -80,11 +80,21 @@ class HtmlAstToIvyAst implements html.Visitor {
errors: ParseError[] = [];
styles: string[] = [];
styleUrls: string[] = [];
private inI18nBlock: boolean = false;
constructor(private bindingParser: BindingParser) {}
// HTML visitor
visitElement(element: html.Element): t.Node|null {
const isI18nRootElement = isI18nRootNode(element.i18n);
if (isI18nRootElement) {
if (this.inI18nBlock) {
this.reportError(
'Cannot mark an element as translatable inside of a translatable section. Please remove the nested i18n marker.',
element.sourceSpan);
}
this.inI18nBlock = true;
}
const preparsedElement = preparseElement(element);
if (preparsedElement.type === PreparsedElementType.SCRIPT) {
return null;
@ -209,7 +219,7 @@ class HtmlAstToIvyAst implements html.Visitor {
// For <ng-template>s with structural directives on them, avoid passing i18n information to
// the wrapping template to prevent unnecessary i18n instructions from being generated. The
// necessary i18n meta information will be extracted from child elements.
const i18n = isTemplateElement && isI18nRootNode(element.i18n) ? undefined : element.i18n;
const i18n = isTemplateElement && isI18nRootElement ? undefined : element.i18n;
// TODO(pk): test for this case
parsedElement = new t.Template(
@ -218,6 +228,9 @@ class HtmlAstToIvyAst implements html.Visitor {
templateVariables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan,
i18n);
}
if (isI18nRootElement) {
this.inI18nBlock = false;
}
return parsedElement;
}

View File

@ -535,10 +535,6 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
const isI18nRootElement: boolean =
isI18nRootNode(element.i18n) && !isSingleI18nIcu(element.i18n);
if (isI18nRootElement && this.i18n) {
throw new Error(`Could not mark an element as translatable inside of a translatable section`);
}
const i18nAttrs: (t.TextAttribute | t.BoundAttribute)[] = [];
const outputAttrs: t.TextAttribute[] = [];
let ngProjectAsAttr: t.TextAttribute|undefined;