Skip to content

Commit 0fa3895

Browse files
tboschIgorMinar
authored andcommitted
feat(compiler): implement style encapsulation for new view engine (angular#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 angular#14013
1 parent ba17dcb commit 0fa3895

38 files changed

+816
-583
lines changed

modules/@angular/compiler/src/aot/compiler.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,12 @@ export class AotCompiler {
101101
});
102102

103103
// compile components
104+
const compViewVars = this._compileComponent(
105+
compMeta, ngModule, ngModule.transitiveModule.directives,
106+
stylesCompileResults.componentStylesheet, fileSuffix, statements);
104107
exportedVars.push(
105108
this._compileComponentFactory(compMeta, ngModule, fileSuffix, statements),
106-
this._compileComponent(
107-
compMeta, ngModule, ngModule.transitiveModule.directives,
108-
stylesCompileResults.componentStylesheet, fileSuffix, statements));
109+
compViewVars.viewClassVar, compViewVars.compRenderTypeVar);
109110
});
110111
if (statements.length > 0) {
111112
const srcModule = this._codegenSourceModule(
@@ -175,8 +176,10 @@ export class AotCompiler {
175176
const hostType = this._metadataResolver.getHostComponentType(compMeta.type.reference);
176177
const hostMeta = createHostComponentMeta(
177178
hostType, compMeta, this._metadataResolver.getHostComponentViewClass(hostType));
178-
const hostViewFactoryVar = this._compileComponent(
179-
hostMeta, ngModule, [compMeta.type], null, fileSuffix, targetStatements);
179+
const hostViewFactoryVar =
180+
this._compileComponent(
181+
hostMeta, ngModule, [compMeta.type], null, fileSuffix, targetStatements)
182+
.viewClassVar;
180183
const compFactoryVar = componentFactoryName(compMeta.type.reference);
181184
targetStatements.push(
182185
o.variable(compFactoryVar)
@@ -198,7 +201,8 @@ export class AotCompiler {
198201
private _compileComponent(
199202
compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata,
200203
directiveIdentifiers: CompileIdentifierMetadata[], componentStyles: CompiledStylesheet,
201-
fileSuffix: string, targetStatements: o.Statement[]): string {
204+
fileSuffix: string,
205+
targetStatements: o.Statement[]): {viewClassVar: string, compRenderTypeVar: string} {
202206
const parsedAnimations = this._animationParser.parseComponent(compMeta);
203207
const directives =
204208
directiveIdentifiers.map(dir => this._metadataResolver.getDirectiveSummary(dir.reference));
@@ -219,7 +223,10 @@ export class AotCompiler {
219223
}
220224
compiledAnimations.forEach(entry => targetStatements.push(...entry.statements));
221225
targetStatements.push(...viewResult.statements);
222-
return viewResult.viewClassVar;
226+
return {
227+
viewClassVar: viewResult.viewClassVar,
228+
compRenderTypeVar: viewResult.componentRenderTypeVar
229+
};
223230
}
224231

225232
private _codgenStyles(

modules/@angular/compiler/src/compile_metadata.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ChangeDetectionStrategy, ComponentFactory, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core';
9+
import {ChangeDetectionStrategy, ComponentFactory, ComponentRenderTypeV2, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core';
1010

1111
import {StaticSymbol} from './aot/static_symbol';
1212
import {ListWrapper} from './facade/collection';
@@ -15,6 +15,7 @@ import {LifecycleHooks, reflector} from './private_import_core';
1515
import {CssSelector} from './selector';
1616
import {splitAtColon} from './util';
1717

18+
1819
// group 0: "[prop] or (event) or @trigger"
1920
// group 1: "prop" from "[prop]"
2021
// group 2: "event" from "(event)"
@@ -116,6 +117,10 @@ export function viewClassName(compType: any, embeddedTemplateIndex: number): str
116117
return `View_${identifierName({reference: compType})}_${embeddedTemplateIndex}`;
117118
}
118119

120+
export function componentRenderTypeName(compType: any): string {
121+
return `RenderType_${identifierName({reference: compType})}`;
122+
}
123+
119124
export function hostViewClassName(compType: any): string {
120125
return `HostView_${identifierName({reference: compType})}`;
121126
}
@@ -310,6 +315,7 @@ export interface CompileDirectiveSummary extends CompileTypeSummary {
310315
template: CompileTemplateSummary;
311316
wrapperType: StaticSymbol|ProxyClass;
312317
componentViewType: StaticSymbol|ProxyClass;
318+
componentRenderType: StaticSymbol|ComponentRenderTypeV2;
313319
componentFactory: StaticSymbol|ComponentFactory<any>;
314320
}
315321

@@ -320,7 +326,7 @@ export class CompileDirectiveMetadata {
320326
static create(
321327
{isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
322328
providers, viewProviders, queries, viewQueries, entryComponents, template, wrapperType,
323-
componentViewType, componentFactory}: {
329+
componentViewType, componentRenderType, componentFactory}: {
324330
isHost?: boolean,
325331
type?: CompileTypeMetadata,
326332
isComponent?: boolean,
@@ -338,6 +344,7 @@ export class CompileDirectiveMetadata {
338344
template?: CompileTemplateMetadata,
339345
wrapperType?: StaticSymbol|ProxyClass,
340346
componentViewType?: StaticSymbol|ProxyClass,
347+
componentRenderType?: StaticSymbol|ComponentRenderTypeV2,
341348
componentFactory?: StaticSymbol|ComponentFactory<any>,
342349
} = {}): CompileDirectiveMetadata {
343350
const hostListeners: {[key: string]: string} = {};
@@ -392,6 +399,7 @@ export class CompileDirectiveMetadata {
392399
template,
393400
wrapperType,
394401
componentViewType,
402+
componentRenderType,
395403
componentFactory,
396404
});
397405
}
@@ -416,12 +424,14 @@ export class CompileDirectiveMetadata {
416424

417425
wrapperType: StaticSymbol|ProxyClass;
418426
componentViewType: StaticSymbol|ProxyClass;
427+
componentRenderType: StaticSymbol|ComponentRenderTypeV2;
419428
componentFactory: StaticSymbol|ComponentFactory<any>;
420429

421430
constructor({isHost, type, isComponent, selector, exportAs,
422431
changeDetection, inputs, outputs, hostListeners, hostProperties,
423432
hostAttributes, providers, viewProviders, queries, viewQueries,
424-
entryComponents, template, wrapperType, componentViewType, componentFactory}: {
433+
entryComponents, template, wrapperType, componentViewType, componentRenderType,
434+
componentFactory}: {
425435
isHost?: boolean,
426436
type?: CompileTypeMetadata,
427437
isComponent?: boolean,
@@ -441,6 +451,7 @@ export class CompileDirectiveMetadata {
441451
template?: CompileTemplateMetadata,
442452
wrapperType?: StaticSymbol|ProxyClass,
443453
componentViewType?: StaticSymbol|ProxyClass,
454+
componentRenderType?: StaticSymbol|ComponentRenderTypeV2,
444455
componentFactory?: StaticSymbol|ComponentFactory<any>,
445456
} = {}) {
446457
this.isHost = !!isHost;
@@ -463,6 +474,7 @@ export class CompileDirectiveMetadata {
463474

464475
this.wrapperType = wrapperType;
465476
this.componentViewType = componentViewType;
477+
this.componentRenderType = componentRenderType;
466478
this.componentFactory = componentFactory;
467479
}
468480

@@ -487,6 +499,7 @@ export class CompileDirectiveMetadata {
487499
template: this.template && this.template.toSummary(),
488500
wrapperType: this.wrapperType,
489501
componentViewType: this.componentViewType,
502+
componentRenderType: this.componentRenderType,
490503
componentFactory: this.componentFactory
491504
};
492505
}
@@ -521,7 +534,9 @@ export function createHostComponentMeta(
521534
viewProviders: [],
522535
queries: [],
523536
viewQueries: [],
524-
componentViewType: hostViewType
537+
componentViewType: hostViewType,
538+
componentRenderType:
539+
{id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}}
525540
});
526541
}
527542

modules/@angular/compiler/src/identifiers.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
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';
9+
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';
1010

1111
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
1212

@@ -380,6 +380,12 @@ export class Identifiers {
380380
member: 'unwrapValue',
381381
runtime: ɵviewEngine.unwrapValue
382382
};
383+
static createComponentRenderTypeV2: IdentifierSpec = {
384+
name: 'ɵviewEngine',
385+
moduleUrl: CORE,
386+
member: 'createComponentRenderTypeV2',
387+
runtime: ɵviewEngine.createComponentRenderTypeV2
388+
};
383389
}
384390

385391
export function assetUrl(pkg: string, path: string = null, type: string = 'src'): string {

modules/@angular/compiler/src/jit/compiler.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Compiler, ComponentFactory, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type} from '@angular/core';
9+
import {Compiler, ComponentFactory, ComponentRenderTypeV2, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type} from '@angular/core';
1010

1111
import {AnimationCompiler} from '../animation/animation_compiler';
1212
import {AnimationParser} from '../animation/animation_parser';
@@ -133,11 +133,11 @@ export class JitCompiler implements Compiler {
133133
const compileResult = this._ngModuleCompiler.compile(moduleMeta, extraProviders);
134134
if (!this._compilerConfig.useJit) {
135135
ngModuleFactory =
136-
interpretStatements(compileResult.statements, compileResult.ngModuleFactoryVar);
136+
interpretStatements(compileResult.statements, [compileResult.ngModuleFactoryVar])[0];
137137
} else {
138138
ngModuleFactory = jitStatements(
139139
`/${identifierName(moduleMeta.type)}/module.ngfactory.js`, compileResult.statements,
140-
compileResult.ngModuleFactoryVar);
140+
[compileResult.ngModuleFactoryVar])[0];
141141
}
142142
this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
143143
}
@@ -252,11 +252,12 @@ export class JitCompiler implements Compiler {
252252
const statements = compileResult.statements;
253253
let directiveWrapperClass: any;
254254
if (!this._compilerConfig.useJit) {
255-
directiveWrapperClass = interpretStatements(statements, compileResult.dirWrapperClassVar);
255+
directiveWrapperClass =
256+
interpretStatements(statements, [compileResult.dirWrapperClassVar])[0];
256257
} else {
257258
directiveWrapperClass = jitStatements(
258259
`/${identifierName(moduleMeta.type)}/${identifierName(dirMeta.type)}/wrapper.ngfactory.js`,
259-
statements, compileResult.dirWrapperClassVar);
260+
statements, [compileResult.dirWrapperClassVar])[0];
260261
}
261262
(<ProxyClass>dirMeta.wrapperType).setDelegate(directiveWrapperClass);
262263
this._compiledDirectiveWrapperCache.set(dirMeta.type.reference, directiveWrapperClass);
@@ -290,14 +291,18 @@ export class JitCompiler implements Compiler {
290291
.concat(...compiledAnimations.map(ca => ca.statements))
291292
.concat(compileResult.statements);
292293
let viewClass: any;
294+
let componentRenderType: any;
293295
if (!this._compilerConfig.useJit) {
294-
viewClass = interpretStatements(statements, compileResult.viewClassVar);
296+
[viewClass, componentRenderType] = interpretStatements(
297+
statements, [compileResult.viewClassVar, compileResult.componentRenderTypeVar]);
295298
} else {
296-
viewClass = jitStatements(
297-
`/${identifierName(template.ngModule.type)}/${identifierName(template.compType)}/${template.isHost?'host':'component'}.ngfactory.js`,
298-
statements, compileResult.viewClassVar);
299+
const sourceUrl =
300+
`/${identifierName(template.ngModule.type)}/${identifierName(template.compType)}/${template.isHost?'host':'component'}.ngfactory.js`;
301+
[viewClass, componentRenderType] = jitStatements(
302+
sourceUrl, statements,
303+
[compileResult.viewClassVar, compileResult.componentRenderTypeVar]);
299304
}
300-
template.compiled(viewClass);
305+
template.compiled(viewClass, componentRenderType);
301306
}
302307

303308
private _resolveStylesCompileResult(
@@ -315,10 +320,10 @@ export class JitCompiler implements Compiler {
315320
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
316321
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
317322
if (!this._compilerConfig.useJit) {
318-
return interpretStatements(result.statements, result.stylesVar);
323+
return interpretStatements(result.statements, [result.stylesVar])[0];
319324
} else {
320325
return jitStatements(
321-
`/${result.meta.moduleUrl}.ngstyle.js`, result.statements, result.stylesVar);
326+
`/${result.meta.moduleUrl}.ngstyle.js`, result.statements, [result.stylesVar])[0];
322327
}
323328
}
324329
}
@@ -332,9 +337,12 @@ class CompiledTemplate {
332337
public compMeta: CompileDirectiveMetadata, public ngModule: CompileNgModuleMetadata,
333338
public directives: CompileIdentifierMetadata[]) {}
334339

335-
compiled(viewClass: Function) {
340+
compiled(viewClass: Function, componentRenderType: any) {
336341
this._viewClass = viewClass;
337342
(<ProxyClass>this.compMeta.componentViewType).setDelegate(viewClass);
343+
for (let prop in componentRenderType) {
344+
(<any>this.compMeta.componentRenderType)[prop] = componentRenderType[prop];
345+
}
338346
this.isCompiled = true;
339347
}
340348
}

modules/@angular/compiler/src/metadata_resolver.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
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';
9+
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';
1010

1111
import {StaticSymbol, StaticSymbolCache} from './aot/static_symbol';
1212
import {ngfactoryFilePath} from './aot/util';
@@ -131,6 +131,17 @@ export class CompileMetadataResolver {
131131
}
132132
}
133133

134+
private getComponentRenderType(dirType: any): StaticSymbol|ComponentRenderTypeV2 {
135+
if (dirType instanceof StaticSymbol) {
136+
return this._staticSymbolCache.get(
137+
ngfactoryFilePath(dirType.filePath), cpl.componentRenderTypeName(dirType));
138+
} else {
139+
// returning an object as proxy,
140+
// that we fill later during runtime compilation.
141+
return <any>{};
142+
}
143+
}
144+
134145
private getComponentFactory(selector: string, dirType: any): StaticSymbol|ComponentFactory<any> {
135146
if (dirType instanceof StaticSymbol) {
136147
return this._staticSymbolCache.get(
@@ -235,6 +246,7 @@ export class CompileMetadataResolver {
235246
entryComponents: metadata.entryComponents,
236247
wrapperType: metadata.wrapperType,
237248
componentViewType: metadata.componentViewType,
249+
componentRenderType: metadata.componentRenderType,
238250
componentFactory: metadata.componentFactory,
239251
template: templateMetadata
240252
});
@@ -372,6 +384,8 @@ export class CompileMetadataResolver {
372384
wrapperType: this.getDirectiveWrapperClass(directiveType),
373385
componentViewType: nonNormalizedTemplateMetadata ? this.getComponentViewClass(directiveType) :
374386
undefined,
387+
componentRenderType:
388+
nonNormalizedTemplateMetadata ? this.getComponentRenderType(directiveType) : undefined,
375389
componentFactory: nonNormalizedTemplateMetadata ?
376390
this.getComponentFactory(selector, directiveType) :
377391
undefined

modules/@angular/compiler/src/output/output_interpreter.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import {isPresent} from '../facade/lang';
1212
import * as o from './output_ast';
1313
import {debugOutputAstAsTypeScript} from './ts_emitter';
1414

15-
export function interpretStatements(statements: o.Statement[], resultVar: string): any {
16-
const stmtsWithReturn = statements.concat([new o.ReturnStatement(o.variable(resultVar))]);
15+
export function interpretStatements(statements: o.Statement[], resultVars: string[]): any[] {
16+
const stmtsWithReturn = statements.concat(
17+
[new o.ReturnStatement(o.literalArr(resultVars.map(resultVar => o.variable(resultVar))))]);
1718
const ctx = new _ExecutionContext(null, null, null, new Map<string, any>());
1819
const visitor = new StatementInterpreter();
1920
const result = visitor.visitAllStatements(stmtsWithReturn, ctx);

modules/@angular/compiler/src/output/output_jit.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
1313
import * as o from './output_ast';
1414

1515
function evalExpression(
16-
sourceUrl: string, expr: string, ctx: EmitterVisitorContext, vars: {[key: string]: any}): any {
16+
sourceUrl: string, ctx: EmitterVisitorContext, vars: {[key: string]: any}): any {
1717
const fnBody =
18-
`${ctx.toSource()}\nreturn ${expr}\n//# sourceURL=${sourceUrl}\n${ctx.toSourceMapGenerator().toJsComment()}`;
18+
`${ctx.toSource()}\n//# sourceURL=${sourceUrl}\n${ctx.toSourceMapGenerator().toJsComment()}`;
1919
const fnArgNames: string[] = [];
2020
const fnArgValues: any[] = [];
2121
for (const argName in vars) {
@@ -26,11 +26,13 @@ function evalExpression(
2626
}
2727

2828
export function jitStatements(
29-
sourceUrl: string, statements: o.Statement[], resultVar: string): any {
29+
sourceUrl: string, statements: o.Statement[], resultVars: string[]): any[] {
3030
const converter = new JitEmitterVisitor();
31-
const ctx = EmitterVisitorContext.createRoot([resultVar]);
32-
converter.visitAllStatements(statements, ctx);
33-
return evalExpression(sourceUrl, resultVar, ctx, converter.getArgs());
31+
const ctx = EmitterVisitorContext.createRoot(resultVars);
32+
const returnStmt =
33+
new o.ReturnStatement(o.literalArr(resultVars.map(resultVar => o.variable(resultVar))));
34+
converter.visitAllStatements(statements.concat([returnStmt]), ctx);
35+
return evalExpression(sourceUrl, ctx, converter.getArgs());
3436
}
3537

3638
class JitEmitterVisitor extends AbstractJsEmitterVisitor {

0 commit comments

Comments
 (0)