refactor(compiler): introduce `ClassBuilder`.

Part of #11683
This commit is contained in:
Tobias Bosch 2016-10-21 13:37:51 -07:00 committed by vsavkin
parent faa3478514
commit cb7643ccea
6 changed files with 160 additions and 88 deletions

View File

@ -11,6 +11,7 @@ import {Injectable} from '@angular/core';
import {CompileDirectiveMetadata, CompileIdentifierMetadata} from './compile_metadata'; import {CompileDirectiveMetadata, CompileIdentifierMetadata} from './compile_metadata';
import {CompilerConfig} from './config'; import {CompilerConfig} from './config';
import {Identifiers, resolveIdentifier} from './identifiers'; import {Identifiers, resolveIdentifier} from './identifiers';
import {ClassBuilder, createClassStmt} from './output/class_builder';
import * as o from './output/output_ast'; import * as o from './output/output_ast';
import {LifecycleHooks, isDefaultChangeDetectionStrategy} from './private_import_core'; import {LifecycleHooks, isDefaultChangeDetectionStrategy} from './private_import_core';
@ -45,59 +46,68 @@ export class DirectiveWrapperCompiler {
constructor(private compilerConfig: CompilerConfig) {} constructor(private compilerConfig: CompilerConfig) {}
compile(dirMeta: CompileDirectiveMetadata): DirectiveWrapperCompileResult { compile(dirMeta: CompileDirectiveMetadata): DirectiveWrapperCompileResult {
const builder = new DirectiveWrapperBuilder(this.compilerConfig, dirMeta);
Object.keys(dirMeta.inputs).forEach((inputFieldName) => {
createCheckInputMethod(inputFieldName, builder);
});
createDetectChangesInternalMethod(builder);
const classStmt = builder.build();
return new DirectiveWrapperCompileResult([classStmt], classStmt.name);
}
}
class DirectiveWrapperBuilder implements ClassBuilder {
fields: o.ClassField[] = [];
getters: o.ClassGetter[] = [];
methods: o.ClassMethod[] = [];
ctorStmts: o.Statement[] = [];
genChanges: boolean;
ngOnChanges: boolean;
ngOnInit: boolean;
ngDoCheck: boolean;
constructor(public compilerConfig: CompilerConfig, public dirMeta: CompileDirectiveMetadata) {
const dirLifecycleHooks = dirMeta.type.lifecycleHooks;
this.genChanges = dirLifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1 ||
this.compilerConfig.logBindingUpdate;
this.ngOnChanges = dirLifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1;
this.ngOnInit = dirLifecycleHooks.indexOf(LifecycleHooks.OnInit) !== -1;
this.ngDoCheck = dirLifecycleHooks.indexOf(LifecycleHooks.DoCheck) !== -1;
}
build(): o.ClassStmt {
const dirDepParamNames: string[] = []; const dirDepParamNames: string[] = [];
for (let i = 0; i < dirMeta.type.diDeps.length; i++) { for (let i = 0; i < this.dirMeta.type.diDeps.length; i++) {
dirDepParamNames.push(`p${i}`); dirDepParamNames.push(`p${i}`);
} }
const dirLifecycleHooks = dirMeta.type.lifecycleHooks;
let lifecycleHooks: GenConfig = {
genChanges: dirLifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1 ||
this.compilerConfig.logBindingUpdate,
ngOnChanges: dirLifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1,
ngOnInit: dirLifecycleHooks.indexOf(LifecycleHooks.OnInit) !== -1,
ngDoCheck: dirLifecycleHooks.indexOf(LifecycleHooks.DoCheck) !== -1
};
const fields: o.ClassField[] = [ const fields: o.ClassField[] = [
new o.ClassField(CONTEXT_FIELD_NAME, o.importType(dirMeta.type)), new o.ClassField(CONTEXT_FIELD_NAME, o.importType(this.dirMeta.type)),
new o.ClassField(CHANGED_FIELD_NAME, o.BOOL_TYPE), new o.ClassField(CHANGED_FIELD_NAME, o.BOOL_TYPE),
]; ];
const ctorStmts: o.Statement[] = const ctorStmts: o.Statement[] =
[o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(false)).toStmt()]; [o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(false)).toStmt()];
if (lifecycleHooks.genChanges) { if (this.genChanges) {
fields.push(new o.ClassField(CHANGES_FIELD_NAME, new o.MapType(o.DYNAMIC_TYPE))); fields.push(new o.ClassField(CHANGES_FIELD_NAME, new o.MapType(o.DYNAMIC_TYPE)));
ctorStmts.push(RESET_CHANGES_STMT); ctorStmts.push(RESET_CHANGES_STMT);
} }
const methods: o.ClassMethod[] = [];
Object.keys(dirMeta.inputs).forEach((inputFieldName, idx) => {
const fieldName = `_${inputFieldName}`;
// private is fine here as no child view will reference the cached value...
fields.push(new o.ClassField(fieldName, null, [o.StmtModifier.Private]));
ctorStmts.push(o.THIS_EXPR.prop(fieldName)
.set(o.importExpr(resolveIdentifier(Identifiers.UNINITIALIZED)))
.toStmt());
methods.push(checkInputMethod(inputFieldName, o.THIS_EXPR.prop(fieldName), lifecycleHooks));
});
methods.push(detectChangesInternalMethod(lifecycleHooks, this.compilerConfig.genDebugInfo));
ctorStmts.push( ctorStmts.push(
o.THIS_EXPR.prop(CONTEXT_FIELD_NAME) o.THIS_EXPR.prop(CONTEXT_FIELD_NAME)
.set(o.importExpr(dirMeta.type) .set(o.importExpr(this.dirMeta.type)
.instantiate(dirDepParamNames.map((paramName) => o.variable(paramName)))) .instantiate(dirDepParamNames.map((paramName) => o.variable(paramName))))
.toStmt()); .toStmt());
const ctor = new o.ClassMethod(
null, dirDepParamNames.map((paramName) => new o.FnParam(paramName, o.DYNAMIC_TYPE)),
ctorStmts);
const wrapperClassName = DirectiveWrapperCompiler.dirWrapperClassName(dirMeta.type); return createClassStmt({
const classStmt = new o.ClassStmt(wrapperClassName, null, fields, [], ctor, methods); name: DirectiveWrapperCompiler.dirWrapperClassName(this.dirMeta.type),
return new DirectiveWrapperCompileResult([classStmt], wrapperClassName); ctorParams: dirDepParamNames.map((paramName) => new o.FnParam(paramName, o.DYNAMIC_TYPE)),
builders: [{fields: fields, ctorStmts: ctorStmts}, this]
})
} }
} }
function detectChangesInternalMethod( function createDetectChangesInternalMethod(builder: DirectiveWrapperBuilder) {
lifecycleHooks: GenConfig, logBindingUpdate: boolean): o.ClassMethod {
const changedVar = o.variable('changed'); const changedVar = o.variable('changed');
const stmts: o.Statement[] = [ const stmts: o.Statement[] = [
changedVar.set(o.THIS_EXPR.prop(CHANGED_FIELD_NAME)).toDeclStmt(), changedVar.set(o.THIS_EXPR.prop(CHANGED_FIELD_NAME)).toDeclStmt(),
@ -105,14 +115,14 @@ function detectChangesInternalMethod(
]; ];
const lifecycleStmts: o.Statement[] = []; const lifecycleStmts: o.Statement[] = [];
if (lifecycleHooks.genChanges) { if (builder.genChanges) {
const onChangesStmts: o.Statement[] = []; const onChangesStmts: o.Statement[] = [];
if (lifecycleHooks.ngOnChanges) { if (builder.ngOnChanges) {
onChangesStmts.push(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME) onChangesStmts.push(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME)
.callMethod('ngOnChanges', [o.THIS_EXPR.prop(CHANGES_FIELD_NAME)]) .callMethod('ngOnChanges', [o.THIS_EXPR.prop(CHANGES_FIELD_NAME)])
.toStmt()); .toStmt());
} }
if (logBindingUpdate) { if (builder.compilerConfig.logBindingUpdate) {
onChangesStmts.push( onChangesStmts.push(
o.importExpr(resolveIdentifier(Identifiers.setBindingDebugInfoForChanges)) o.importExpr(resolveIdentifier(Identifiers.setBindingDebugInfoForChanges))
.callFn( .callFn(
@ -123,12 +133,12 @@ function detectChangesInternalMethod(
lifecycleStmts.push(new o.IfStmt(changedVar, onChangesStmts)); lifecycleStmts.push(new o.IfStmt(changedVar, onChangesStmts));
} }
if (lifecycleHooks.ngOnInit) { if (builder.ngOnInit) {
lifecycleStmts.push(new o.IfStmt( lifecycleStmts.push(new o.IfStmt(
VIEW_VAR.prop('numberOfChecks').identical(new o.LiteralExpr(0)), VIEW_VAR.prop('numberOfChecks').identical(new o.LiteralExpr(0)),
[o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).callMethod('ngOnInit', []).toStmt()])); [o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).callMethod('ngOnInit', []).toStmt()]));
} }
if (lifecycleHooks.ngDoCheck) { if (builder.ngDoCheck) {
lifecycleStmts.push(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).callMethod('ngDoCheck', []).toStmt()); lifecycleStmts.push(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).callMethod('ngDoCheck', []).toStmt());
} }
if (lifecycleStmts.length > 0) { if (lifecycleStmts.length > 0) {
@ -136,7 +146,7 @@ function detectChangesInternalMethod(
} }
stmts.push(new o.ReturnStatement(changedVar)); stmts.push(new o.ReturnStatement(changedVar));
return new o.ClassMethod( builder.methods.push(new o.ClassMethod(
'detectChangesInternal', 'detectChangesInternal',
[ [
new o.FnParam( new o.FnParam(
@ -144,16 +154,22 @@ function detectChangesInternalMethod(
new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE), new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE), new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
], ],
stmts, o.BOOL_TYPE); stmts, o.BOOL_TYPE));
} }
function checkInputMethod( function createCheckInputMethod(input: string, builder: DirectiveWrapperBuilder) {
input: string, fieldExpr: o.ReadPropExpr, lifecycleHooks: GenConfig): o.ClassMethod { const fieldName = `_${input}`;
const fieldExpr = o.THIS_EXPR.prop(fieldName);
// private is fine here as no child view will reference the cached value...
builder.fields.push(new o.ClassField(fieldName, null, [o.StmtModifier.Private]));
builder.ctorStmts.push(o.THIS_EXPR.prop(fieldName)
.set(o.importExpr(resolveIdentifier(Identifiers.UNINITIALIZED)))
.toStmt());
var onChangeStatements: o.Statement[] = [ var onChangeStatements: o.Statement[] = [
o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(true)).toStmt(), o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(true)).toStmt(),
o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).prop(input).set(CURR_VALUE_VAR).toStmt(), o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).prop(input).set(CURR_VALUE_VAR).toStmt(),
]; ];
if (lifecycleHooks.genChanges) { if (builder.genChanges) {
onChangeStatements.push(o.THIS_EXPR.prop(CHANGES_FIELD_NAME) onChangeStatements.push(o.THIS_EXPR.prop(CHANGES_FIELD_NAME)
.key(o.literal(input)) .key(o.literal(input))
.set(o.importExpr(resolveIdentifier(Identifiers.SimpleChange)) .set(o.importExpr(resolveIdentifier(Identifiers.SimpleChange))
@ -168,19 +184,12 @@ function checkInputMethod(
.callFn([THROW_ON_CHANGE_VAR, fieldExpr, CURR_VALUE_VAR])), .callFn([THROW_ON_CHANGE_VAR, fieldExpr, CURR_VALUE_VAR])),
onChangeStatements), onChangeStatements),
]; ];
return new o.ClassMethod( builder.methods.push(new o.ClassMethod(
`check_${input}`, `check_${input}`,
[ [
new o.FnParam(CURR_VALUE_VAR.name, o.DYNAMIC_TYPE), new o.FnParam(CURR_VALUE_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE), new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
new o.FnParam(FORCE_UPDATE_VAR.name, o.BOOL_TYPE), new o.FnParam(FORCE_UPDATE_VAR.name, o.BOOL_TYPE),
], ],
methodBody); methodBody));
} }
interface GenConfig {
genChanges: boolean;
ngOnChanges: boolean;
ngOnInit: boolean;
ngDoCheck: boolean;
}

View File

@ -12,6 +12,7 @@ import {CompileDiDependencyMetadata, CompileIdentifierMetadata, CompileNgModuleM
import {createDiTokenExpression} from './compiler_util/identifier_util'; import {createDiTokenExpression} from './compiler_util/identifier_util';
import {isPresent} from './facade/lang'; import {isPresent} from './facade/lang';
import {Identifiers, resolveIdentifier, resolveIdentifierToken} from './identifiers'; import {Identifiers, resolveIdentifier, resolveIdentifierToken} from './identifiers';
import {ClassBuilder, createClassStmt} from './output/class_builder';
import * as o from './output/output_ast'; import * as o from './output/output_ast';
import {convertValueToOutputAst} from './output/value_util'; import {convertValueToOutputAst} from './output/value_util';
import {ParseLocation, ParseSourceFile, ParseSourceSpan} from './parse_util'; import {ParseLocation, ParseSourceFile, ParseSourceSpan} from './parse_util';
@ -82,13 +83,15 @@ export class NgModuleCompiler {
} }
} }
class _InjectorBuilder { class _InjectorBuilder implements ClassBuilder {
private _tokens: CompileTokenMetadata[] = []; private _tokens: CompileTokenMetadata[] = [];
private _instances = new Map<any, o.Expression>(); private _instances = new Map<any, o.Expression>();
private _fields: o.ClassField[] = []; fields: o.ClassField[] = [];
private _createStmts: o.Statement[] = []; private _createStmts: o.Statement[] = [];
private _destroyStmts: o.Statement[] = []; private _destroyStmts: o.Statement[] = [];
private _getters: o.ClassGetter[] = []; getters: o.ClassGetter[] = [];
methods: o.ClassMethod[] = [];
ctorStmts: o.Statement[] = [];
constructor( constructor(
private _ngModuleMeta: CompileNgModuleMetadata, private _ngModuleMeta: CompileNgModuleMetadata,
@ -136,26 +139,23 @@ class _InjectorBuilder {
), ),
]; ];
var ctor = new o.ClassMethod( var parentArgs = [
null, o.variable(InjectorProps.parent.name),
[new o.FnParam( o.literalArr(
InjectorProps.parent.name, o.importType(resolveIdentifier(Identifiers.Injector)))], this._entryComponentFactories.map((componentFactory) => o.importExpr(componentFactory))),
[o.SUPER_EXPR o.literalArr(this._bootstrapComponentFactories.map(
.callFn([ (componentFactory) => o.importExpr(componentFactory)))
o.variable(InjectorProps.parent.name), ];
o.literalArr(this._entryComponentFactories.map(
(componentFactory) => o.importExpr(componentFactory))),
o.literalArr(this._bootstrapComponentFactories.map(
(componentFactory) => o.importExpr(componentFactory)))
])
.toStmt()]);
var injClassName = `${this._ngModuleMeta.type.name}Injector`; var injClassName = `${this._ngModuleMeta.type.name}Injector`;
return new o.ClassStmt( return createClassStmt({
injClassName, o.importExpr( name: injClassName,
resolveIdentifier(Identifiers.NgModuleInjector), ctorParams: [new o.FnParam(
[o.importType(this._ngModuleMeta.type)]), InjectorProps.parent.name, o.importType(resolveIdentifier(Identifiers.Injector)))],
this._fields, this._getters, ctor, methods); parent: o.importExpr(
resolveIdentifier(Identifiers.NgModuleInjector), [o.importType(this._ngModuleMeta.type)]),
parentArgs: parentArgs,
builders: [{methods: methods}, this]
});
} }
private _getProviderValue(provider: CompileProviderMetadata): o.Expression { private _getProviderValue(provider: CompileProviderMetadata): o.Expression {
@ -194,11 +194,11 @@ class _InjectorBuilder {
type = o.DYNAMIC_TYPE; type = o.DYNAMIC_TYPE;
} }
if (isEager) { if (isEager) {
this._fields.push(new o.ClassField(propName, type)); this.fields.push(new o.ClassField(propName, type));
this._createStmts.push(o.THIS_EXPR.prop(propName).set(resolvedProviderValueExpr).toStmt()); this._createStmts.push(o.THIS_EXPR.prop(propName).set(resolvedProviderValueExpr).toStmt());
} else { } else {
var internalField = `_${propName}`; var internalField = `_${propName}`;
this._fields.push(new o.ClassField(internalField, type)); this.fields.push(new o.ClassField(internalField, type));
// Note: Equals is important for JS so that it also checks the undefined case! // Note: Equals is important for JS so that it also checks the undefined case!
var getterStmts = [ var getterStmts = [
new o.IfStmt( new o.IfStmt(
@ -206,7 +206,7 @@ class _InjectorBuilder {
[o.THIS_EXPR.prop(internalField).set(resolvedProviderValueExpr).toStmt()]), [o.THIS_EXPR.prop(internalField).set(resolvedProviderValueExpr).toStmt()]),
new o.ReturnStatement(o.THIS_EXPR.prop(internalField)) new o.ReturnStatement(o.THIS_EXPR.prop(internalField))
]; ];
this._getters.push(new o.ClassGetter(propName, getterStmts, type)); this.getters.push(new o.ClassGetter(propName, getterStmts, type));
} }
return o.THIS_EXPR.prop(propName); return o.THIS_EXPR.prop(propName);
} }

