perf(ivy): chain multiple `i18nExp` calls (#31258)
Implement function chaining for `i18nExp` to reduce the output size. FW-1391 #resolve PR Close #31258
This commit is contained in:
parent
3846192bde
commit
ef9cb6a034
|
@ -464,14 +464,10 @@ describe('i18n support in the view compiler', () => {
|
|||
$r3$.ɵɵelementEnd();
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(1, 6, ctx.valueA));
|
||||
$r3$.ɵɵi18nExp(ctx.valueB);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(1, 6, ctx.valueA))(ctx.valueB);
|
||||
$r3$.ɵɵi18nApply(2);
|
||||
$r3$.ɵɵselect(3);
|
||||
$r3$.ɵɵi18nExp(ctx.valueA);
|
||||
$r3$.ɵɵi18nExp(ctx.valueB);
|
||||
$r3$.ɵɵi18nExp(ctx.valueA + ctx.valueB);
|
||||
$r3$.ɵɵi18nExp(ctx.valueC);
|
||||
$r3$.ɵɵi18nExp(ctx.valueA)(ctx.valueB)(ctx.valueA + ctx.valueB)(ctx.valueC);
|
||||
$r3$.ɵɵi18nApply(4);
|
||||
}
|
||||
}
|
||||
|
@ -690,14 +686,10 @@ describe('i18n support in the view compiler', () => {
|
|||
$r3$.ɵɵelementEnd();
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(1, 6, ctx.valueA));
|
||||
$r3$.ɵɵi18nExp(ctx.valueB);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(1, 6, ctx.valueA))(ctx.valueB);
|
||||
$r3$.ɵɵi18nApply(2);
|
||||
$r3$.ɵɵselect(3);
|
||||
$r3$.ɵɵi18nExp(ctx.valueA);
|
||||
$r3$.ɵɵi18nExp(ctx.valueB);
|
||||
$r3$.ɵɵi18nExp(ctx.valueA + ctx.valueB);
|
||||
$r3$.ɵɵi18nExp(ctx.valueC);
|
||||
$r3$.ɵɵi18nExp(ctx.valueA)(ctx.valueB)(ctx.valueA + ctx.valueB)(ctx.valueC);
|
||||
$r3$.ɵɵi18nApply(4);
|
||||
}
|
||||
}
|
||||
|
@ -1054,8 +1046,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(1);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(2, 2, ctx.valueA));
|
||||
$r3$.ɵɵi18nExp(ctx.valueA == null ? null : ctx.valueA.a == null ? null : ctx.valueA.a.b);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(2, 2, ctx.valueA))(ctx.valueA == null ? null : ctx.valueA.a == null ? null : ctx.valueA.a.b);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
@ -1224,8 +1215,7 @@ describe('i18n support in the view compiler', () => {
|
|||
$r3$.ɵɵi18nExp(ctx.one);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
$r3$.ɵɵselect(4);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(5, 3, ctx.two));
|
||||
$r3$.ɵɵi18nExp(ctx.nestedInBlockTwo);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(5, 3, ctx.two))(ctx.nestedInBlockTwo);
|
||||
$r3$.ɵɵi18nApply(4);
|
||||
}
|
||||
}
|
||||
|
@ -1335,8 +1325,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(2);
|
||||
$r3$.ɵɵi18nExp(ctx.valueB);
|
||||
$r3$.ɵɵi18nExp(ctx.valueC);
|
||||
$r3$.ɵɵi18nExp(ctx.valueB)(ctx.valueC);
|
||||
$r3$.ɵɵi18nApply(3);
|
||||
$r3$.ɵɵi18nExp(ctx.valueA);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
|
@ -1402,8 +1391,7 @@ describe('i18n support in the view compiler', () => {
|
|||
if (rf & 2) {
|
||||
const $ctx_r0$ = $r3$.ɵɵnextContext();
|
||||
$r3$.ɵɵselect(2);
|
||||
$r3$.ɵɵi18nExp($ctx_r0$.valueA);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(4, 2, $ctx_r0$.valueB));
|
||||
$r3$.ɵɵi18nExp($ctx_r0$.valueA)($r3$.ɵɵpipeBind1(4, 2, $ctx_r0$.valueB));
|
||||
$r3$.ɵɵi18nApply(2);
|
||||
}
|
||||
}
|
||||
|
@ -1527,8 +1515,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
const $ctx_r2$ = $r3$.ɵɵnextContext(2);
|
||||
$r3$.ɵɵi18nExp($ctx_r2$.valueC);
|
||||
$r3$.ɵɵi18nExp($ctx_r2$.valueD);
|
||||
$r3$.ɵɵi18nExp($ctx_r2$.valueC)($ctx_r2$.valueD);
|
||||
$r3$.ɵɵi18nApply(0);
|
||||
}
|
||||
}
|
||||
|
@ -1547,8 +1534,7 @@ describe('i18n support in the view compiler', () => {
|
|||
const $ctx_r0$ = $r3$.ɵɵnextContext();
|
||||
$r3$.ɵɵselect(4);
|
||||
$r3$.ɵɵproperty("ngIf", $ctx_r0$.exists);
|
||||
$r3$.ɵɵi18nExp($ctx_r0$.valueA);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(3, 3, $ctx_r0$.valueB));
|
||||
$r3$.ɵɵi18nExp($ctx_r0$.valueA)($r3$.ɵɵpipeBind1(3, 3, $ctx_r0$.valueB));
|
||||
$r3$.ɵɵi18nApply(0);
|
||||
}
|
||||
}
|
||||
|
@ -1596,8 +1582,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
const $ctx_r1$ = $r3$.ɵɵnextContext();
|
||||
$r3$.ɵɵi18nExp($ctx_r1$.valueE + $ctx_r1$.valueF);
|
||||
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(3, 2, $ctx_r1$.valueG));
|
||||
$r3$.ɵɵi18nExp($ctx_r1$.valueE + $ctx_r1$.valueF)($r3$.ɵɵpipeBind1(3, 2, $ctx_r1$.valueG));
|
||||
$r3$.ɵɵi18nApply(0);
|
||||
}
|
||||
}
|
||||
|
@ -2554,8 +2539,7 @@ describe('i18n support in the view compiler', () => {
|
|||
if (rf & 2) {
|
||||
const $ctx_r1$ = $r3$.ɵɵnextContext();
|
||||
$r3$.ɵɵselect(2);
|
||||
$r3$.ɵɵi18nExp($ctx_r1$.count);
|
||||
$r3$.ɵɵi18nExp($ctx_r1$.count);
|
||||
$r3$.ɵɵi18nExp($ctx_r1$.count)($ctx_r1$.count);
|
||||
$r3$.ɵɵi18nApply(2);
|
||||
}
|
||||
}
|
||||
|
@ -2615,8 +2599,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(1);
|
||||
$r3$.ɵɵi18nExp(ctx.age);
|
||||
$r3$.ɵɵi18nExp(ctx.other);
|
||||
$r3$.ɵɵi18nExp(ctx.age)(ctx.other);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
@ -2742,8 +2725,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(1);
|
||||
$r3$.ɵɵi18nExp(ctx.gender);
|
||||
$r3$.ɵɵi18nExp(ctx.ageA + ctx.ageB + ctx.ageC);
|
||||
$r3$.ɵɵi18nExp(ctx.gender)(ctx.ageA + ctx.ageB + ctx.ageC);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
@ -2808,8 +2790,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(1);
|
||||
$r3$.ɵɵi18nExp(ctx.gender);
|
||||
$r3$.ɵɵi18nExp(ctx.age);
|
||||
$r3$.ɵɵi18nExp(ctx.gender)(ctx.age);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
@ -2914,8 +2895,7 @@ describe('i18n support in the view compiler', () => {
|
|||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(3);
|
||||
$r3$.ɵɵproperty("ngIf", ctx.visible);
|
||||
$r3$.ɵɵi18nExp(ctx.gender);
|
||||
$r3$.ɵɵi18nExp(ctx.gender);
|
||||
$r3$.ɵɵi18nExp(ctx.gender)(ctx.gender);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
@ -2962,8 +2942,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(1);
|
||||
$r3$.ɵɵi18nExp(ctx.age);
|
||||
$r3$.ɵɵi18nExp(ctx.gender);
|
||||
$r3$.ɵɵi18nExp(ctx.age)(ctx.gender);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
@ -3132,8 +3111,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
const $ctx_r0$ = $r3$.ɵɵnextContext();
|
||||
$r3$.ɵɵi18nExp($ctx_r0$.age);
|
||||
$r3$.ɵɵi18nExp($ctx_r0$.otherAge);
|
||||
$r3$.ɵɵi18nExp($ctx_r0$.age)($ctx_r0$.otherAge);
|
||||
$r3$.ɵɵi18nApply(0);
|
||||
}
|
||||
}
|
||||
|
@ -3151,9 +3129,7 @@ describe('i18n support in the view compiler', () => {
|
|||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(2);
|
||||
$r3$.ɵɵproperty("ngIf", ctx.ageVisible);
|
||||
$r3$.ɵɵi18nExp(ctx.gender);
|
||||
$r3$.ɵɵi18nExp(ctx.weight);
|
||||
$r3$.ɵɵi18nExp(ctx.height);
|
||||
$r3$.ɵɵi18nExp(ctx.gender)(ctx.weight)(ctx.height);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
@ -3204,10 +3180,7 @@ describe('i18n support in the view compiler', () => {
|
|||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵɵselect(1);
|
||||
$r3$.ɵɵi18nExp(ctx.gender);
|
||||
$r3$.ɵɵi18nExp(ctx.weight);
|
||||
$r3$.ɵɵi18nExp(ctx.height);
|
||||
$r3$.ɵɵi18nExp(ctx.age);
|
||||
$r3$.ɵɵi18nExp(ctx.gender)(ctx.weight)(ctx.height)(ctx.age);
|
||||
$r3$.ɵɵi18nApply(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -456,10 +456,14 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
// setup accumulated bindings
|
||||
const {index, bindings} = this.i18n;
|
||||
if (bindings.size) {
|
||||
const chainBindings: ChainableBindingInstruction[] = [];
|
||||
bindings.forEach(binding => {
|
||||
this.updateInstruction(
|
||||
index, span, R3.i18nExp, () => [this.convertPropertyBinding(binding)]);
|
||||
chainBindings.push({
|
||||
sourceSpan: span,
|
||||
value: () => this.convertPropertyBinding(binding)
|
||||
});
|
||||
});
|
||||
this.updateInstructionChain(index, R3.i18nExp, chainBindings);
|
||||
this.updateInstruction(index, span, R3.i18nApply, [o.literal(index)]);
|
||||
}
|
||||
if (!selfClosing) {
|
||||
|
@ -641,6 +645,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
if (i18nAttrs.length) {
|
||||
let hasBindings: boolean = false;
|
||||
const i18nAttrArgs: o.Expression[] = [];
|
||||
const bindings: ChainableBindingInstruction[] = [];
|
||||
i18nAttrs.forEach(attr => {
|
||||
const message = attr.i18n !as i18n.Message;
|
||||
if (attr instanceof t.TextAttribute) {
|
||||
|
@ -654,13 +659,17 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
i18nAttrArgs.push(o.literal(attr.name), this.i18nTranslate(message, params));
|
||||
converted.expressions.forEach(expression => {
|
||||
hasBindings = true;
|
||||
this.updateInstruction(
|
||||
elementIndex, element.sourceSpan, R3.i18nExp,
|
||||
() => [this.convertExpressionBinding(expression)]);
|
||||
bindings.push({
|
||||
sourceSpan: element.sourceSpan,
|
||||
value: () => this.convertExpressionBinding(expression)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (bindings.length) {
|
||||
this.updateInstructionChain(elementIndex, R3.i18nExp, bindings);
|
||||
}
|
||||
if (i18nAttrArgs.length) {
|
||||
const index: o.Expression = o.literal(this.allocateDataSlot());
|
||||
const args = this.constantPool.getConstLiteral(o.literalArr(i18nAttrArgs), true);
|
||||
|
@ -733,7 +742,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
|
||||
propertyBindings.push({
|
||||
name: prepareSyntheticPropertyName(input.name),
|
||||
input,
|
||||
sourceSpan: input.sourceSpan,
|
||||
value: () => hasValue ? this.convertPropertyBinding(value) : emptyValueBindInstruction
|
||||
});
|
||||
} else {
|
||||
|
@ -771,7 +780,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
// [prop]="value"
|
||||
// Collect all the properties so that we can chain into a single function at the end.
|
||||
propertyBindings.push(
|
||||
{name: attrName, input, value: () => this.convertPropertyBinding(value), params});
|
||||
{name: attrName, sourceSpan: input.sourceSpan, value: () => this.convertPropertyBinding(value), params});
|
||||
}
|
||||
} else if (inputType === BindingType.Attribute) {
|
||||
if (value instanceof Interpolation && getInterpolationArgsLength(value) > 1) {
|
||||
|
@ -785,7 +794,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
// Collect the attribute bindings so that they can be chained at the end.
|
||||
attributeBindings.push({
|
||||
name: attrName,
|
||||
input,
|
||||
sourceSpan: input.sourceSpan,
|
||||
value: () => this.convertPropertyBinding(boundValue), params
|
||||
});
|
||||
}
|
||||
|
@ -830,18 +839,6 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an update instruction for a bound property or attribute, such as `[prop]="value"` or
|
||||
* `[attr.title]="value"`
|
||||
*/
|
||||
boundUpdateInstruction(
|
||||
instruction: o.ExternalReference, elementIndex: number, attrName: string,
|
||||
input: t.BoundAttribute, value: any, params: any[]) {
|
||||
this.updateInstruction(elementIndex, input.sourceSpan, instruction, () => {
|
||||
return [o.literal(attrName), this.convertPropertyBinding(value), ...params];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an update instruction for an interpolated property or attribute, such as
|
||||
* `prop="{{value}}"` or `attr.title="{{value}}"`
|
||||
|
@ -1042,7 +1039,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
if (value !== undefined) {
|
||||
this.allocateBindingSlots(value);
|
||||
propertyBindings.push(
|
||||
{name: input.name, input, value: () => this.convertPropertyBinding(value)});
|
||||
{name: input.name, sourceSpan: input.sourceSpan, value: () => this.convertPropertyBinding(value)});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1093,12 +1090,17 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
|
||||
private updateInstructionChain(
|
||||
nodeIndex: number, reference: o.ExternalReference, bindings: ChainableBindingInstruction[]) {
|
||||
const span = bindings.length ? bindings[0].input.sourceSpan : null;
|
||||
const span = bindings.length ? bindings[0].sourceSpan : null;
|
||||
|
||||
this.addSelectInstructionIfNecessary(nodeIndex, span);
|
||||
this._updateCodeFns.push(() => {
|
||||
const calls = bindings.map(
|
||||
property => [o.literal(property.name), property.value(), ...(property.params || [])]);
|
||||
const calls = bindings.map(property => {
|
||||
const fnParams = [property.value(), ...(property.params || [])];
|
||||
if (property.name) {
|
||||
fnParams.unshift(o.literal(property.name));
|
||||
}
|
||||
return fnParams;
|
||||
});
|
||||
|
||||
return chainedInstruction(span, reference, calls).toStmt();
|
||||
});
|
||||
|
@ -2027,8 +2029,8 @@ function hasTextChildrenOnly(children: t.Node[]): boolean {
|
|||
}
|
||||
|
||||
interface ChainableBindingInstruction {
|
||||
name: string;
|
||||
input: t.BoundAttribute;
|
||||
name?: string;
|
||||
sourceSpan: ParseSourceSpan|null;
|
||||
value: () => o.Expression;
|
||||
params?: any[];
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import {assertDataInRange, assertDefined, assertEqual, assertGreaterThan} from '
|
|||
import {attachPatchData} from './context_discovery';
|
||||
import {bind, setDelayProjection, ɵɵload} from './instructions/all';
|
||||
import {attachI18nOpCodesDebug} from './instructions/lview_debug';
|
||||
import {allocExpando, elementAttributeInternal, elementPropertyInternal, getOrCreateTNode, setInputsForProperty, textBindingInternal} from './instructions/shared';
|
||||
import {allocExpando, elementAttributeInternal, elementPropertyInternal, getOrCreateTNode, setInputsForProperty, textBindingInternal, TsickleIssue1009} from './instructions/shared';
|
||||
import {LContainer, NATIVE} from './interfaces/container';
|
||||
import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nMutateOpCodes, I18nUpdateOpCode, I18nUpdateOpCodes, IcuType, TI18n, TIcu} from './interfaces/i18n';
|
||||
import {TElementNode, TIcuContainerNode, TNode, TNodeFlags, TNodeType, TProjectionNode} from './interfaces/node';
|
||||
|
@ -1012,16 +1012,19 @@ let shiftsCounter = 0;
|
|||
* update the translated nodes.
|
||||
*
|
||||
* @param value The binding's value
|
||||
* @returns This function returns itself so that it may be chained
|
||||
* (e.g. `i18nExp(ctx.name)(ctx.title)`)
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵi18nExp<T>(value: T): void {
|
||||
export function ɵɵi18nExp<T>(value: T): TsickleIssue1009 {
|
||||
const lView = getLView();
|
||||
const expression = bind(lView, value);
|
||||
if (expression !== NO_CHANGE) {
|
||||
changeMask = changeMask | (1 << shiftsCounter);
|
||||
}
|
||||
shiftsCounter++;
|
||||
return ɵɵi18nExp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -851,7 +851,7 @@ export declare function ɵɵi18nAttributes(index: number, values: string[]): voi
|
|||
|
||||
export declare function ɵɵi18nEnd(): void;
|
||||
|
||||
export declare function ɵɵi18nExp<T>(value: T): void;
|
||||
export declare function ɵɵi18nExp<T>(value: T): TsickleIssue1009;
|
||||
|
||||
/** @deprecated */
|
||||
export declare function ɵɵi18nLocalize(input: string, placeholders?: {
|
||||
|
|
Loading…
Reference in New Issue