feat(compiler): implement style encapsulation for new view engine (#14518)

Included refactoring:
- splits the `RendererV2` into a `RendererFactoryV2` and a `RendererV2`
- makes the `DebugRendererV2` a private class in `@angular/core`
- remove `setBindingDebugInfo` from `RendererV2`, but rename `RendererV2.setText` to 
  `RendererV2.setValue` and allow it on comments and text nodes.

Part of #14013
This commit is contained in:
Tobias Bosch
2017-02-16 13:55:55 -08:00
committed by Igor Minar
parent ba17dcbf2b
commit 0fa3895d5b
38 changed files with 828 additions and 595 deletions

View File

@ -101,11 +101,12 @@ export class AotCompiler {
});
// compile components
const compViewVars = this._compileComponent(
compMeta, ngModule, ngModule.transitiveModule.directives,
stylesCompileResults.componentStylesheet, fileSuffix, statements);
exportedVars.push(
this._compileComponentFactory(compMeta, ngModule, fileSuffix, statements),
this._compileComponent(
compMeta, ngModule, ngModule.transitiveModule.directives,
stylesCompileResults.componentStylesheet, fileSuffix, statements));
compViewVars.viewClassVar, compViewVars.compRenderTypeVar);
});
if (statements.length > 0) {
const srcModule = this._codegenSourceModule(
@ -175,8 +176,10 @@ export class AotCompiler {
const hostType = this._metadataResolver.getHostComponentType(compMeta.type.reference);
const hostMeta = createHostComponentMeta(
hostType, compMeta, this._metadataResolver.getHostComponentViewClass(hostType));
const hostViewFactoryVar = this._compileComponent(
hostMeta, ngModule, [compMeta.type], null, fileSuffix, targetStatements);
const hostViewFactoryVar =
this._compileComponent(
hostMeta, ngModule, [compMeta.type], null, fileSuffix, targetStatements)
.viewClassVar;
const compFactoryVar = componentFactoryName(compMeta.type.reference);
targetStatements.push(
o.variable(compFactoryVar)
@ -198,7 +201,8 @@ export class AotCompiler {
private _compileComponent(
compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata,
directiveIdentifiers: CompileIdentifierMetadata[], componentStyles: CompiledStylesheet,
fileSuffix: string, targetStatements: o.Statement[]): string {
fileSuffix: string,
targetStatements: o.Statement[]): {viewClassVar: string, compRenderTypeVar: string} {
const parsedAnimations = this._animationParser.parseComponent(compMeta);
const directives =
directiveIdentifiers.map(dir => this._metadataResolver.getDirectiveSummary(dir.reference));
@ -219,7 +223,10 @@ export class AotCompiler {
}
compiledAnimations.forEach(entry => targetStatements.push(...entry.statements));
targetStatements.push(...viewResult.statements);
return viewResult.viewClassVar;
return {
viewClassVar: viewResult.viewClassVar,
compRenderTypeVar: viewResult.componentRenderTypeVar
};
}
private _codgenStyles(

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ChangeDetectionStrategy, ComponentFactory, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core';
import {ChangeDetectionStrategy, ComponentFactory, ComponentRenderTypeV2, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core';
import {StaticSymbol} from './aot/static_symbol';
import {ListWrapper} from './facade/collection';
@ -15,6 +15,7 @@ import {LifecycleHooks, reflector} from './private_import_core';
import {CssSelector} from './selector';
import {splitAtColon} from './util';
// group 0: "[prop] or (event) or @trigger"
// group 1: "prop" from "[prop]"
// group 2: "event" from "(event)"
@ -116,6 +117,10 @@ export function viewClassName(compType: any, embeddedTemplateIndex: number): str
return `View_${identifierName({reference: compType})}_${embeddedTemplateIndex}`;
}
export function componentRenderTypeName(compType: any): string {
return `RenderType_${identifierName({reference: compType})}`;
}
export function hostViewClassName(compType: any): string {
return `HostView_${identifierName({reference: compType})}`;
}
@ -310,6 +315,7 @@ export interface CompileDirectiveSummary extends CompileTypeSummary {
template: CompileTemplateSummary;
wrapperType: StaticSymbol|ProxyClass;
componentViewType: StaticSymbol|ProxyClass;
componentRenderType: StaticSymbol|ComponentRenderTypeV2;
componentFactory: StaticSymbol|ComponentFactory<any>;
}
@ -320,7 +326,7 @@ export class CompileDirectiveMetadata {
static create(
{isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
providers, viewProviders, queries, viewQueries, entryComponents, template, wrapperType,
componentViewType, componentFactory}: {
componentViewType, componentRenderType, componentFactory}: {
isHost?: boolean,
type?: CompileTypeMetadata,
isComponent?: boolean,
@ -338,6 +344,7 @@ export class CompileDirectiveMetadata {
template?: CompileTemplateMetadata,
wrapperType?: StaticSymbol|ProxyClass,
componentViewType?: StaticSymbol|ProxyClass,
componentRenderType?: StaticSymbol|ComponentRenderTypeV2,
componentFactory?: StaticSymbol|ComponentFactory<any>,
} = {}): CompileDirectiveMetadata {
const hostListeners: {[key: string]: string} = {};
@ -392,6 +399,7 @@ export class CompileDirectiveMetadata {
template,
wrapperType,
componentViewType,
componentRenderType,
componentFactory,
});
}
@ -416,12 +424,14 @@ export class CompileDirectiveMetadata {
wrapperType: StaticSymbol|ProxyClass;
componentViewType: StaticSymbol|ProxyClass;
componentRenderType: StaticSymbol|ComponentRenderTypeV2;
componentFactory: StaticSymbol|ComponentFactory<any>;
constructor({isHost, type, isComponent, selector, exportAs,
changeDetection, inputs, outputs, hostListeners, hostProperties,
hostAttributes, providers, viewProviders, queries, viewQueries,
entryComponents, template, wrapperType, componentViewType, componentFactory}: {
entryComponents, template, wrapperType, componentViewType, componentRenderType,
componentFactory}: {
isHost?: boolean,
type?: CompileTypeMetadata,
isComponent?: boolean,
@ -441,6 +451,7 @@ export class CompileDirectiveMetadata {
template?: CompileTemplateMetadata,
wrapperType?: StaticSymbol|ProxyClass,
componentViewType?: StaticSymbol|ProxyClass,
componentRenderType?: StaticSymbol|ComponentRenderTypeV2,
componentFactory?: StaticSymbol|ComponentFactory<any>,
} = {}) {
this.isHost = !!isHost;
@ -463,6 +474,7 @@ export class CompileDirectiveMetadata {
this.wrapperType = wrapperType;
this.componentViewType = componentViewType;
this.componentRenderType = componentRenderType;
this.componentFactory = componentFactory;
}
@ -487,6 +499,7 @@ export class CompileDirectiveMetadata {
template: this.template && this.template.toSummary(),
wrapperType: this.wrapperType,
componentViewType: this.componentViewType,
componentRenderType: this.componentRenderType,
componentFactory: this.componentFactory
};
}
@ -521,7 +534,9 @@ export function createHostComponentMeta(
viewProviders: [],
queries: [],
viewQueries: [],
componentViewType: hostViewType
componentViewType: hostViewType,
componentRenderType:
{id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}}
});
}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, ElementRef, Injector, LOCALE_ID, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT, TemplateRef, ViewContainerRef, ViewEncapsulation, ɵAnimationGroupPlayer, ɵAnimationKeyframe, ɵAnimationSequencePlayer, ɵAnimationStyles, ɵAnimationTransition, ɵAppView, ɵChangeDetectorStatus, ɵCodegenComponentFactoryResolver, ɵComponentRef_, ɵDebugAppView, ɵDebugContext, ɵNgModuleInjector, ɵNoOpAnimationPlayer, ɵStaticNodeDebugInfo, ɵTemplateRef_, ɵValueUnwrapper, ɵViewContainer, ɵViewType, ɵbalanceAnimationKeyframes, ɵclearStyles, ɵcollectAndResolveStyles, ɵdevModeEqual, ɵprepareFinalAnimationStyles, ɵreflector, ɵregisterModuleFactory, ɵrenderStyles, ɵviewEngine, ɵview_utils} from '@angular/core';
import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, ComponentRenderTypeV2, ElementRef, Injector, LOCALE_ID, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT, TemplateRef, ViewContainerRef, ViewEncapsulation, ɵAnimationGroupPlayer, ɵAnimationKeyframe, ɵAnimationSequencePlayer, ɵAnimationStyles, ɵAnimationTransition, ɵAppView, ɵChangeDetectorStatus, ɵCodegenComponentFactoryResolver, ɵComponentRef_, ɵDebugAppView, ɵDebugContext, ɵNgModuleInjector, ɵNoOpAnimationPlayer, ɵStaticNodeDebugInfo, ɵTemplateRef_, ɵValueUnwrapper, ɵViewContainer, ɵViewType, ɵbalanceAnimationKeyframes, ɵclearStyles, ɵcollectAndResolveStyles, ɵdevModeEqual, ɵprepareFinalAnimationStyles, ɵreflector, ɵregisterModuleFactory, ɵrenderStyles, ɵviewEngine, ɵview_utils} from '@angular/core';
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
@ -380,6 +380,12 @@ export class Identifiers {
member: 'unwrapValue',
runtime: ɵviewEngine.unwrapValue
};
static createComponentRenderTypeV2: IdentifierSpec = {
name: 'ɵviewEngine',
moduleUrl: CORE,
member: 'createComponentRenderTypeV2',
runtime: ɵviewEngine.createComponentRenderTypeV2
};
}
export function assetUrl(pkg: string, path: string = null, type: string = 'src'): string {

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Compiler, ComponentFactory, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type} from '@angular/core';
import {Compiler, ComponentFactory, ComponentRenderTypeV2, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type} from '@angular/core';
import {AnimationCompiler} from '../animation/animation_compiler';
import {AnimationParser} from '../animation/animation_parser';
@ -133,11 +133,11 @@ export class JitCompiler implements Compiler {
const compileResult = this._ngModuleCompiler.compile(moduleMeta, extraProviders);
if (!this._compilerConfig.useJit) {
ngModuleFactory =
interpretStatements(compileResult.statements, compileResult.ngModuleFactoryVar);
interpretStatements(compileResult.statements, [compileResult.ngModuleFactoryVar])[0];
} else {
ngModuleFactory = jitStatements(
`/${identifierName(moduleMeta.type)}/module.ngfactory.js`, compileResult.statements,
compileResult.ngModuleFactoryVar);
[compileResult.ngModuleFactoryVar])[0];
}
this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
}
@ -252,11 +252,12 @@ export class JitCompiler implements Compiler {
const statements = compileResult.statements;
let directiveWrapperClass: any;
if (!this._compilerConfig.useJit) {
directiveWrapperClass = interpretStatements(statements, compileResult.dirWrapperClassVar);
directiveWrapperClass =
interpretStatements(statements, [compileResult.dirWrapperClassVar])[0];
} else {
directiveWrapperClass = jitStatements(
`/${identifierName(moduleMeta.type)}/${identifierName(dirMeta.type)}/wrapper.ngfactory.js`,
statements, compileResult.dirWrapperClassVar);
statements, [compileResult.dirWrapperClassVar])[0];
}
(<ProxyClass>dirMeta.wrapperType).setDelegate(directiveWrapperClass);
this._compiledDirectiveWrapperCache.set(dirMeta.type.reference, directiveWrapperClass);
@ -290,14 +291,18 @@ export class JitCompiler implements Compiler {
.concat(...compiledAnimations.map(ca => ca.statements))
.concat(compileResult.statements);
let viewClass: any;
let componentRenderType: any;
if (!this._compilerConfig.useJit) {
viewClass = interpretStatements(statements, compileResult.viewClassVar);
[viewClass, componentRenderType] = interpretStatements(
statements, [compileResult.viewClassVar, compileResult.componentRenderTypeVar]);
} else {
viewClass = jitStatements(
`/${identifierName(template.ngModule.type)}/${identifierName(template.compType)}/${template.isHost?'host':'component'}.ngfactory.js`,
statements, compileResult.viewClassVar);
const sourceUrl =
`/${identifierName(template.ngModule.type)}/${identifierName(template.compType)}/${template.isHost?'host':'component'}.ngfactory.js`;
[viewClass, componentRenderType] = jitStatements(
sourceUrl, statements,
[compileResult.viewClassVar, compileResult.componentRenderTypeVar]);
}
template.compiled(viewClass);
template.compiled(viewClass, componentRenderType);
}
private _resolveStylesCompileResult(
@ -315,10 +320,10 @@ export class JitCompiler implements Compiler {
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
if (!this._compilerConfig.useJit) {
return interpretStatements(result.statements, result.stylesVar);
return interpretStatements(result.statements, [result.stylesVar])[0];
} else {
return jitStatements(
`/${result.meta.moduleUrl}.ngstyle.js`, result.statements, result.stylesVar);
`/${result.meta.moduleUrl}.ngstyle.js`, result.statements, [result.stylesVar])[0];
}
}
}
@ -332,9 +337,12 @@ class CompiledTemplate {
public compMeta: CompileDirectiveMetadata, public ngModule: CompileNgModuleMetadata,
public directives: CompileIdentifierMetadata[]) {}
compiled(viewClass: Function) {
compiled(viewClass: Function, componentRenderType: any) {
this._viewClass = viewClass;
(<ProxyClass>this.compMeta.componentViewType).setDelegate(viewClass);
for (let prop in componentRenderType) {
(<any>this.compMeta.componentRenderType)[prop] = componentRenderType[prop];
}
this.isCompiled = true;
}
}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef} from '@angular/core';
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, Attribute, ChangeDetectionStrategy, Component, ComponentFactory, ComponentRenderTypeV2, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef} from '@angular/core';
import {StaticSymbol, StaticSymbolCache} from './aot/static_symbol';
import {ngfactoryFilePath} from './aot/util';
@ -131,6 +131,17 @@ export class CompileMetadataResolver {
}
}
private getComponentRenderType(dirType: any): StaticSymbol|ComponentRenderTypeV2 {
if (dirType instanceof StaticSymbol) {
return this._staticSymbolCache.get(
ngfactoryFilePath(dirType.filePath), cpl.componentRenderTypeName(dirType));
} else {
// returning an object as proxy,
// that we fill later during runtime compilation.
return <any>{};
}
}
private getComponentFactory(selector: string, dirType: any): StaticSymbol|ComponentFactory<any> {
if (dirType instanceof StaticSymbol) {
return this._staticSymbolCache.get(
@ -235,6 +246,7 @@ export class CompileMetadataResolver {
entryComponents: metadata.entryComponents,
wrapperType: metadata.wrapperType,
componentViewType: metadata.componentViewType,
componentRenderType: metadata.componentRenderType,
componentFactory: metadata.componentFactory,
template: templateMetadata
});
@ -372,6 +384,8 @@ export class CompileMetadataResolver {
wrapperType: this.getDirectiveWrapperClass(directiveType),
componentViewType: nonNormalizedTemplateMetadata ? this.getComponentViewClass(directiveType) :
undefined,
componentRenderType:
nonNormalizedTemplateMetadata ? this.getComponentRenderType(directiveType) : undefined,
componentFactory: nonNormalizedTemplateMetadata ?
this.getComponentFactory(selector, directiveType) :
undefined

View File

@ -12,8 +12,9 @@ import {isPresent} from '../facade/lang';
import * as o from './output_ast';
import {debugOutputAstAsTypeScript} from './ts_emitter';
export function interpretStatements(statements: o.Statement[], resultVar: string): any {
const stmtsWithReturn = statements.concat([new o.ReturnStatement(o.variable(resultVar))]);
export function interpretStatements(statements: o.Statement[], resultVars: string[]): any[] {
const stmtsWithReturn = statements.concat(
[new o.ReturnStatement(o.literalArr(resultVars.map(resultVar => o.variable(resultVar))))]);
const ctx = new _ExecutionContext(null, null, null, new Map<string, any>());
const visitor = new StatementInterpreter();
const result = visitor.visitAllStatements(stmtsWithReturn, ctx);

View File

@ -13,9 +13,9 @@ import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
import * as o from './output_ast';
function evalExpression(
sourceUrl: string, expr: string, ctx: EmitterVisitorContext, vars: {[key: string]: any}): any {
sourceUrl: string, ctx: EmitterVisitorContext, vars: {[key: string]: any}): any {
const fnBody =
`${ctx.toSource()}\nreturn ${expr}\n//# sourceURL=${sourceUrl}\n${ctx.toSourceMapGenerator().toJsComment()}`;
`${ctx.toSource()}\n//# sourceURL=${sourceUrl}\n${ctx.toSourceMapGenerator().toJsComment()}`;
const fnArgNames: string[] = [];
const fnArgValues: any[] = [];
for (const argName in vars) {
@ -26,11 +26,13 @@ function evalExpression(
}
export function jitStatements(
sourceUrl: string, statements: o.Statement[], resultVar: string): any {
sourceUrl: string, statements: o.Statement[], resultVars: string[]): any[] {
const converter = new JitEmitterVisitor();
const ctx = EmitterVisitorContext.createRoot([resultVar]);
converter.visitAllStatements(statements, ctx);
return evalExpression(sourceUrl, resultVar, ctx, converter.getArgs());
const ctx = EmitterVisitorContext.createRoot(resultVars);
const returnStmt =
new o.ReturnStatement(o.literalArr(resultVars.map(resultVar => o.variable(resultVar))));
converter.visitAllStatements(statements.concat([returnStmt]), ctx);
return evalExpression(sourceUrl, ctx, converter.getArgs());
}
class JitEmitterVisitor extends AbstractJsEmitterVisitor {

View File

@ -7,7 +7,7 @@
*/
import {AnimationEntryCompileResult} from '../animation/animation_compiler';
import {CompileDirectiveMetadata, CompilePipeSummary, tokenName, viewClassName} from '../compile_metadata';
import {CompileDirectiveMetadata, CompilePipeSummary, componentRenderTypeName, tokenName, viewClassName} from '../compile_metadata';
import {EventHandlerVars, LegacyNameResolver} from '../compiler_util/expression_converter';
import {CompilerConfig} from '../config';
import {isPresent} from '../facade/lang';
@ -70,6 +70,7 @@ export class CompileView implements LegacyNameResolver {
public pipes: CompilePipe[] = [];
public locals = new Map<string, o.Expression>();
public className: string;
public renderComponentTypeName: string;
public classType: o.Type;
public classExpr: o.ReadVarExpr;
@ -102,6 +103,7 @@ export class CompileView implements LegacyNameResolver {
this.viewType = getViewType(component, viewIndex);
this.className = viewClassName(component.type.reference, viewIndex);
this.renderComponentTypeName = componentRenderTypeName(component.type.reference);
this.classType = o.expressionType(o.variable(this.className));
this.classExpr = o.variable(this.className);
if (this.viewType === ViewType.COMPONENT || this.viewType === ViewType.HOST) {

View File

@ -386,7 +386,7 @@ function createViewTopLevelStmts(view: CompileView, targetStatements: o.Statemen
const renderCompTypeVar: o.ReadVarExpr =
o.variable(`renderType_${identifierName(view.component.type)}`); // fix highlighting: `
o.variable(view.renderComponentTypeName); // fix highlighting: `
if (view.viewIndex === 0) {
let templateUrlInfo: string;
if (view.component.template.templateUrl == identifierModuleUrl(view.component.type)) {

View File

@ -25,6 +25,7 @@ export {ComponentFactoryDependency, ComponentViewDependency, DirectiveWrapperDep
export class ViewCompileResult {
constructor(
public statements: o.Statement[], public viewClassVar: string,
public componentRenderTypeVar: string,
public dependencies:
Array<ComponentViewDependency|ComponentFactoryDependency|DirectiveWrapperDependency>) {}
}
@ -50,6 +51,7 @@ export class ViewCompiler {
bindView(view, template, this._schemaRegistry);
finishView(view, statements);
return new ViewCompileResult(statements, view.classExpr.name, dependencies);
return new ViewCompileResult(
statements, view.classExpr.name, view.renderComponentTypeName, dependencies);
}
}

View File

@ -6,10 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ChangeDetectionStrategy} from '@angular/core';
import {ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';
import {AnimationEntryCompileResult} from '../animation/animation_compiler';
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileProviderMetadata, CompileTokenMetadata, CompileTypeMetadata, identifierModuleUrl, identifierName, tokenReference} from '../compile_metadata';
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileProviderMetadata, CompileTokenMetadata, CompileTypeMetadata, componentRenderTypeName, identifierModuleUrl, identifierName, tokenReference, viewClassName} from '../compile_metadata';
import {BuiltinConverter, BuiltinConverterFactory, EventHandlerVars, LocalResolver, convertActionBinding, convertPropertyBinding, convertPropertyBindingBuiltins} from '../compiler_util/expression_converter';
import {CompilerConfig} from '../config';
import {AST, ASTWithSource, Interpolation} from '../expression_parser/ast';
@ -20,7 +20,6 @@ import {convertValueToOutputAst} from '../output/value_util';
import {LifecycleHooks, viewEngine} from '../private_import_core';
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAst, ProviderAstType, QueryMatch, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast';
import {ViewEncapsulationEnum} from '../view_compiler/constants';
import {ComponentFactoryDependency, ComponentViewDependency, DirectiveWrapperDependency, ViewCompileResult, ViewCompiler} from '../view_compiler/view_compiler';
const CLASS_ATTR = 'class';
@ -44,19 +43,33 @@ export class ViewCompilerNext extends ViewCompiler {
let embeddedViewCount = 0;
const staticQueryIds = findStaticQueryIds(template);
const statements: o.Statement[] = [];
const renderComponentVar = o.variable(componentRenderTypeName(component.type.reference));
statements.push(
renderComponentVar
.set(o.importExpr(createIdentifier(Identifiers.createComponentRenderTypeV2)).callFn([
new o.LiteralMapExpr([
new o.LiteralMapEntry('encapsulation', o.literal(component.template.encapsulation)),
new o.LiteralMapEntry('styles', styles),
// TODO: copy this from the @Component directive...
new o.LiteralMapEntry('data', o.literalMap([])),
])
]))
.toDeclStmt());
const viewBuilderFactory = (parent: ViewBuilder): ViewBuilder => {
const embeddedViewIndex = embeddedViewCount++;
const viewName = `view_${compName}_${embeddedViewIndex}`;
const viewName = viewClassName(component.type.reference, embeddedViewIndex);
return new ViewBuilder(parent, viewName, usedPipes, staticQueryIds, viewBuilderFactory);
};
const visitor = viewBuilderFactory(null);
visitor.visitAll([], template);
const statements: o.Statement[] = [];
statements.push(...visitor.build(component));
return new ViewCompileResult(statements, visitor.viewName, []);
return new ViewCompileResult(statements, visitor.viewName, renderComponentVar.name, []);
}
}
@ -458,9 +471,11 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver, BuiltinConverter
}
});
let compRenderType = o.NULL_EXPR;
let compView = o.NULL_EXPR;
if (directiveAst.directive.isComponent) {
compView = o.importExpr({reference: directiveAst.directive.componentViewType});
compRenderType = o.importExpr({reference: directiveAst.directive.componentRenderType});
}
const inputDefs = directiveAst.inputs.map((inputAst, inputIndex) => {
@ -507,7 +522,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver, BuiltinConverter
o.literal(flags), queryMatchExprs.length ? o.literalArr(queryMatchExprs) : o.NULL_EXPR,
o.literal(childCount), providerExpr, depsExpr,
inputDefs.length ? new o.LiteralMapExpr(inputDefs) : o.NULL_EXPR,
outputDefs.length ? new o.LiteralMapExpr(outputDefs) : o.NULL_EXPR, compView
outputDefs.length ? new o.LiteralMapExpr(outputDefs) : o.NULL_EXPR, compView, compRenderType
]);
this.nodeDefs[nodeIndex] = nodeDef;