View File

@ -0,0 +1,60 @@
/**
* @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 * as o from './output_ast';
/**
* Create a new class stmts based on the given data.
*/
export function createClassStmt(config: {
name: string,
parent?: o.Expression,
parentArgs?: o.Expression[],
ctorParams?: o.FnParam[],
builders: ClassBuilderPart | ClassBuilderPart[], modifiers?: o.StmtModifier[]
}): o.ClassStmt {
const parentArgs = config.parentArgs || [];
const superCtorStmts = config.parent ? [o.SUPER_EXPR.callFn(parentArgs).toStmt()] : [];
const builder =
concatClassBuilderParts(Array.isArray(config.builders) ? config.builders : [config.builders]);
const ctor =
new o.ClassMethod(null, config.ctorParams || [], superCtorStmts.concat(builder.ctorStmts));
return new o.ClassStmt(
config.name, config.parent, builder.fields, builder.getters, ctor, builder.methods,
config.modifiers || [])
}
function concatClassBuilderParts(builders: ClassBuilderPart[]): ClassBuilder {
return {
fields: [].concat(...builders.map(builder => builder.fields || [])),
methods: [].concat(...builders.map(builder => builder.methods || [])),
getters: [].concat(...builders.map(builder => builder.getters || [])),
ctorStmts: [].concat(...builders.map(builder => builder.ctorStmts || [])),
};
}
/**
* Collects data for a generated class.
*/
export interface ClassBuilderPart {
fields?: o.ClassField[];
methods?: o.ClassMethod[];
getters?: o.ClassGetter[];
ctorStmts?: o.Statement[];
}
/**
* Collects data for a generated class.
*/
export interface ClassBuilder extends ClassBuilderPart {
fields: o.ClassField[];
methods: o.ClassMethod[];
getters: o.ClassGetter[];
ctorStmts: o.Statement[];
}

