diff --git a/packages/compiler/src/aot/compiler.ts b/packages/compiler/src/aot/compiler.ts index 8c11916130..4bfc4004b6 100644 --- a/packages/compiler/src/aot/compiler.ts +++ b/packages/compiler/src/aot/compiler.ts @@ -22,7 +22,6 @@ import * as o from '../output/output_ast'; import {ParseError} from '../parse_util'; import {compileNgModule as compileIvyModule} from '../render3/r3_module_compiler'; import {compilePipe as compileIvyPipe} from '../render3/r3_pipe_compiler'; -import {OutputMode} from '../render3/r3_types'; import {compileComponent as compileIvyComponent, compileDirective as compileIvyDirective} from '../render3/r3_view_compiler'; import {CompiledStylesheet, StyleCompiler} from '../style_compiler'; import {SummaryResolver} from '../summary_resolver'; @@ -389,17 +388,16 @@ export class AotCompiler { this._parseTemplate(directiveMetadata, module, module.transitiveModule.directives); compileIvyComponent( context, directiveMetadata, parsedPipes, parsedTemplate, this.reflector, - hostBindingParser, OutputMode.PartialClass); + hostBindingParser); } else { - compileIvyDirective( - context, directiveMetadata, this.reflector, hostBindingParser, OutputMode.PartialClass); + compileIvyDirective(context, directiveMetadata, this.reflector, hostBindingParser); } }); pipes.forEach(pipeType => { const pipeMetadata = this._metadataResolver.getPipeMetadata(pipeType); if (pipeMetadata) { - compileIvyPipe(context, pipeMetadata, this.reflector, OutputMode.PartialClass); + compileIvyPipe(context, pipeMetadata, this.reflector); } }); diff --git a/packages/compiler/src/render3/r3_back_patch_compiler.ts b/packages/compiler/src/render3/r3_back_patch_compiler.ts deleted file mode 100644 index c16db2c41b..0000000000 --- a/packages/compiler/src/render3/r3_back_patch_compiler.ts +++ /dev/null @@ -1,106 +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 {StaticReflector} from '../aot/static_reflector'; -import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeSummary, CompileTypeMetadata} from '../compile_metadata'; -import {DEFAULT_INTERPOLATION_CONFIG, DomElementSchemaRegistry, Lexer, ParseError, Parser} from '../compiler'; -import {CompileMetadataResolver} from '../metadata_resolver'; -import * as o from '../output/output_ast'; -import {BindingParser} from '../template_parser/binding_parser'; -import {TemplateAst} from '../template_parser/template_ast'; -import {OutputContext} from '../util'; - -import {compilePipe} from './r3_pipe_compiler'; -import {BUILD_OPTIMIZER_REMOVE, OutputMode} from './r3_types'; -import {compileComponent, compileDirective} from './r3_view_compiler'; - -export const enum ModuleKind { - Renderer2, - Renderer3, -} - -/** - * Produce the back-patching function for the given module to the output context. - */ -export function compileModuleBackPatch( - outputCtx: OutputContext, name: string, module: CompileNgModuleMetadata, kind: ModuleKind, - backPatchReferenceOf: (module: CompileTypeMetadata) => o.Expression, - parseTemplate: ( - compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata, - directiveIdentifiers: CompileIdentifierMetadata[]) => { - template: TemplateAst[], - pipes: CompilePipeSummary[] - }, - reflector: StaticReflector, resolver: CompileMetadataResolver) { - const imports: o.Statement[] = []; - let statements: o.Statement[] = []; - - // Call dependent back patching - for (const importedModule of module.importedModules) { - const importBackPatchFunction = backPatchReferenceOf(importedModule.type); - - // e.g. // @BUILD_OPTIMIZER_REMOVE - imports.push(new o.CommentStmt(BUILD_OPTIMIZER_REMOVE)); - - // e.g. ngBackPatch_some_other_module_Module(); - imports.push(importBackPatchFunction.callFn([]).toStmt()); - } - - // The local output context allows collecting the back-patch statements that - // are generated by the various compilers which allows putting placing them - // into the body of a function instead of at global scope. - const localCtx: OutputContext = { - statements, - constantPool: outputCtx.constantPool, - genFilePath: outputCtx.genFilePath, - importExpr: outputCtx.importExpr - }; - - // e.g. export function ngBackPatch_some_module_Lib1Module() - if (kind === ModuleKind.Renderer2) { - // For all Renderer2 modules generate back-patching code for all the components, directives, - // pipes, and injectables as well as the injector def for the module itself. - - const expressionParser = new Parser(new Lexer()); - const elementSchemaRegistry = new DomElementSchemaRegistry(); - const errors: ParseError[] = []; - const hostBindingParser = new BindingParser( - expressionParser, DEFAULT_INTERPOLATION_CONFIG, elementSchemaRegistry, [], errors); - - // Back-patch all declared directive and components - for (const declaredDirective of module.declaredDirectives) { - const declaredDirectiveMetadata = resolver.getDirectiveMetadata(declaredDirective.reference); - if (declaredDirectiveMetadata.isComponent) { - const {template: parsedTemplate, pipes: parsedPipes} = - parseTemplate(declaredDirectiveMetadata, module, module.transitiveModule.directives); - compileComponent( - localCtx, declaredDirectiveMetadata, parsedPipes, parsedTemplate, reflector, - hostBindingParser, OutputMode.BackPatch); - } else { - compileDirective( - localCtx, declaredDirectiveMetadata, reflector, hostBindingParser, - OutputMode.BackPatch); - } - } - - // Back-patch all pipes declared in the module. - for (const pipeType of module.declaredPipes) { - const pipeMetadata = resolver.getPipeMetadata(pipeType.reference); - if (pipeMetadata) { - compilePipe(localCtx, pipeMetadata, reflector, OutputMode.BackPatch); - } - } - - if (errors.length) { - throw new Error(errors.map(e => e.toString()).join('\n')); - } - } - - outputCtx.statements.push(new o.DeclareFunctionStmt( - name, [], [...imports, ...statements], o.INFERRED_TYPE, [o.StmtModifier.Exported])); -} diff --git a/packages/compiler/src/render3/r3_pipe_compiler.ts b/packages/compiler/src/render3/r3_pipe_compiler.ts index 6bf26f1563..6f60723caa 100644 --- a/packages/compiler/src/render3/r3_pipe_compiler.ts +++ b/packages/compiler/src/render3/r3_pipe_compiler.ts @@ -13,15 +13,14 @@ import * as o from '../output/output_ast'; import {OutputContext, error} from '../util'; import {Identifiers as R3} from './r3_identifiers'; -import {BUILD_OPTIMIZER_COLOCATE, OutputMode} from './r3_types'; +import {BUILD_OPTIMIZER_COLOCATE} from './r3_types'; import {createFactory} from './r3_view_compiler'; /** * Write a pipe definition to the output context. */ export function compilePipe( - outputCtx: OutputContext, pipe: CompilePipeMetadata, reflector: CompileReflector, - mode: OutputMode) { + outputCtx: OutputContext, pipe: CompilePipeMetadata, reflector: CompileReflector) { const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = []; // e.g. `name: 'myPipe'` @@ -47,25 +46,15 @@ export function compilePipe( const definitionFunction = o.importExpr(R3.definePipe).callFn([o.literalMap(definitionMapValues)]); - if (mode === OutputMode.PartialClass) { - outputCtx.statements.push(new o.ClassStmt( - /* name */ className, - /* parent */ null, - /* fields */[new o.ClassField( - /* name */ definitionField, - /* type */ o.INFERRED_TYPE, - /* modifiers */[o.StmtModifier.Static], - /* initializer */ definitionFunction)], - /* getters */[], - /* constructorMethod */ new o.ClassMethod(null, [], []), - /* methods */[])); - } else { - // Create back-patch definition. - const classReference = outputCtx.importExpr(pipe.type.reference); - - // Create the back-patch statement - outputCtx.statements.push( - new o.CommentStmt(BUILD_OPTIMIZER_COLOCATE), - classReference.prop(definitionField).set(definitionFunction).toStmt()); - } + outputCtx.statements.push(new o.ClassStmt( + /* name */ className, + /* parent */ null, + /* fields */[new o.ClassField( + /* name */ definitionField, + /* type */ o.INFERRED_TYPE, + /* modifiers */[o.StmtModifier.Static], + /* initializer */ definitionFunction)], + /* getters */[], + /* constructorMethod */ new o.ClassMethod(null, [], []), + /* methods */[])); } \ No newline at end of file diff --git a/packages/compiler/src/render3/r3_types.ts b/packages/compiler/src/render3/r3_types.ts index 87f0f1257a..1111f902d4 100644 --- a/packages/compiler/src/render3/r3_types.ts +++ b/packages/compiler/src/render3/r3_types.ts @@ -6,14 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -/** - * The statement mode for the render, either as a class back-patch or as a partial class - */ -export const enum OutputMode { - PartialClass, - BackPatch, -} - /** * Comment to insert above back-patch */ diff --git a/packages/compiler/src/render3/r3_view_compiler.ts b/packages/compiler/src/render3/r3_view_compiler.ts index 662053033f..fdbf069097 100644 --- a/packages/compiler/src/render3/r3_view_compiler.ts +++ b/packages/compiler/src/render3/r3_view_compiler.ts @@ -22,7 +22,7 @@ import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventA import {OutputContext, error} from '../util'; import {Identifiers as R3} from './r3_identifiers'; -import {BUILD_OPTIMIZER_COLOCATE, OutputMode} from './r3_types'; +import {BUILD_OPTIMIZER_COLOCATE} from './r3_types'; /** Name of the context parameter passed into a template function */ @@ -50,7 +50,7 @@ const ID_SEPARATOR = '@@'; export function compileDirective( outputCtx: OutputContext, directive: CompileDirectiveMetadata, reflector: CompileReflector, - bindingParser: BindingParser, mode: OutputMode) { + bindingParser: BindingParser) { const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = []; const field = (key: string, value: o.Expression | null) => { @@ -87,34 +87,24 @@ export function compileDirective( const definitionFunction = o.importExpr(R3.defineDirective).callFn([o.literalMap(definitionMapValues)]); - if (mode === OutputMode.PartialClass) { - // Create the partial class to be merged with the actual class. - outputCtx.statements.push(new o.ClassStmt( - /* name */ className, - /* parent */ null, - /* fields */[new o.ClassField( - /* name */ definitionField, - /* type */ o.INFERRED_TYPE, - /* modifiers */[o.StmtModifier.Static], - /* initializer */ definitionFunction)], - /* getters */[], - /* constructorMethod */ new o.ClassMethod(null, [], []), - /* methods */[])); - } else { - // Create back-patch definition. - const classReference = outputCtx.importExpr(directive.type.reference); - - // Create the back-patch statement - outputCtx.statements.push(new o.CommentStmt(BUILD_OPTIMIZER_COLOCATE)); - outputCtx.statements.push( - classReference.prop(definitionField).set(definitionFunction).toStmt()); - } + // Create the partial class to be merged with the actual class. + outputCtx.statements.push(new o.ClassStmt( + /* name */ className, + /* parent */ null, + /* fields */[new o.ClassField( + /* name */ definitionField, + /* type */ o.INFERRED_TYPE, + /* modifiers */[o.StmtModifier.Static], + /* initializer */ definitionFunction)], + /* getters */[], + /* constructorMethod */ new o.ClassMethod(null, [], []), + /* methods */[])); } export function compileComponent( outputCtx: OutputContext, component: CompileDirectiveMetadata, pipeSummaries: CompilePipeSummary[], template: TemplateAst[], reflector: CompileReflector, - bindingParser: BindingParser, mode: OutputMode) { + bindingParser: BindingParser) { const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = []; // Pipes and Directives found in the template @@ -200,30 +190,21 @@ export function compileComponent( const definitionField = outputCtx.constantPool.propertyNameOf(DefinitionKind.Component); const definitionFunction = o.importExpr(R3.defineComponent).callFn([o.literalMap(definitionMapValues)]); - if (mode === OutputMode.PartialClass) { - const className = identifierName(component.type) !; - className || error(`Cannot resolver the name of ${component.type}`); + const className = identifierName(component.type) !; + className || error(`Cannot resolver the name of ${component.type}`); - // Create the partial class to be merged with the actual class. - outputCtx.statements.push(new o.ClassStmt( - /* name */ className, - /* parent */ null, - /* fields */[new o.ClassField( - /* name */ definitionField, - /* type */ o.INFERRED_TYPE, - /* modifiers */[o.StmtModifier.Static], - /* initializer */ definitionFunction)], - /* getters */[], - /* constructorMethod */ new o.ClassMethod(null, [], []), - /* methods */[])); - } else { - const classReference = outputCtx.importExpr(component.type.reference); - - // Create the back-patch statement - outputCtx.statements.push( - new o.CommentStmt(BUILD_OPTIMIZER_COLOCATE), - classReference.prop(definitionField).set(definitionFunction).toStmt()); - } + // Create the partial class to be merged with the actual class. + outputCtx.statements.push(new o.ClassStmt( + /* name */ className, + /* parent */ null, + /* fields */[new o.ClassField( + /* name */ definitionField, + /* type */ o.INFERRED_TYPE, + /* modifiers */[o.StmtModifier.Static], + /* initializer */ definitionFunction)], + /* getters */[], + /* constructorMethod */ new o.ClassMethod(null, [], []), + /* methods */[])); } // TODO: Remove these when the things are fully supported diff --git a/packages/compiler/test/render3/mock_compile.ts b/packages/compiler/test/render3/mock_compile.ts index 4326d66d3d..b911d87e97 100644 --- a/packages/compiler/test/render3/mock_compile.ts +++ b/packages/compiler/test/render3/mock_compile.ts @@ -6,19 +6,18 @@ * found in the LICENSE file at https://angular.io/license */ -import {AotCompilerHost, AotCompilerOptions, AotSummaryResolver, CompileDirectiveMetadata, CompileIdentifierMetadata, CompileMetadataResolver, CompileNgModuleMetadata, CompilePipeSummary, CompileTypeMetadata, CompilerConfig, DEFAULT_INTERPOLATION_CONFIG, DirectiveNormalizer, DirectiveResolver, DomElementSchemaRegistry, HtmlParser, Lexer, NgModuleResolver, ParseError, Parser, PipeResolver, StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, TemplateParser, TypeScriptEmitter, analyzeNgModules, createAotUrlResolver, templateSourceUrl} from '@angular/compiler'; +import {AotCompilerOptions, AotSummaryResolver, CompileMetadataResolver, CompilerConfig, DEFAULT_INTERPOLATION_CONFIG, DirectiveNormalizer, DirectiveResolver, DomElementSchemaRegistry, HtmlParser, Lexer, NgModuleResolver, ParseError, Parser, PipeResolver, StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, TemplateParser, TypeScriptEmitter, analyzeNgModules, createAotUrlResolver} from '@angular/compiler'; import {ViewEncapsulation} from '@angular/core'; import * as ts from 'typescript'; import {NgAnalyzedModules} from '../../src/aot/compiler'; import {ConstantPool} from '../../src/constant_pool'; -import {ParserError} from '../../src/expression_parser/ast'; +import * as html from '../../src/ml_parser/ast'; +import {removeWhitespaces} from '../../src/ml_parser/html_whitespaces'; import * as o from '../../src/output/output_ast'; -import {ModuleKind, compileModuleBackPatch} from '../../src/render3/r3_back_patch_compiler'; -import {compileModuleFactory} from '../../src/render3/r3_module_factory_compiler'; import {compilePipe} from '../../src/render3/r3_pipe_compiler'; -import {OutputMode} from '../../src/render3/r3_types'; -import {compileComponent, compileDirective} from '../../src/render3/r3_view_compiler'; +import {HtmlToTemplateTransform} from '../../src/render3/r3_template_transform'; +import {compileComponent, compileDirective} from '../../src/render3/r3_view_compiler_local'; import {BindingParser} from '../../src/template_parser/binding_parser'; import {OutputContext, escapeRegExp} from '../../src/util'; import {MockAotCompilerHost, MockCompilerHost, MockData, MockDirectory, arrayToMockDir, expectNoDiagnostics, settings, toMockFileArray} from '../aot/test_util'; @@ -252,9 +251,6 @@ function doCompile( const emitter = new TypeScriptEmitter(); - const moduleName = compilerHost.fileNameToModuleName( - fakeOutputContext.genFilePath, fakeOutputContext.genFilePath); - const result = emitter.emitStatementsAndContext( fakeOutputContext.genFilePath, fakeOutputContext.statements, '', false, /* referenceFilter */ undefined, @@ -294,81 +290,18 @@ export function compile( const parsedTemplate = templateParser.parse( metadata, htmlAst, directives, pipes, module.schemas, fakeUrl, false); compileComponent( - outputCtx, metadata, pipes, parsedTemplate.template, reflector, hostBindingParser, - OutputMode.PartialClass); + outputCtx, metadata, pipes, parsedTemplate.template, reflector, hostBindingParser); } else { compileDirective( - outputCtx, metadata, reflector, hostBindingParser, OutputMode.PartialClass); + outputCtx, metadata, reflector, hostBindingParser); } } else if (resolver.isPipe(pipeOrDirective)) { const metadata = resolver.getPipeMetadata(pipeOrDirective); if (metadata) { - compilePipe(outputCtx, metadata, reflector, OutputMode.PartialClass); + compilePipe(outputCtx, metadata, reflector); } } } }); } - -const DTS = /\.d\.ts$/; -const EXT = /(\.\w+)+$/; -const NONE_WORD = /\W/g; -const NODE_MODULES = /^.*\/node_modules\//; - -function getBackPatchFunctionName(type: CompileTypeMetadata) { - const filePath = (type.reference.filePath as string) - .replace(EXT, '') - .replace(NODE_MODULES, '') - .replace(NONE_WORD, '_'); - return `ngBackPatch_${filePath.split('/').filter(s => !!s).join('_')}_${type.reference.name}`; -} - -function getBackPatchReference(type: CompileTypeMetadata): o.Expression { - return o.variable(getBackPatchFunctionName(type)); -} - -export function backPatch( - data: MockDirectory, angularFiles: MockData, options: AotCompilerOptions = {}, - errorCollector: (error: any, fileName?: string) => void = error => { throw error;}) { - return doCompile( - data, angularFiles, options, errorCollector, - (outputCtx: OutputContext, analyzedModules: NgAnalyzedModules, - resolver: CompileMetadataResolver, htmlParser: HtmlParser, templateParser: TemplateParser, - hostBindingParser: BindingParser, reflector: StaticReflector) => { - - const parseTemplate = - (compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata, - directiveIdentifiers: CompileIdentifierMetadata[]) => { - const directives = - directiveIdentifiers.map(dir => resolver.getDirectiveSummary(dir.reference)); - const pipes = ngModule.transitiveModule.pipes.map( - pipe => resolver.getPipeSummary(pipe.reference)); - return templateParser.parse( - compMeta, compMeta.template !.htmlAst !, directives, pipes, ngModule.schemas, - templateSourceUrl(ngModule.type, compMeta, compMeta.template !), true); - }; - - for (const module of analyzedModules.ngModules) { - compileModuleBackPatch( - outputCtx, getBackPatchFunctionName(module.type), module, - DTS.test(module.type.reference.filePath) ? ModuleKind.Renderer2 : - ModuleKind.Renderer3, - getBackPatchReference, parseTemplate, reflector, resolver); - } - }); -} - -export function createFactories( - data: MockDirectory, context: MockData, options: AotCompilerOptions = {}, - errorCollector: (error: any, fileName?: string) => void = error => { throw error;}) { - return doCompile( - data, context, options, errorCollector, - (outputCtx: OutputContext, analyzedModules: NgAnalyzedModules, - resolver: CompileMetadataResolver, htmlParser: HtmlParser, templateParser: TemplateParser, - hostBindingParser: BindingParser, reflector: StaticReflector) => { - for (const module of analyzedModules.ngModules) { - compileModuleFactory(outputCtx, module, getBackPatchReference, resolver); - } - }); -} diff --git a/packages/compiler/test/render3/r3_back_patch_compiler_spec.ts b/packages/compiler/test/render3/r3_back_patch_compiler_spec.ts deleted file mode 100644 index 4c34089180..0000000000 --- a/packages/compiler/test/render3/r3_back_patch_compiler_spec.ts +++ /dev/null @@ -1,218 +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 {MockDirectory, emitLibrary, mergeMaps, setup} from '../aot/test_util'; - -import {backPatch, expectEmit} from './mock_compile'; - -describe('r3_back_patch_compiler', () => { - const angularFiles = setup({ - compileAngular: true, - compileAnimations: false, - compileCommon: true, - }); - - it('should back-patch a component in a library', () => { - const libraries = { - lib1: { - src: { - 'component.ts': ` - import {Component} from '@angular/core'; - - @Component({ - selector: 'lib1-cmp', - template: '