-
Notifications
You must be signed in to change notification settings - Fork 25.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(compiler): integrate compiler with view engine - hello world
Part of #14013
- Loading branch information
Showing
25 changed files
with
419 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Compiler Integration for new View Engine | ||
|
||
This folder contains the code to integrate the compiler with the new view engine. | ||
|
||
Note: This is work in progress, and once complete will replace the regular view_compiler folder. |
181 changes: 181 additions & 0 deletions
181
modules/@angular/compiler/src/view_compiler_next/view_compiler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/** | ||
* @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 {AnimationEntryCompileResult} from '../animation/animation_compiler'; | ||
import {CompileDirectiveMetadata, CompilePipeSummary, identifierModuleUrl, identifierName} from '../compile_metadata'; | ||
import {convertPropertyBinding} from '../compiler_util/expression_converter'; | ||
import {CompilerConfig} from '../config'; | ||
import {ASTWithSource, Interpolation} from '../expression_parser/ast'; | ||
import {Identifiers, createIdentifier} from '../identifiers'; | ||
import {CompilerInjectable} from '../injectable'; | ||
import * as o from '../output/output_ast'; | ||
import {viewEngine} from '../private_import_core'; | ||
import {ElementSchemaRegistry} from '../schema/element_schema_registry'; | ||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, 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'; | ||
|
||
@CompilerInjectable() | ||
export class ViewCompilerNext extends ViewCompiler { | ||
constructor( | ||
private _genConfigNext: CompilerConfig, private _schemaRegistryNext: ElementSchemaRegistry) { | ||
super(_genConfigNext, _schemaRegistryNext); | ||
} | ||
|
||
compileComponent( | ||
component: CompileDirectiveMetadata, template: TemplateAst[], styles: o.Expression, | ||
pipes: CompilePipeSummary[], | ||
compiledAnimations: AnimationEntryCompileResult[]): ViewCompileResult { | ||
const visitor = new ViewBuilderVisitor(); | ||
templateVisitAll(visitor, template); | ||
|
||
const statements: o.Statement[] = []; | ||
const compName = identifierName(component.type) + (component.isHost ? `_Host` : ''); | ||
const viewName = `view_${compName}`; | ||
|
||
const renderCompTypeName = `renderType_${compName}`; | ||
statements.push( | ||
createRenderComponentType(renderCompTypeName, component, styles, compiledAnimations)); | ||
const renderCompType = o.variable(renderCompTypeName); | ||
statements.push(...visitor.build(viewName, o.importType(component.type), renderCompType)); | ||
|
||
return new ViewCompileResult(statements, viewName, []); | ||
} | ||
} | ||
|
||
function createRenderComponentType( | ||
renderCompTypeName: string, component: CompileDirectiveMetadata, styles: o.Expression, | ||
animations: AnimationEntryCompileResult[]): o.Statement { | ||
const compName = identifierName(component.type); | ||
const compFilePath = identifierModuleUrl(component.type); | ||
const renderCompTypeVar: o.ReadVarExpr = o.variable(renderCompTypeName); | ||
return renderCompTypeVar | ||
.set(o.importExpr(createIdentifier(Identifiers.createRenderComponentType)).callFn([ | ||
o.literal(''), | ||
o.literal(component.template.ngContentSelectors.length), | ||
ViewEncapsulationEnum.fromValue(component.template.encapsulation), | ||
styles, | ||
o.literalMap( | ||
animations.map((entry): [string, o.Expression] => [entry.name, entry.fnExp]), null, | ||
true), | ||
])) | ||
.toDeclStmt(o.importType(createIdentifier(Identifiers.RenderComponentType))); | ||
} | ||
|
||
const VIEW_VAR = o.variable('view'); | ||
const COMP_VAR = o.variable('comp'); | ||
|
||
class ViewBuilderVisitor implements TemplateAstVisitor { | ||
private nodeDefs: o.Expression[] = []; | ||
private updateStmts: o.Statement[] = []; | ||
private bindingCount = 0; | ||
private nodeCount = 0; | ||
|
||
build(viewName: string, compType: o.Type, renderCompType: o.Expression): o.Statement[] { | ||
const viewFlags = 0; | ||
let updateFn: o.Expression; | ||
if (this.updateStmts.length > 0) { | ||
updateFn = o.fn( | ||
[new o.FnParam(VIEW_VAR.name)], | ||
[COMP_VAR.set(VIEW_VAR.prop('component')).toDeclStmt(compType), ...this.updateStmts]); | ||
} else { | ||
updateFn = o.NULL_EXPR; | ||
} | ||
const handleEventFn = o.NULL_EXPR; | ||
const viewFactory = new o.DeclareFunctionStmt( | ||
viewName, [], | ||
[new o.ReturnStatement(o.importExpr(createIdentifier(Identifiers.viewDef)).callFn([ | ||
o.literal(viewFlags), o.literalArr(this.nodeDefs.slice().reverse()), updateFn, | ||
handleEventFn, renderCompType | ||
]))]); | ||
|
||
return [viewFactory]; | ||
} | ||
|
||
visitNgContent(ast: NgContentAst, context: any): any {} | ||
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any {} | ||
visitElement(ast: ElementAst, context: any): any { | ||
// elementDef( | ||
// flags: NodeFlags, matchedQueries: [string, QueryValueType][], ngContentIndex: number, | ||
// childCount: number, name: string, fixedAttrs: {[name: string]: string} = {}, | ||
// bindings?: | ||
// ([BindingType.ElementClass, string] | [BindingType.ElementStyle, string, string] | | ||
// [BindingType.ElementAttribute | BindingType.ElementProperty, string, | ||
// SecurityContext])[], | ||
// outputs?: (string | [string, string])[]): NodeDef; | ||
const nodeIndex = this.nodeCount++; | ||
templateVisitAll(this, ast.directives); | ||
templateVisitAll(this, ast.children); | ||
const childCount = this.nodeCount - nodeIndex - 1; | ||
|
||
const flags = o.literal(0); | ||
const fixedAttrs = o.literalMap([]); | ||
this.nodeDefs.push(o.importExpr(createIdentifier(Identifiers.elementDef)).callFn([ | ||
flags, o.NULL_EXPR, o.NULL_EXPR, o.literal(childCount), o.literal(ast.name), fixedAttrs | ||
])); | ||
} | ||
visitReference(ast: ReferenceAst, context: any): any {} | ||
visitVariable(ast: VariableAst, context: any): any {} | ||
visitEvent(ast: BoundEventAst, context: any): any {} | ||
visitElementProperty(ast: BoundElementPropertyAst, context: any): any {} | ||
visitAttr(ast: AttrAst, context: any): any {} | ||
visitBoundText(ast: BoundTextAst, context: any): any { | ||
const nodeIndex = this.nodeCount++; | ||
const astWithSource = <ASTWithSource>ast.value; | ||
const inter = <Interpolation>astWithSource.ast; | ||
this.updateStmts.push(o.importExpr(createIdentifier(Identifiers.setCurrentNode)) | ||
.callFn([o.variable('view'), o.literal(nodeIndex)]) | ||
.toStmt()); | ||
const exprs = inter.expressions.map((expr) => { | ||
const bindingId = `bind_${this.bindingCount++}`; | ||
const converted = convertPropertyBinding(null, null, COMP_VAR, expr, bindingId); | ||
this.updateStmts.push(...converted.stmts); | ||
return converted.currValExpr; | ||
}); | ||
if (exprs.length > 10) { | ||
this.updateStmts.push(o.importExpr(createIdentifier(Identifiers.checkNodeDynamic)) | ||
.callFn([o.literalArr(exprs)]) | ||
.toStmt()); | ||
} else { | ||
this.updateStmts.push( | ||
o.importExpr(createIdentifier(Identifiers.checkNodeInline)).callFn(exprs).toStmt()); | ||
} | ||
|
||
// textDef(ngContentIndex: number, constants: string[]): NodeDef; | ||
this.nodeDefs.push(o.importExpr(createIdentifier(Identifiers.textDef)).callFn([ | ||
o.NULL_EXPR, o.literalArr(inter.strings.map(s => o.literal(s))) | ||
])); | ||
} | ||
visitText(ast: TextAst, context: any): any { | ||
this.nodeCount++; | ||
// textDef(ngContentIndex: number, constants: string[]): NodeDef; | ||
this.nodeDefs.push(o.importExpr(createIdentifier(Identifiers.textDef)).callFn([ | ||
o.NULL_EXPR, o.literalArr([o.literal(ast.value)]) | ||
])); | ||
} | ||
visitDirective(ast: DirectiveAst, context: any): any { | ||
this.nodeCount++; | ||
const flags = 0; | ||
const childCount = 0; | ||
const deps: o.Expression[] = []; | ||
let compView = o.NULL_EXPR; | ||
if (ast.directive.isComponent) { | ||
compView = o.importExpr({reference: ast.directive.componentViewType}); | ||
} | ||
// directiveDef( | ||
// flags: NodeFlags, matchedQueries: [string, QueryValueType][], childCount: number, ctor: | ||
// any, | ||
// deps: ([DepFlags, any] | any)[], props?: {[name: string]: [number, string]}, | ||
// outputs?: {[name: string]: string}, component?: () => ViewDefinition): NodeDef; | ||
this.nodeDefs.push(o.importExpr(createIdentifier(Identifiers.directiveDef)).callFn([ | ||
o.literal(flags), o.NULL_EXPR, o.literal(childCount), o.importExpr(ast.directive.type), | ||
o.literalArr(deps), o.NULL_EXPR, o.NULL_EXPR, compView | ||
])); | ||
} | ||
visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.