refactor(compiler): rename i18n `AST` to `i18nMeta` (#33318)

This better reflects what this type represents and what it is used for.

PR Close #33318
This commit is contained in:
Pete Bacon Darwin 2019-10-22 15:05:44 +01:00 committed by Matias Niemelä
parent 447e251736
commit 03103d2d59
8 changed files with 41 additions and 32 deletions

View File

@ -98,7 +98,13 @@ export class IcuPlaceholder implements Node {
visit(visitor: Visitor, context?: any): any { return visitor.visitIcuPlaceholder(this, context); }
}
export type AST = Message | Node;
/**
* Each HTML node that is affect by an i18n tag will also have an `i18n` property that is of type
* `I18nMeta`.
* This information is either a `Message`, which indicates it is the root of an i18n message, or a
* `Node`, which indicates is it part of a containing `Message`.
*/
export type I18nMeta = Message | Node;
export interface Visitor {
visitText(text: Text, context?: any): any;

View File

@ -7,7 +7,7 @@
*/
import {AstPath} from '../ast_path';
import {AST as I18nAST} from '../i18n/i18n_ast';
import {I18nMeta} from '../i18n/i18n_ast';
import {ParseSourceSpan} from '../parse_util';
export interface Node {
@ -16,7 +16,7 @@ export interface Node {
}
export class Text implements Node {
constructor(public value: string, public sourceSpan: ParseSourceSpan, public i18n?: I18nAST) {}
constructor(public value: string, public sourceSpan: ParseSourceSpan, public i18n?: I18nMeta) {}
visit(visitor: Visitor, context: any): any { return visitor.visitText(this, context); }
}
@ -24,7 +24,7 @@ export class Expansion implements Node {
constructor(
public switchValue: string, public type: string, public cases: ExpansionCase[],
public sourceSpan: ParseSourceSpan, public switchValueSourceSpan: ParseSourceSpan,
public i18n?: I18nAST) {}
public i18n?: I18nMeta) {}
visit(visitor: Visitor, context: any): any { return visitor.visitExpansion(this, context); }
}
@ -39,7 +39,7 @@ export class ExpansionCase implements Node {
export class Attribute implements Node {
constructor(
public name: string, public value: string, public sourceSpan: ParseSourceSpan,
public valueSpan?: ParseSourceSpan, public i18n?: I18nAST) {}
public valueSpan?: ParseSourceSpan, public i18n?: I18nMeta) {}
visit(visitor: Visitor, context: any): any { return visitor.visitAttribute(this, context); }
}
@ -47,7 +47,7 @@ export class Element implements Node {
constructor(
public name: string, public attrs: Attribute[], public children: Node[],
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null = null,
public endSourceSpan: ParseSourceSpan|null = null, public i18n?: I18nAST) {}
public endSourceSpan: ParseSourceSpan|null = null, public i18n?: I18nMeta) {}
visit(visitor: Visitor, context: any): any { return visitor.visitElement(this, context); }
}

View File

@ -8,7 +8,7 @@
import {SecurityContext} from '../core';
import {AST, BindingType, BoundElementProperty, ParsedEvent, ParsedEventType} from '../expression_parser/ast';
import {AST as I18nAST} from '../i18n/i18n_ast';
import {I18nMeta} from '../i18n/i18n_ast';
import {ParseSourceSpan} from '../parse_util';
export interface Node {
@ -22,14 +22,14 @@ export class Text implements Node {
}
export class BoundText implements Node {
constructor(public value: AST, public sourceSpan: ParseSourceSpan, public i18n?: I18nAST) {}
constructor(public value: AST, public sourceSpan: ParseSourceSpan, public i18n?: I18nMeta) {}
visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitBoundText(this); }
}
export class TextAttribute implements Node {
constructor(
public name: string, public value: string, public sourceSpan: ParseSourceSpan,
public valueSpan?: ParseSourceSpan, public i18n?: I18nAST) {}
public valueSpan?: ParseSourceSpan, public i18n?: I18nMeta) {}
visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitTextAttribute(this); }
}
@ -37,9 +37,9 @@ export class BoundAttribute implements Node {
constructor(
public name: string, public type: BindingType, public securityContext: SecurityContext,
public value: AST, public unit: string|null, public sourceSpan: ParseSourceSpan,
public valueSpan?: ParseSourceSpan, public i18n?: I18nAST) {}
public valueSpan?: ParseSourceSpan, public i18n?: I18nMeta) {}
static fromBoundElementProperty(prop: BoundElementProperty, i18n?: I18nAST) {
static fromBoundElementProperty(prop: BoundElementProperty, i18n?: I18nMeta) {
return new BoundAttribute(
prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan,
prop.valueSpan, i18n);
@ -70,7 +70,7 @@ export class Element implements Node {
public name: string, public attributes: TextAttribute[], public inputs: BoundAttribute[],
public outputs: BoundEvent[], public children: Node[], public references: Reference[],
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null,
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nAST) {
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nMeta) {
// If the element is empty then the source span should include any closing tag
if (children.length === 0 && startSourceSpan && endSourceSpan) {
this.sourceSpan = new ParseSourceSpan(sourceSpan.start, endSourceSpan.end);
@ -85,14 +85,14 @@ export class Template implements Node {
public outputs: BoundEvent[], public templateAttrs: (BoundAttribute|TextAttribute)[],
public children: Node[], public references: Reference[], public variables: Variable[],
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null,
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nAST) {}
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nMeta) {}
visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitTemplate(this); }
}
export class Content implements Node {
constructor(
public selector: string, public attributes: TextAttribute[],
public sourceSpan: ParseSourceSpan, public i18n?: I18nAST) {}
public sourceSpan: ParseSourceSpan, public i18n?: I18nMeta) {}
visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitContent(this); }
}
@ -114,7 +114,7 @@ export class Icu implements Node {
constructor(
public vars: {[name: string]: BoundText},
public placeholders: {[name: string]: Text | BoundText}, public sourceSpan: ParseSourceSpan,
public i18n?: I18nAST) {}
public i18n?: I18nMeta) {}
visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitIcu(this); }
}