View File

@ -12,6 +12,7 @@ import {CompilerConfig} from '../config';
import {MapWrapper} from '../facade/collection'; import {MapWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, resolveIdentifier} from '../identifiers';
import {ClassBuilder} from '../output/class_builder';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {ViewType} from '../private_import_core'; import {ViewType} from '../private_import_core';
@ -24,7 +25,7 @@ import {EventHandlerVars} from './constants';
import {NameResolver} from './expression_converter'; import {NameResolver} from './expression_converter';
import {createPureProxy, getPropertyInView, getViewFactoryName} from './util'; import {createPureProxy, getPropertyInView, getViewFactoryName} from './util';
export class CompileView implements NameResolver { export class CompileView implements NameResolver, ClassBuilder {
public viewType: ViewType; public viewType: ViewType;
public viewQueries: Map<any, CompileQuery[]>; public viewQueries: Map<any, CompileQuery[]>;
@ -34,7 +35,6 @@ export class CompileView implements NameResolver {
public bindings: CompileBinding[] = []; public bindings: CompileBinding[] = [];
public classStatements: o.Statement[] = [];
public createMethod: CompileMethod; public createMethod: CompileMethod;
public animationBindingsMethod: CompileMethod; public animationBindingsMethod: CompileMethod;
public injectorGetMethod: CompileMethod; public injectorGetMethod: CompileMethod;
@ -47,8 +47,9 @@ export class CompileView implements NameResolver {
public afterViewLifecycleCallbacksMethod: CompileMethod; public afterViewLifecycleCallbacksMethod: CompileMethod;
public destroyMethod: CompileMethod; public destroyMethod: CompileMethod;
public detachMethod: CompileMethod; public detachMethod: CompileMethod;
public eventHandlerMethods: o.ClassMethod[] = []; public methods: o.ClassMethod[] = [];
public ctorStmts: o.Statement[] = [];
public fields: o.ClassField[] = []; public fields: o.ClassField[] = [];
public getters: o.ClassGetter[] = []; public getters: o.ClassGetter[] = [];
public disposables: o.Expression[] = []; public disposables: o.Expression[] = [];

View File

@ -92,7 +92,7 @@ export class CompileEventListener {
.concat(this._method.finish()) .concat(this._method.finish())
.concat([new o.ReturnStatement(resultExpr)]); .concat([new o.ReturnStatement(resultExpr)]);
// private is fine here as no child view will reference the event handler... // private is fine here as no child view will reference the event handler...
this.compileElement.view.eventHandlerMethods.push(new o.ClassMethod( this.compileElement.view.methods.push(new o.ClassMethod(
this._methodName, [this._eventParam], stmts, o.BOOL_TYPE, [o.StmtModifier.Private])); this._methodName, [this._eventParam], stmts, o.BOOL_TYPE, [o.StmtModifier.Private]));
} }

View File

@ -12,6 +12,7 @@ import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileTokenMetadat
import {createDiTokenExpression, createFastArray} from '../compiler_util/identifier_util'; import {createDiTokenExpression, createFastArray} from '../compiler_util/identifier_util';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, identifierToken, resolveIdentifier} from '../identifiers'; import {Identifiers, identifierToken, resolveIdentifier} from '../identifiers';
import {createClassStmt} from '../output/class_builder';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {ChangeDetectorStatus, ViewType, isDefaultChangeDetectionStrategy} from '../private_import_core'; import {ChangeDetectorStatus, ViewType, isDefaultChangeDetectionStrategy} from '../private_import_core';
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast'; import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast';
@ -432,9 +433,6 @@ function createViewClass(
if (view.genConfig.genDebugInfo) { if (view.genConfig.genDebugInfo) {
superConstructorArgs.push(nodeDebugInfosVar); superConstructorArgs.push(nodeDebugInfosVar);
} }
var viewConstructor = new o.ClassMethod(
null, viewConstructorArgs, [o.SUPER_EXPR.callFn(superConstructorArgs).toStmt()]);
var viewMethods = [ var viewMethods = [
new o.ClassMethod( new o.ClassMethod(
'createInternal', [new o.FnParam(rootSelectorVar.name, o.STRING_TYPE)], 'createInternal', [new o.FnParam(rootSelectorVar.name, o.STRING_TYPE)],
@ -455,12 +453,16 @@ function createViewClass(
new o.ClassMethod('dirtyParentQueriesInternal', [], view.dirtyParentQueriesMethod.finish()), new o.ClassMethod('dirtyParentQueriesInternal', [], view.dirtyParentQueriesMethod.finish()),
new o.ClassMethod('destroyInternal', [], view.destroyMethod.finish()), new o.ClassMethod('destroyInternal', [], view.destroyMethod.finish()),
new o.ClassMethod('detachInternal', [], view.detachMethod.finish()) new o.ClassMethod('detachInternal', [], view.detachMethod.finish())
].concat(view.eventHandlerMethods); ].filter((method) => method.body.length > 0);
var superClass = view.genConfig.genDebugInfo ? Identifiers.DebugAppView : Identifiers.AppView; var superClass = view.genConfig.genDebugInfo ? Identifiers.DebugAppView : Identifiers.AppView;
var viewClass = new o.ClassStmt(
view.className, o.importExpr(resolveIdentifier(superClass), [getContextType(view)]), var viewClass = createClassStmt({
view.fields, view.getters, viewConstructor, name: view.className,
viewMethods.filter((method) => method.body.length > 0)); parent: o.importExpr(resolveIdentifier(superClass), [getContextType(view)]),
parentArgs: superConstructorArgs,
ctorParams: viewConstructorArgs,
builders: [{methods: viewMethods}, view]
});
return viewClass; return viewClass;
} }