perf: delete pre-view-engine core, compiler, platform-browser, etc code (#14788)
After the introduction of the view engine, we can drop a lot of code that is not used any more. This should reduce the size of the app bundles because a lot of this code was not being properly tree-shaken by today's tools even though it was dead code.
This commit is contained in:
@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ClassBuilder} from '../output/class_builder';
|
||||
import * as o from '../output/output_ast';
|
||||
|
||||
export class CheckBindingField {
|
||||
constructor(public expression: o.ReadPropExpr, public bindingId: string) {}
|
||||
}
|
||||
|
||||
export function createCheckBindingField(builder: ClassBuilder): CheckBindingField {
|
||||
const bindingId = `${builder.fields.length}`;
|
||||
const fieldExpr = createBindFieldExpr(bindingId);
|
||||
// private is fine here as no child view will reference the cached value...
|
||||
builder.fields.push(new o.ClassField(fieldExpr.name, null, [o.StmtModifier.Private]));
|
||||
builder.ctorStmts.push(o.THIS_EXPR.prop(fieldExpr.name).set(o.literal(undefined)).toStmt());
|
||||
return new CheckBindingField(fieldExpr, bindingId);
|
||||
}
|
||||
|
||||
function createBindFieldExpr(bindingId: string): o.ReadPropExpr {
|
||||
return o.THIS_EXPR.prop(`_expr_${bindingId}`);
|
||||
}
|
||||
|
||||
export function isFirstViewCheck(view: o.Expression): o.Expression {
|
||||
return o.not(view.prop('numberOfChecks'));
|
||||
}
|
@ -10,13 +10,8 @@
|
||||
import * as cdAst from '../expression_parser/ast';
|
||||
import {isBlank} from '../facade/lang';
|
||||
import {Identifiers, createIdentifier} from '../identifiers';
|
||||
import {ClassBuilder} from '../output/class_builder';
|
||||
import * as o from '../output/output_ast';
|
||||
|
||||
import {createPureProxy} from './identifier_util';
|
||||
|
||||
const VAL_UNWRAPPER_VAR = o.variable(`valUnwrapper`);
|
||||
|
||||
export class EventHandlerVars { static event = o.variable('$event'); }
|
||||
|
||||
export interface LocalResolver { getLocal(name: string): o.Expression; }
|
||||
@ -116,73 +111,6 @@ export function convertPropertyBinding(
|
||||
return new ConvertPropertyBindingResult(stmts, currValExpr);
|
||||
}
|
||||
|
||||
|
||||
export class LegacyConvertPropertyBindingResult implements ConvertPropertyBindingResult {
|
||||
constructor(
|
||||
public stmts: o.Statement[], public currValExpr: o.Expression,
|
||||
public forceUpdate: o.Expression) {}
|
||||
}
|
||||
|
||||
export interface LegacyNameResolver {
|
||||
callPipe(name: string, input: o.Expression, args: o.Expression[]): o.Expression;
|
||||
getLocal(name: string): o.Expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given expression AST into an executable output AST, assuming the expression is
|
||||
* used in a property binding.
|
||||
*/
|
||||
export function legacyConvertPropertyBinding(
|
||||
builder: ClassBuilder, nameResolver: LegacyNameResolver, implicitReceiver: o.Expression,
|
||||
expression: cdAst.AST, bindingId: string): LegacyConvertPropertyBindingResult {
|
||||
if (!nameResolver) {
|
||||
nameResolver = new LegacyDefaultNameResolver();
|
||||
}
|
||||
let needsValueUnwrapper = false;
|
||||
const expressionWithoutBuiltins = convertBuiltins(
|
||||
{
|
||||
createLiteralArrayConverter: (argCount: number) => {
|
||||
return (args: o.Expression[]) => legacyCreateCachedLiteralArray(builder, args);
|
||||
},
|
||||
createLiteralMapConverter: (keys: string[]) => {
|
||||
return (args: o.Expression[]) => legacyCreateCachedLiteralMap(
|
||||
builder, <[string, o.Expression][]>keys.map((key, i) => [key, args[i]]));
|
||||
},
|
||||
createPipeConverter: (name: string) => {
|
||||
needsValueUnwrapper = true;
|
||||
return (args: o.Expression[]) => VAL_UNWRAPPER_VAR.callMethod(
|
||||
'unwrap', [nameResolver.callPipe(name, args[0], args.slice(1))]);
|
||||
}
|
||||
},
|
||||
expression);
|
||||
|
||||
const {stmts, currValExpr} =
|
||||
convertPropertyBinding(nameResolver, implicitReceiver, expressionWithoutBuiltins, bindingId);
|
||||
let forceUpdate: o.Expression = null;
|
||||
if (needsValueUnwrapper) {
|
||||
const initValueUnwrapperStmt = VAL_UNWRAPPER_VAR.callMethod('reset', []).toStmt();
|
||||
stmts.unshift(initValueUnwrapperStmt);
|
||||
forceUpdate = VAL_UNWRAPPER_VAR.prop('hasWrappedValue');
|
||||
}
|
||||
return new LegacyConvertPropertyBindingResult(stmts, currValExpr, forceUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates variables that are shared by multiple calls to `convertActionBinding` /
|
||||
* `convertPropertyBinding`
|
||||
*/
|
||||
export function legacyCreateSharedBindingVariablesIfNeeded(stmts: o.Statement[]): o.Statement[] {
|
||||
const unwrapperStmts: o.Statement[] = [];
|
||||
const readVars = o.findReadVarNames(stmts);
|
||||
if (readVars.has(VAL_UNWRAPPER_VAR.name)) {
|
||||
unwrapperStmts.push(
|
||||
VAL_UNWRAPPER_VAR
|
||||
.set(o.importExpr(createIdentifier(Identifiers.ValueUnwrapper)).instantiate([]))
|
||||
.toDeclStmt(null, [o.StmtModifier.Final]));
|
||||
}
|
||||
return unwrapperStmts;
|
||||
}
|
||||
|
||||
function convertBuiltins(converterFactory: BuiltinConverterFactory, ast: cdAst.AST): cdAst.AST {
|
||||
const visitor = new _BuiltinAstConverter(converterFactory);
|
||||
return ast.visit(visitor);
|
||||
@ -649,50 +577,6 @@ function flattenStatements(arg: any, output: o.Statement[]) {
|
||||
}
|
||||
}
|
||||
|
||||
function legacyCreateCachedLiteralArray(
|
||||
builder: ClassBuilder, values: o.Expression[]): o.Expression {
|
||||
if (values.length === 0) {
|
||||
return o.importExpr(createIdentifier(Identifiers.EMPTY_ARRAY));
|
||||
}
|
||||
const proxyExpr = o.THIS_EXPR.prop(`_arr_${builder.fields.length}`);
|
||||
const proxyParams: o.FnParam[] = [];
|
||||
const proxyReturnEntries: o.Expression[] = [];
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const paramName = `p${i}`;
|
||||
proxyParams.push(new o.FnParam(paramName));
|
||||
proxyReturnEntries.push(o.variable(paramName));
|
||||
}
|
||||
createPureProxy(
|
||||
o.fn(
|
||||
proxyParams, [new o.ReturnStatement(o.literalArr(proxyReturnEntries))],
|
||||
new o.ArrayType(o.DYNAMIC_TYPE)),
|
||||
values.length, proxyExpr, builder);
|
||||
return proxyExpr.callFn(values);
|
||||
}
|
||||
|
||||
function legacyCreateCachedLiteralMap(
|
||||
builder: ClassBuilder, entries: [string, o.Expression][]): o.Expression {
|
||||
if (entries.length === 0) {
|
||||
return o.importExpr(createIdentifier(Identifiers.EMPTY_MAP));
|
||||
}
|
||||
const proxyExpr = o.THIS_EXPR.prop(`_map_${builder.fields.length}`);
|
||||
const proxyParams: o.FnParam[] = [];
|
||||
const proxyReturnEntries: [string, o.Expression][] = [];
|
||||
const values: o.Expression[] = [];
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
const paramName = `p${i}`;
|
||||
proxyParams.push(new o.FnParam(paramName));
|
||||
proxyReturnEntries.push([entries[i][0], o.variable(paramName)]);
|
||||
values.push(<o.Expression>entries[i][1]);
|
||||
}
|
||||
createPureProxy(
|
||||
o.fn(
|
||||
proxyParams, [new o.ReturnStatement(o.literalMap(proxyReturnEntries))],
|
||||
new o.MapType(o.DYNAMIC_TYPE)),
|
||||
entries.length, proxyExpr, builder);
|
||||
return proxyExpr.callFn(values);
|
||||
}
|
||||
|
||||
class DefaultLocalResolver implements LocalResolver {
|
||||
getLocal(name: string): o.Expression {
|
||||
if (name === EventHandlerVars.event.name) {
|
||||
@ -702,16 +586,6 @@ class DefaultLocalResolver implements LocalResolver {
|
||||
}
|
||||
}
|
||||
|
||||
class LegacyDefaultNameResolver implements LegacyNameResolver {
|
||||
callPipe(name: string, input: o.Expression, args: o.Expression[]): o.Expression { return null; }
|
||||
getLocal(name: string): o.Expression {
|
||||
if (name === EventHandlerVars.event.name) {
|
||||
return EventHandlerVars.event;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function createCurrValueExpr(bindingId: string): o.ReadVarExpr {
|
||||
return o.variable(`currVal_${bindingId}`); // fix syntax highlighting: `
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CompileTokenMetadata} from '../compile_metadata';
|
||||
import {isPresent} from '../facade/lang';
|
||||
import {IdentifierSpec, Identifiers, createEnumIdentifier, createIdentifier} from '../identifiers';
|
||||
import * as o from '../output/output_ast';
|
||||
|
||||
export function createDiTokenExpression(token: CompileTokenMetadata): o.Expression {
|
||||
if (isPresent(token.value)) {
|
||||
return o.literal(token.value);
|
||||
} else {
|
||||
return o.importExpr(token.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
export function createInlineArray(values: o.Expression[]): o.Expression {
|
||||
if (values.length === 0) {
|
||||
return o.importExpr(createIdentifier(Identifiers.EMPTY_INLINE_ARRAY));
|
||||
}
|
||||
const log2 = Math.log(values.length) / Math.log(2);
|
||||
const index = Math.ceil(log2);
|
||||
const identifierSpec = index < Identifiers.inlineArrays.length ? Identifiers.inlineArrays[index] :
|
||||
Identifiers.InlineArrayDynamic;
|
||||
const identifier = createIdentifier(identifierSpec);
|
||||
return o.importExpr(identifier).instantiate([
|
||||
<o.Expression>o.literal(values.length)
|
||||
].concat(values));
|
||||
}
|
||||
|
||||
export function createPureProxy(
|
||||
fn: o.Expression, argCount: number, pureProxyProp: o.ReadPropExpr,
|
||||
builder: {fields: o.ClassField[], ctorStmts: {push: (stmt: o.Statement) => void}}) {
|
||||
builder.fields.push(new o.ClassField(pureProxyProp.name, null));
|
||||
const pureProxyId =
|
||||
argCount < Identifiers.pureProxies.length ? Identifiers.pureProxies[argCount] : null;
|
||||
if (!pureProxyId) {
|
||||
throw new Error(`Unsupported number of argument for pure functions: ${argCount}`);
|
||||
}
|
||||
builder.ctorStmts.push(o.THIS_EXPR.prop(pureProxyProp.name)
|
||||
.set(o.importExpr(createIdentifier(pureProxyId)).callFn([fn]))
|
||||
.toStmt());
|
||||
}
|
||||
|
||||
export function createEnumExpression(enumType: IdentifierSpec, enumValue: any): o.Expression {
|
||||
const enumName =
|
||||
Object.keys(enumType.runtime).find((propName) => enumType.runtime[propName] === enumValue);
|
||||
if (!enumName) {
|
||||
throw new Error(`Unknown enum value ${enumValue} in ${enumType.name}`);
|
||||
}
|
||||
return o.importExpr(createEnumIdentifier(enumType, enumName));
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {SecurityContext, ɵEMPTY_STATE as EMPTY_ANIMATION_STATE} from '@angular/core';
|
||||
import {Identifiers, createIdentifier} from '../identifiers';
|
||||
import * as o from '../output/output_ast';
|
||||
import {BoundElementPropertyAst, BoundEventAst, PropertyBindingType} from '../template_parser/template_ast';
|
||||
|
||||
import {isFirstViewCheck} from './binding_util';
|
||||
import {LegacyConvertPropertyBindingResult} from './expression_converter';
|
||||
import {createEnumExpression} from './identifier_util';
|
||||
|
||||
export function createCheckRenderBindingStmt(
|
||||
view: o.Expression, renderElement: o.Expression, boundProp: BoundElementPropertyAst,
|
||||
oldValue: o.ReadPropExpr, evalResult: LegacyConvertPropertyBindingResult,
|
||||
securityContextExpression?: o.Expression): o.Statement[] {
|
||||
const checkStmts: o.Statement[] = [...evalResult.stmts];
|
||||
const securityContext = calcSecurityContext(boundProp, securityContextExpression);
|
||||
switch (boundProp.type) {
|
||||
case PropertyBindingType.Property:
|
||||
checkStmts.push(o.importExpr(createIdentifier(Identifiers.checkRenderProperty))
|
||||
.callFn([
|
||||
view, renderElement, o.literal(boundProp.name), oldValue,
|
||||
oldValue.set(evalResult.currValExpr),
|
||||
evalResult.forceUpdate || o.literal(false), securityContext
|
||||
])
|
||||
.toStmt());
|
||||
break;
|
||||
case PropertyBindingType.Attribute:
|
||||
checkStmts.push(o.importExpr(createIdentifier(Identifiers.checkRenderAttribute))
|
||||
.callFn([
|
||||
view, renderElement, o.literal(boundProp.name), oldValue,
|
||||
oldValue.set(evalResult.currValExpr),
|
||||
evalResult.forceUpdate || o.literal(false), securityContext
|
||||
])
|
||||
.toStmt());
|
||||
break;
|
||||
case PropertyBindingType.Class:
|
||||
checkStmts.push(
|
||||
o.importExpr(createIdentifier(Identifiers.checkRenderClass))
|
||||
.callFn([
|
||||
view, renderElement, o.literal(boundProp.name), oldValue,
|
||||
oldValue.set(evalResult.currValExpr), evalResult.forceUpdate || o.literal(false)
|
||||
])
|
||||
.toStmt());
|
||||
break;
|
||||
case PropertyBindingType.Style:
|
||||
checkStmts.push(
|
||||
o.importExpr(createIdentifier(Identifiers.checkRenderStyle))
|
||||
.callFn([
|
||||
view, renderElement, o.literal(boundProp.name), o.literal(boundProp.unit), oldValue,
|
||||
oldValue.set(evalResult.currValExpr), evalResult.forceUpdate || o.literal(false),
|
||||
securityContext
|
||||
])
|
||||
.toStmt());
|
||||
break;
|
||||
case PropertyBindingType.Animation:
|
||||
throw new Error('Illegal state: Should not come here!');
|
||||
}
|
||||
return checkStmts;
|
||||
}
|
||||
|
||||
function calcSecurityContext(
|
||||
boundProp: BoundElementPropertyAst, securityContextExpression?: o.Expression): o.Expression {
|
||||
if (boundProp.securityContext === SecurityContext.NONE) {
|
||||
return o.NULL_EXPR; // No sanitization needed.
|
||||
}
|
||||
if (!boundProp.needsRuntimeSecurityContext) {
|
||||
securityContextExpression =
|
||||
createEnumExpression(Identifiers.SecurityContext, boundProp.securityContext);
|
||||
}
|
||||
if (!securityContextExpression) {
|
||||
throw new Error(`internal error, no SecurityContext given ${boundProp.name}`);
|
||||
}
|
||||
return securityContextExpression;
|
||||
}
|
||||
|
||||
export function createCheckAnimationBindingStmts(
|
||||
view: o.Expression, componentView: o.Expression, boundProp: BoundElementPropertyAst,
|
||||
boundOutputs: BoundEventAst[], eventListener: o.Expression, renderElement: o.Expression,
|
||||
oldValue: o.ReadPropExpr, evalResult: LegacyConvertPropertyBindingResult) {
|
||||
const detachStmts: o.Statement[] = [];
|
||||
const updateStmts: o.Statement[] = [];
|
||||
|
||||
const animationName = boundProp.name;
|
||||
|
||||
const animationFnExpr =
|
||||
componentView.prop('componentType').prop('animations').key(o.literal(animationName));
|
||||
|
||||
// it's important to normalize the void value as `void` explicitly
|
||||
// so that the styles data can be obtained from the stringmap
|
||||
const emptyStateValue = o.literal(EMPTY_ANIMATION_STATE);
|
||||
const animationTransitionVar = o.variable('animationTransition_' + animationName);
|
||||
|
||||
updateStmts.push(
|
||||
animationTransitionVar
|
||||
.set(animationFnExpr.callFn([
|
||||
view, renderElement, isFirstViewCheck(view).conditional(emptyStateValue, oldValue),
|
||||
evalResult.currValExpr
|
||||
]))
|
||||
.toDeclStmt());
|
||||
updateStmts.push(oldValue.set(evalResult.currValExpr).toStmt());
|
||||
|
||||
detachStmts.push(animationTransitionVar
|
||||
.set(animationFnExpr.callFn(
|
||||
[view, renderElement, evalResult.currValExpr, emptyStateValue]))
|
||||
.toDeclStmt());
|
||||
|
||||
const registerStmts: o.Statement[] = [];
|
||||
const animationStartMethodExists = boundOutputs.find(
|
||||
event => event.isAnimation && event.name == animationName && event.phase == 'start');
|
||||
if (animationStartMethodExists) {
|
||||
registerStmts.push(
|
||||
animationTransitionVar
|
||||
.callMethod(
|
||||
'onStart',
|
||||
[eventListener.callMethod(
|
||||
o.BuiltinMethod.Bind,
|
||||
[view, o.literal(BoundEventAst.calcFullName(animationName, null, 'start'))])])
|
||||
.toStmt());
|
||||
}
|
||||
|
||||
const animationDoneMethodExists = boundOutputs.find(
|
||||
event => event.isAnimation && event.name == animationName && event.phase == 'done');
|
||||
if (animationDoneMethodExists) {
|
||||
registerStmts.push(
|
||||
animationTransitionVar
|
||||
.callMethod(
|
||||
'onDone',
|
||||
[eventListener.callMethod(
|
||||
o.BuiltinMethod.Bind,
|
||||
[view, o.literal(BoundEventAst.calcFullName(animationName, null, 'done'))])])
|
||||
.toStmt());
|
||||
}
|
||||
|
||||
updateStmts.push(...registerStmts);
|
||||
detachStmts.push(...registerStmts);
|
||||
|
||||
const checkUpdateStmts: o.Statement[] = [
|
||||
...evalResult.stmts,
|
||||
new o.IfStmt(
|
||||
o.importExpr(createIdentifier(Identifiers.checkBinding)).callFn([
|
||||
view, oldValue, evalResult.currValExpr, evalResult.forceUpdate || o.literal(false)
|
||||
]),
|
||||
updateStmts)
|
||||
];
|
||||
const checkDetachStmts: o.Statement[] = [...evalResult.stmts, ...detachStmts];
|
||||
return {checkUpdateStmts, checkDetachStmts};
|
||||
}
|
Reference in New Issue
Block a user