View File

@ -109,7 +109,7 @@ class HtmlAstToIvyAst implements html.Visitor {
const variables: t.Variable[] = [];
const references: t.Reference[] = [];
const attributes: t.TextAttribute[] = [];
const i18nAttrsMeta: {[key: string]: i18n.AST} = {};
const i18nAttrsMeta: {[key: string]: i18n.I18nMeta} = {};
const templateParsedProperties: ParsedProperty[] = [];
const templateVariables: t.Variable[] = [];
@ -263,7 +263,8 @@ class HtmlAstToIvyAst implements html.Visitor {
// convert view engine `ParsedProperty` to a format suitable for IVY
private extractAttributes(
elementName: string, properties: ParsedProperty[], i18nPropsMeta: {[key: string]: i18n.AST}):
elementName: string, properties: ParsedProperty[],
i18nPropsMeta: {[key: string]: i18n.I18nMeta}):
{bound: t.BoundAttribute[], literal: t.TextAttribute[]} {
const bound: t.BoundAttribute[] = [];
const literal: t.TextAttribute[] = [];
@ -364,8 +365,8 @@ class HtmlAstToIvyAst implements html.Visitor {
return hasBinding;
}
private _visitTextWithInterpolation(value: string, sourceSpan: ParseSourceSpan, i18n?: i18n.AST):
t.Text|t.BoundText {
private _visitTextWithInterpolation(
value: string, sourceSpan: ParseSourceSpan, i18n?: i18n.I18nMeta): t.Text|t.BoundText {
const valueNoNgsp = replaceNgsp(value);
const expr = this.bindingParser.parseInterpolation(valueNoNgsp, sourceSpan);
return expr ? new t.BoundText(expr, sourceSpan, i18n) : new t.Text(valueNoNgsp, sourceSpan);

View File

@ -51,7 +51,8 @@ export class I18nContext {
constructor(
readonly index: number, readonly ref: o.ReadVarExpr, readonly level: number = 0,
readonly templateIndex: number|null = null, readonly meta: i18n.AST, private registry?: any) {
readonly templateIndex: number|null = null, readonly meta: i18n.I18nMeta,
private registry?: any) {
this._registry = registry || setupRegistry();
this.id = this._registry.getUniqueId();
}
@ -81,21 +82,21 @@ export class I18nContext {
appendIcu(name: string, ref: o.Expression) {
updatePlaceholderMap(this._registry.icus, name, ref);
}
appendBoundText(node: i18n.AST) {
appendBoundText(node: i18n.I18nMeta) {
const phs = assembleBoundTextPlaceholders(node, this.bindings.size, this.id);
phs.forEach((values, key) => updatePlaceholderMap(this.placeholders, key, ...values));
}
appendTemplate(node: i18n.AST, index: number) {
appendTemplate(node: i18n.I18nMeta, index: number) {
// add open and close tags at the same time,
// since we process nested templates separately
this.appendTag(TagType.TEMPLATE, node as i18n.TagPlaceholder, index, false);
this.appendTag(TagType.TEMPLATE, node as i18n.TagPlaceholder, index, true);
this._unresolvedCtxCount++;
}
appendElement(node: i18n.AST, index: number, closed?: boolean) {
appendElement(node: i18n.I18nMeta, index: number, closed?: boolean) {
this.appendTag(TagType.ELEMENT, node as i18n.TagPlaceholder, index, closed);
}
appendProjection(node: i18n.AST, index: number) {
appendProjection(node: i18n.I18nMeta, index: number) {
// add open and close tags at the same time,
// since we process projected content separately
this.appendTag(TagType.PROJECTION, node as i18n.TagPlaceholder, index, false);
@ -112,7 +113,7 @@ export class I18nContext {
*
* @returns I18nContext instance
*/
forkChildContext(index: number, templateIndex: number, meta: i18n.AST) {
forkChildContext(index: number, templateIndex: number, meta: i18n.I18nMeta) {
return new I18nContext(index, this.ref, this.level + 1, templateIndex, meta, this._registry);
}

View File

@ -23,7 +23,7 @@ export type I18nMeta = {
meaning?: string
};
function setI18nRefs(html: html.Node & {i18n?: i18n.AST}, i18n: i18n.Node): i18n.Node {
function setI18nRefs(html: html.Node & {i18n?: i18n.I18nMeta}, i18n: i18n.Node): i18n.Node {
html.i18n = i18n;
return i18n;
}
@ -42,7 +42,8 @@ export class I18nMetaVisitor implements html.Visitor {
private keepI18nAttrs: boolean = false, private i18nLegacyMessageIdFormat: string = '') {}
private _generateI18nMessage(
nodes: html.Node[], meta: string|i18n.AST = '', visitNodeFn?: VisitNodeFn): i18n.Message {
nodes: html.Node[], meta: string|i18n.I18nMeta = '',
visitNodeFn?: VisitNodeFn): i18n.Message {
const parsed: I18nMeta =
typeof meta === 'string' ? parseI18nMeta(meta) : metaFromI18nMessage(meta as i18n.Message);
const message = this._createI18nMessage(

View File

@ -33,11 +33,11 @@ export function isI18nAttribute(name: string): boolean {
return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
}
export function isI18nRootNode(meta?: i18n.AST): meta is i18n.Message {
export function isI18nRootNode(meta?: i18n.I18nMeta): meta is i18n.Message {
return meta instanceof i18n.Message;
}
export function isSingleI18nIcu(meta?: i18n.AST): boolean {
export function isSingleI18nIcu(meta?: i18n.I18nMeta): boolean {
return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof i18n.Icu;
}
@ -87,7 +87,7 @@ export function updatePlaceholderMap(map: Map<string, any[]>, name: string, ...v
}
export function assembleBoundTextPlaceholders(
meta: i18n.AST, bindingStartIndex: number = 0, contextId: number = 0): Map<string, any[]> {
meta: i18n.I18nMeta, bindingStartIndex: number = 0, contextId: number = 0): Map<string, any[]> {
const startIdx = bindingStartIndex;
const placeholders = new Map<string, any>();
const node =

View File

@ -188,7 +188,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
buildTemplateFunction(
nodes: t.Node[], variables: t.Variable[], ngContentSelectorsOffset: number = 0,
i18n?: i18n.AST): o.FunctionExpr {
i18n?: i18n.I18nMeta): o.FunctionExpr {
this._ngContentSelectorsOffset = ngContentSelectorsOffset;
if (this._namespace !== R3.namespaceHTML) {
@ -415,7 +415,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
}
}
private i18nStart(span: ParseSourceSpan|null = null, meta: i18n.AST, selfClosing?: boolean):
private i18nStart(span: ParseSourceSpan|null = null, meta: i18n.I18nMeta, selfClosing?: boolean):
void {
const index = this.allocateDataSlot();
if (this.i18nContext) {