@angular/compiler
Version:
Angular - the compiler library
780 lines (779 loc) • 160 kB
JavaScript
/**
* @license
* Copyright Google LLC 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
*/
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define("@angular/compiler/src/aot/compiler", ["require", "exports", "tslib", "@angular/compiler/src/compile_metadata", "@angular/compiler/src/constant_pool", "@angular/compiler/src/core", "@angular/compiler/src/i18n/message_bundle", "@angular/compiler/src/identifiers", "@angular/compiler/src/ml_parser/html_parser", "@angular/compiler/src/ml_parser/html_whitespaces", "@angular/compiler/src/ml_parser/interpolation_config", "@angular/compiler/src/output/output_ast", "@angular/compiler/src/render3/r3_module_compiler", "@angular/compiler/src/render3/r3_pipe_compiler", "@angular/compiler/src/render3/r3_template_transform", "@angular/compiler/src/render3/view/compiler", "@angular/compiler/src/schema/dom_element_schema_registry", "@angular/compiler/src/template_parser/binding_parser", "@angular/compiler/src/util", "@angular/compiler/src/aot/generated_file", "@angular/compiler/src/aot/lazy_routes", "@angular/compiler/src/aot/static_symbol", "@angular/compiler/src/aot/summary_serializer", "@angular/compiler/src/aot/util"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeAnalyzedFiles = exports.analyzeFileForInjectables = exports.analyzeFile = exports.analyzeAndValidateNgModules = exports.analyzeNgModules = exports.AotCompiler = void 0;
var tslib_1 = require("tslib");
var compile_metadata_1 = require("@angular/compiler/src/compile_metadata");
var constant_pool_1 = require("@angular/compiler/src/constant_pool");
var core_1 = require("@angular/compiler/src/core");
var message_bundle_1 = require("@angular/compiler/src/i18n/message_bundle");
var identifiers_1 = require("@angular/compiler/src/identifiers");
var html_parser_1 = require("@angular/compiler/src/ml_parser/html_parser");
var html_whitespaces_1 = require("@angular/compiler/src/ml_parser/html_whitespaces");
var interpolation_config_1 = require("@angular/compiler/src/ml_parser/interpolation_config");
var o = require("@angular/compiler/src/output/output_ast");
var r3_module_compiler_1 = require("@angular/compiler/src/render3/r3_module_compiler");
var r3_pipe_compiler_1 = require("@angular/compiler/src/render3/r3_pipe_compiler");
var r3_template_transform_1 = require("@angular/compiler/src/render3/r3_template_transform");
var compiler_1 = require("@angular/compiler/src/render3/view/compiler");
var dom_element_schema_registry_1 = require("@angular/compiler/src/schema/dom_element_schema_registry");
var binding_parser_1 = require("@angular/compiler/src/template_parser/binding_parser");
var util_1 = require("@angular/compiler/src/util");
var generated_file_1 = require("@angular/compiler/src/aot/generated_file");
var lazy_routes_1 = require("@angular/compiler/src/aot/lazy_routes");
var static_symbol_1 = require("@angular/compiler/src/aot/static_symbol");
var summary_serializer_1 = require("@angular/compiler/src/aot/summary_serializer");
var util_2 = require("@angular/compiler/src/aot/util");
var AotCompiler = /** @class */ (function () {
function AotCompiler(_config, _options, _host, reflector, _metadataResolver, _templateParser, _styleCompiler, _viewCompiler, _typeCheckCompiler, _ngModuleCompiler, _injectableCompiler, _outputEmitter, _summaryResolver, _symbolResolver) {
this._config = _config;
this._options = _options;
this._host = _host;
this.reflector = reflector;
this._metadataResolver = _metadataResolver;
this._templateParser = _templateParser;
this._styleCompiler = _styleCompiler;
this._viewCompiler = _viewCompiler;
this._typeCheckCompiler = _typeCheckCompiler;
this._ngModuleCompiler = _ngModuleCompiler;
this._injectableCompiler = _injectableCompiler;
this._outputEmitter = _outputEmitter;
this._summaryResolver = _summaryResolver;
this._symbolResolver = _symbolResolver;
this._templateAstCache = new Map();
this._analyzedFiles = new Map();
this._analyzedFilesForInjectables = new Map();
}
AotCompiler.prototype.clearCache = function () {
this._metadataResolver.clearCache();
};
AotCompiler.prototype.analyzeModulesSync = function (rootFiles) {
var _this = this;
var analyzeResult = analyzeAndValidateNgModules(rootFiles, this._host, this._symbolResolver, this._metadataResolver);
analyzeResult.ngModules.forEach(function (ngModule) { return _this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, true); });
return analyzeResult;
};
AotCompiler.prototype.analyzeModulesAsync = function (rootFiles) {
var _this = this;
var analyzeResult = analyzeAndValidateNgModules(rootFiles, this._host, this._symbolResolver, this._metadataResolver);
return Promise
.all(analyzeResult.ngModules.map(function (ngModule) { return _this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, false); }))
.then(function () { return analyzeResult; });
};
AotCompiler.prototype._analyzeFile = function (fileName) {
var analyzedFile = this._analyzedFiles.get(fileName);
if (!analyzedFile) {
analyzedFile =
analyzeFile(this._host, this._symbolResolver, this._metadataResolver, fileName);
this._analyzedFiles.set(fileName, analyzedFile);
}
return analyzedFile;
};
AotCompiler.prototype._analyzeFileForInjectables = function (fileName) {
var analyzedFile = this._analyzedFilesForInjectables.get(fileName);
if (!analyzedFile) {
analyzedFile = analyzeFileForInjectables(this._host, this._symbolResolver, this._metadataResolver, fileName);
this._analyzedFilesForInjectables.set(fileName, analyzedFile);
}
return analyzedFile;
};
AotCompiler.prototype.findGeneratedFileNames = function (fileName) {
var _this = this;
var genFileNames = [];
var file = this._analyzeFile(fileName);
// Make sure we create a .ngfactory if we have a injectable/directive/pipe/NgModule
// or a reference to a non source file.
// Note: This is overestimating the required .ngfactory files as the real calculation is harder.
// Only do this for StubEmitFlags.Basic, as adding a type check block
// does not change this file (as we generate type check blocks based on NgModules).
if (this._options.allowEmptyCodegenFiles || file.directives.length || file.pipes.length ||
file.injectables.length || file.ngModules.length || file.exportsNonSourceFiles) {
genFileNames.push(util_2.ngfactoryFilePath(file.fileName, true));
if (this._options.enableSummariesForJit) {
genFileNames.push(util_2.summaryForJitFileName(file.fileName, true));
}
}
var fileSuffix = util_2.normalizeGenFileSuffix(util_2.splitTypescriptSuffix(file.fileName, true)[1]);
file.directives.forEach(function (dirSymbol) {
var compMeta = _this._metadataResolver.getNonNormalizedDirectiveMetadata(dirSymbol).metadata;
if (!compMeta.isComponent) {
return;
}
// Note: compMeta is a component and therefore template is non null.
compMeta.template.styleUrls.forEach(function (styleUrl) {
var normalizedUrl = _this._host.resourceNameToFileName(styleUrl, file.fileName);
if (!normalizedUrl) {
throw util_1.syntaxError("Couldn't resolve resource " + styleUrl + " relative to " + file.fileName);
}
var needsShim = (compMeta.template.encapsulation ||
_this._config.defaultEncapsulation) === core_1.ViewEncapsulation.Emulated;
genFileNames.push(_stylesModuleUrl(normalizedUrl, needsShim, fileSuffix));
if (_this._options.allowEmptyCodegenFiles) {
genFileNames.push(_stylesModuleUrl(normalizedUrl, !needsShim, fileSuffix));
}
});
});
return genFileNames;
};
AotCompiler.prototype.emitBasicStub = function (genFileName, originalFileName) {
var outputCtx = this._createOutputContext(genFileName);
if (genFileName.endsWith('.ngfactory.ts')) {
if (!originalFileName) {
throw new Error("Assertion error: require the original file for .ngfactory.ts stubs. File: " + genFileName);
}
var originalFile = this._analyzeFile(originalFileName);
this._createNgFactoryStub(outputCtx, originalFile, 1 /* Basic */);
}
else if (genFileName.endsWith('.ngsummary.ts')) {
if (this._options.enableSummariesForJit) {
if (!originalFileName) {
throw new Error("Assertion error: require the original file for .ngsummary.ts stubs. File: " + genFileName);
}
var originalFile = this._analyzeFile(originalFileName);
_createEmptyStub(outputCtx);
originalFile.ngModules.forEach(function (ngModule) {
// create exports that user code can reference
summary_serializer_1.createForJitStub(outputCtx, ngModule.type.reference);
});
}
}
else if (genFileName.endsWith('.ngstyle.ts')) {
_createEmptyStub(outputCtx);
}
// Note: for the stubs, we don't need a property srcFileUrl,
// as later on in emitAllImpls we will create the proper GeneratedFiles with the
// correct srcFileUrl.
// This is good as e.g. for .ngstyle.ts files we can't derive
// the url of components based on the genFileUrl.
return this._codegenSourceModule('unknown', outputCtx);
};
AotCompiler.prototype.emitTypeCheckStub = function (genFileName, originalFileName) {
var originalFile = this._analyzeFile(originalFileName);
var outputCtx = this._createOutputContext(genFileName);
if (genFileName.endsWith('.ngfactory.ts')) {
this._createNgFactoryStub(outputCtx, originalFile, 2 /* TypeCheck */);
}
return outputCtx.statements.length > 0 ?
this._codegenSourceModule(originalFile.fileName, outputCtx) :
null;
};
AotCompiler.prototype.loadFilesAsync = function (fileNames, tsFiles) {
var _this = this;
var files = fileNames.map(function (fileName) { return _this._analyzeFile(fileName); });
var loadingPromises = [];
files.forEach(function (file) { return file.ngModules.forEach(function (ngModule) {
return loadingPromises.push(_this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, false));
}); });
var analyzedInjectables = tsFiles.map(function (tsFile) { return _this._analyzeFileForInjectables(tsFile); });
return Promise.all(loadingPromises).then(function (_) { return ({
analyzedModules: mergeAndValidateNgFiles(files),
analyzedInjectables: analyzedInjectables,
}); });
};
AotCompiler.prototype.loadFilesSync = function (fileNames, tsFiles) {
var _this = this;
var files = fileNames.map(function (fileName) { return _this._analyzeFile(fileName); });
files.forEach(function (file) { return file.ngModules.forEach(function (ngModule) { return _this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, true); }); });
var analyzedInjectables = tsFiles.map(function (tsFile) { return _this._analyzeFileForInjectables(tsFile); });
return {
analyzedModules: mergeAndValidateNgFiles(files),
analyzedInjectables: analyzedInjectables,
};
};
AotCompiler.prototype._createNgFactoryStub = function (outputCtx, file, emitFlags) {
var _this = this;
var componentId = 0;
file.ngModules.forEach(function (ngModuleMeta, ngModuleIndex) {
// Note: the code below needs to executed for StubEmitFlags.Basic and StubEmitFlags.TypeCheck,
// so we don't change the .ngfactory file too much when adding the type-check block.
// create exports that user code can reference
_this._ngModuleCompiler.createStub(outputCtx, ngModuleMeta.type.reference);
// add references to the symbols from the metadata.
// These can be used by the type check block for components,
// and they also cause TypeScript to include these files into the program too,
// which will make them part of the analyzedFiles.
var externalReferences = tslib_1.__spread(ngModuleMeta.transitiveModule.directives.map(function (d) { return d.reference; }), ngModuleMeta.transitiveModule.pipes.map(function (d) { return d.reference; }), ngModuleMeta.importedModules.map(function (m) { return m.type.reference; }), ngModuleMeta.exportedModules.map(function (m) { return m.type.reference; }), _this._externalIdentifierReferences([identifiers_1.Identifiers.TemplateRef, identifiers_1.Identifiers.ElementRef]));
var externalReferenceVars = new Map();
externalReferences.forEach(function (ref, typeIndex) {
externalReferenceVars.set(ref, "_decl" + ngModuleIndex + "_" + typeIndex);
});
externalReferenceVars.forEach(function (varName, reference) {
outputCtx.statements.push(o.variable(varName)
.set(o.NULL_EXPR.cast(o.DYNAMIC_TYPE))
.toDeclStmt(o.expressionType(outputCtx.importExpr(reference, /* typeParams */ null, /* useSummaries */ false))));
});
if (emitFlags & 2 /* TypeCheck */) {
// add the type-check block for all components of the NgModule
ngModuleMeta.declaredDirectives.forEach(function (dirId) {
var compMeta = _this._metadataResolver.getDirectiveMetadata(dirId.reference);
if (!compMeta.isComponent) {
return;
}
componentId++;
_this._createTypeCheckBlock(outputCtx, compMeta.type.reference.name + "_Host_" + componentId, ngModuleMeta, _this._metadataResolver.getHostComponentMetadata(compMeta), [compMeta.type], externalReferenceVars);
_this._createTypeCheckBlock(outputCtx, compMeta.type.reference.name + "_" + componentId, ngModuleMeta, compMeta, ngModuleMeta.transitiveModule.directives, externalReferenceVars);
});
}
});
if (outputCtx.statements.length === 0) {
_createEmptyStub(outputCtx);
}
};
AotCompiler.prototype._externalIdentifierReferences = function (references) {
var e_1, _a;
var result = [];
try {
for (var references_1 = tslib_1.__values(references), references_1_1 = references_1.next(); !references_1_1.done; references_1_1 = references_1.next()) {
var reference = references_1_1.value;
var token = identifiers_1.createTokenForExternalReference(this.reflector, reference);
if (token.identifier) {
result.push(token.identifier.reference);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (references_1_1 && !references_1_1.done && (_a = references_1.return)) _a.call(references_1);
}
finally { if (e_1) throw e_1.error; }
}
return result;
};
AotCompiler.prototype._createTypeCheckBlock = function (ctx, componentId, moduleMeta, compMeta, directives, externalReferenceVars) {
var _a;
var _b = this._parseTemplate(compMeta, moduleMeta, directives), parsedTemplate = _b.template, usedPipes = _b.pipes;
(_a = ctx.statements).push.apply(_a, tslib_1.__spread(this._typeCheckCompiler.compileComponent(componentId, compMeta, parsedTemplate, usedPipes, externalReferenceVars, ctx)));
};
AotCompiler.prototype.emitMessageBundle = function (analyzeResult, locale) {
var _this = this;
var errors = [];
var htmlParser = new html_parser_1.HtmlParser();
// TODO(vicb): implicit tags & attributes
var messageBundle = new message_bundle_1.MessageBundle(htmlParser, [], {}, locale);
analyzeResult.files.forEach(function (file) {
var compMetas = [];
file.directives.forEach(function (directiveType) {
var dirMeta = _this._metadataResolver.getDirectiveMetadata(directiveType);
if (dirMeta && dirMeta.isComponent) {
compMetas.push(dirMeta);
}
});
compMetas.forEach(function (compMeta) {
var html = compMeta.template.template;
// Template URL points to either an HTML or TS file depending on whether
// the file is used with `templateUrl:` or `template:`, respectively.
var templateUrl = compMeta.template.templateUrl;
var interpolationConfig = interpolation_config_1.InterpolationConfig.fromArray(compMeta.template.interpolation);
errors.push.apply(errors, tslib_1.__spread(messageBundle.updateFromTemplate(html, templateUrl, interpolationConfig)));
});
});
if (errors.length) {
throw new Error(errors.map(function (e) { return e.toString(); }).join('\n'));
}
return messageBundle;
};
AotCompiler.prototype.emitAllPartialModules = function (_a, r3Files) {
var _this = this;
var ngModuleByPipeOrDirective = _a.ngModuleByPipeOrDirective, files = _a.files;
var contextMap = new Map();
var getContext = function (fileName) {
if (!contextMap.has(fileName)) {
contextMap.set(fileName, _this._createOutputContext(fileName));
}
return contextMap.get(fileName);
};
files.forEach(function (file) { return _this._compilePartialModule(file.fileName, ngModuleByPipeOrDirective, file.directives, file.pipes, file.ngModules, file.injectables, getContext(file.fileName)); });
r3Files.forEach(function (file) { return _this._compileShallowModules(file.fileName, file.shallowModules, getContext(file.fileName)); });
return Array.from(contextMap.values())
.map(function (context) { return ({
fileName: context.genFilePath,
statements: tslib_1.__spread(context.constantPool.statements, context.statements),
}); });
};
AotCompiler.prototype._compileShallowModules = function (fileName, shallowModules, context) {
var _this = this;
shallowModules.forEach(function (module) { return r3_module_compiler_1.compileNgModuleFromRender2(context, module, _this._injectableCompiler); });
};
AotCompiler.prototype._compilePartialModule = function (fileName, ngModuleByPipeOrDirective, directives, pipes, ngModules, injectables, context) {
var _this = this;
var errors = [];
var schemaRegistry = new dom_element_schema_registry_1.DomElementSchemaRegistry();
var hostBindingParser = new binding_parser_1.BindingParser(this._templateParser.expressionParser, interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG, schemaRegistry, [], errors);
// Process all components and directives
directives.forEach(function (directiveType) {
var directiveMetadata = _this._metadataResolver.getDirectiveMetadata(directiveType);
if (directiveMetadata.isComponent) {
var module = ngModuleByPipeOrDirective.get(directiveType);
module ||
util_1.error("Cannot determine the module for component '" + compile_metadata_1.identifierName(directiveMetadata.type) + "'");
var htmlAst = directiveMetadata.template.htmlAst;
var preserveWhitespaces = directiveMetadata.template.preserveWhitespaces;
if (!preserveWhitespaces) {
htmlAst = html_whitespaces_1.removeWhitespaces(htmlAst);
}
var render3Ast = r3_template_transform_1.htmlAstToRender3Ast(htmlAst.rootNodes, hostBindingParser);
// Map of StaticType by directive selectors
var directiveTypeBySel_1 = new Map();
var directives_1 = module.transitiveModule.directives.map(function (dir) { return _this._metadataResolver.getDirectiveSummary(dir.reference); });
directives_1.forEach(function (directive) {
if (directive.selector) {
directiveTypeBySel_1.set(directive.selector, directive.type.reference);
}
});
// Map of StaticType by pipe names
var pipeTypeByName_1 = new Map();
var pipes_1 = module.transitiveModule.pipes.map(function (pipe) { return _this._metadataResolver.getPipeSummary(pipe.reference); });
pipes_1.forEach(function (pipe) {
pipeTypeByName_1.set(pipe.name, pipe.type.reference);
});
compiler_1.compileComponentFromRender2(context, directiveMetadata, render3Ast, _this.reflector, hostBindingParser, directiveTypeBySel_1, pipeTypeByName_1);
}
else {
compiler_1.compileDirectiveFromRender2(context, directiveMetadata, _this.reflector, hostBindingParser);
}
});
pipes.forEach(function (pipeType) {
var pipeMetadata = _this._metadataResolver.getPipeMetadata(pipeType);
if (pipeMetadata) {
r3_pipe_compiler_1.compilePipeFromRender2(context, pipeMetadata, _this.reflector);
}
});
injectables.forEach(function (injectable) { return _this._injectableCompiler.compile(injectable, context); });
};
AotCompiler.prototype.emitAllPartialModules2 = function (files) {
var _this = this;
// Using reduce like this is a select many pattern (where map is a select pattern)
return files.reduce(function (r, file) {
r.push.apply(r, tslib_1.__spread(_this._emitPartialModule2(file.fileName, file.injectables)));
return r;
}, []);
};
AotCompiler.prototype._emitPartialModule2 = function (fileName, injectables) {
var _this = this;
var context = this._createOutputContext(fileName);
injectables.forEach(function (injectable) { return _this._injectableCompiler.compile(injectable, context); });
if (context.statements && context.statements.length > 0) {
return [{ fileName: fileName, statements: tslib_1.__spread(context.constantPool.statements, context.statements) }];
}
return [];
};
AotCompiler.prototype.emitAllImpls = function (analyzeResult) {
var _this = this;
var ngModuleByPipeOrDirective = analyzeResult.ngModuleByPipeOrDirective, files = analyzeResult.files;
var sourceModules = files.map(function (file) { return _this._compileImplFile(file.fileName, ngModuleByPipeOrDirective, file.directives, file.pipes, file.ngModules, file.injectables); });
return compile_metadata_1.flatten(sourceModules);
};
AotCompiler.prototype._compileImplFile = function (srcFileUrl, ngModuleByPipeOrDirective, directives, pipes, ngModules, injectables) {
var _this = this;
var fileSuffix = util_2.normalizeGenFileSuffix(util_2.splitTypescriptSuffix(srcFileUrl, true)[1]);
var generatedFiles = [];
var outputCtx = this._createOutputContext(util_2.ngfactoryFilePath(srcFileUrl, true));
generatedFiles.push.apply(generatedFiles, tslib_1.__spread(this._createSummary(srcFileUrl, directives, pipes, ngModules, injectables, outputCtx)));
// compile all ng modules
ngModules.forEach(function (ngModuleMeta) { return _this._compileModule(outputCtx, ngModuleMeta); });
// compile components
directives.forEach(function (dirType) {
var compMeta = _this._metadataResolver.getDirectiveMetadata(dirType);
if (!compMeta.isComponent) {
return;
}
var ngModule = ngModuleByPipeOrDirective.get(dirType);
if (!ngModule) {
throw new Error("Internal Error: cannot determine the module for component " + compile_metadata_1.identifierName(compMeta.type) + "!");
}
// compile styles
var componentStylesheet = _this._styleCompiler.compileComponent(outputCtx, compMeta);
// Note: compMeta is a component and therefore template is non null.
compMeta.template.externalStylesheets.forEach(function (stylesheetMeta) {
// Note: fill non shim and shim style files as they might
// be shared by component with and without ViewEncapsulation.
var shim = _this._styleCompiler.needsStyleShim(compMeta);
generatedFiles.push(_this._codegenStyles(srcFileUrl, compMeta, stylesheetMeta, shim, fileSuffix));
if (_this._options.allowEmptyCodegenFiles) {
generatedFiles.push(_this._codegenStyles(srcFileUrl, compMeta, stylesheetMeta, !shim, fileSuffix));
}
});
// compile components
var compViewVars = _this._compileComponent(outputCtx, compMeta, ngModule, ngModule.transitiveModule.directives, componentStylesheet, fileSuffix);
_this._compileComponentFactory(outputCtx, compMeta, ngModule, fileSuffix);
});
if (outputCtx.statements.length > 0 || this._options.allowEmptyCodegenFiles) {
var srcModule = this._codegenSourceModule(srcFileUrl, outputCtx);
generatedFiles.unshift(srcModule);
}
return generatedFiles;
};
AotCompiler.prototype._createSummary = function (srcFileName, directives, pipes, ngModules, injectables, ngFactoryCtx) {
var _this = this;
var symbolSummaries = this._symbolResolver.getSymbolsOf(srcFileName)
.map(function (symbol) { return _this._symbolResolver.resolveSymbol(symbol); });
var typeData = tslib_1.__spread(ngModules.map(function (meta) { return ({
summary: _this._metadataResolver.getNgModuleSummary(meta.type.reference),
metadata: _this._metadataResolver.getNgModuleMetadata(meta.type.reference)
}); }), directives.map(function (ref) { return ({
summary: _this._metadataResolver.getDirectiveSummary(ref),
metadata: _this._metadataResolver.getDirectiveMetadata(ref)
}); }), pipes.map(function (ref) { return ({
summary: _this._metadataResolver.getPipeSummary(ref),
metadata: _this._metadataResolver.getPipeMetadata(ref)
}); }), injectables.map(function (ref) { return ({
summary: _this._metadataResolver.getInjectableSummary(ref.symbol),
metadata: _this._metadataResolver.getInjectableSummary(ref.symbol).type
}); }));
var forJitOutputCtx = this._options.enableSummariesForJit ?
this._createOutputContext(util_2.summaryForJitFileName(srcFileName, true)) :
null;
var _a = summary_serializer_1.serializeSummaries(srcFileName, forJitOutputCtx, this._summaryResolver, this._symbolResolver, symbolSummaries, typeData, this._options.createExternalSymbolFactoryReexports), json = _a.json, exportAs = _a.exportAs;
exportAs.forEach(function (entry) {
ngFactoryCtx.statements.push(o.variable(entry.exportAs).set(ngFactoryCtx.importExpr(entry.symbol)).toDeclStmt(null, [
o.StmtModifier.Exported
]));
});
var summaryJson = new generated_file_1.GeneratedFile(srcFileName, util_2.summaryFileName(srcFileName), json);
var result = [summaryJson];
if (forJitOutputCtx) {
result.push(this._codegenSourceModule(srcFileName, forJitOutputCtx));
}
return result;
};
AotCompiler.prototype._compileModule = function (outputCtx, ngModule) {
var providers = [];
if (this._options.locale) {
var normalizedLocale = this._options.locale.replace(/_/g, '-');
providers.push({
token: identifiers_1.createTokenForExternalReference(this.reflector, identifiers_1.Identifiers.LOCALE_ID),
useValue: normalizedLocale,
});
}
if (this._options.i18nFormat) {
providers.push({
token: identifiers_1.createTokenForExternalReference(this.reflector, identifiers_1.Identifiers.TRANSLATIONS_FORMAT),
useValue: this._options.i18nFormat
});
}
this._ngModuleCompiler.compile(outputCtx, ngModule, providers);
};
AotCompiler.prototype._compileComponentFactory = function (outputCtx, compMeta, ngModule, fileSuffix) {
var hostMeta = this._metadataResolver.getHostComponentMetadata(compMeta);
var hostViewFactoryVar = this._compileComponent(outputCtx, hostMeta, ngModule, [compMeta.type], null, fileSuffix)
.viewClassVar;
var compFactoryVar = compile_metadata_1.componentFactoryName(compMeta.type.reference);
var inputsExprs = [];
for (var propName in compMeta.inputs) {
var templateName = compMeta.inputs[propName];
// Don't quote so that the key gets minified...
inputsExprs.push(new o.LiteralMapEntry(propName, o.literal(templateName), false));
}
var outputsExprs = [];
for (var propName in compMeta.outputs) {
var templateName = compMeta.outputs[propName];
// Don't quote so that the key gets minified...
outputsExprs.push(new o.LiteralMapEntry(propName, o.literal(templateName), false));
}
outputCtx.statements.push(o.variable(compFactoryVar)
.set(o.importExpr(identifiers_1.Identifiers.createComponentFactory).callFn([
o.literal(compMeta.selector), outputCtx.importExpr(compMeta.type.reference),
o.variable(hostViewFactoryVar), new o.LiteralMapExpr(inputsExprs),
new o.LiteralMapExpr(outputsExprs),
o.literalArr(compMeta.template.ngContentSelectors.map(function (selector) { return o.literal(selector); }))
]))
.toDeclStmt(o.importType(identifiers_1.Identifiers.ComponentFactory, [o.expressionType(outputCtx.importExpr(compMeta.type.reference))], [o.TypeModifier.Const]), [o.StmtModifier.Final, o.StmtModifier.Exported]));
};
AotCompiler.prototype._compileComponent = function (outputCtx, compMeta, ngModule, directiveIdentifiers, componentStyles, fileSuffix) {
var _a = this._parseTemplate(compMeta, ngModule, directiveIdentifiers), parsedTemplate = _a.template, usedPipes = _a.pipes;
var stylesExpr = componentStyles ? o.variable(componentStyles.stylesVar) : o.literalArr([]);
var viewResult = this._viewCompiler.compileComponent(outputCtx, compMeta, parsedTemplate, stylesExpr, usedPipes);
if (componentStyles) {
_resolveStyleStatements(this._symbolResolver, componentStyles, this._styleCompiler.needsStyleShim(compMeta), fileSuffix);
}
return viewResult;
};
AotCompiler.prototype._parseTemplate = function (compMeta, ngModule, directiveIdentifiers) {
var _this = this;
if (this._templateAstCache.has(compMeta.type.reference)) {
return this._templateAstCache.get(compMeta.type.reference);
}
var preserveWhitespaces = compMeta.template.preserveWhitespaces;
var directives = directiveIdentifiers.map(function (dir) { return _this._metadataResolver.getDirectiveSummary(dir.reference); });
var pipes = ngModule.transitiveModule.pipes.map(function (pipe) { return _this._metadataResolver.getPipeSummary(pipe.reference); });
var result = this._templateParser.parse(compMeta, compMeta.template.htmlAst, directives, pipes, ngModule.schemas, compile_metadata_1.templateSourceUrl(ngModule.type, compMeta, compMeta.template), preserveWhitespaces);
this._templateAstCache.set(compMeta.type.reference, result);
return result;
};
AotCompiler.prototype._createOutputContext = function (genFilePath) {
var _this = this;
var importExpr = function (symbol, typeParams, useSummaries) {
if (typeParams === void 0) { typeParams = null; }
if (useSummaries === void 0) { useSummaries = true; }
if (!(symbol instanceof static_symbol_1.StaticSymbol)) {
throw new Error("Internal error: unknown identifier " + JSON.stringify(symbol));
}
var arity = _this._symbolResolver.getTypeArity(symbol) || 0;
var _a = _this._symbolResolver.getImportAs(symbol, useSummaries) || symbol, filePath = _a.filePath, name = _a.name, members = _a.members;
var importModule = _this._fileNameToModuleName(filePath, genFilePath);
// It should be good enough to compare filePath to genFilePath and if they are equal
// there is a self reference. However, ngfactory files generate to .ts but their
// symbols have .d.ts so a simple compare is insufficient. They should be canonical
// and is tracked by #17705.
var selfReference = _this._fileNameToModuleName(genFilePath, genFilePath);
var moduleName = importModule === selfReference ? null : importModule;
// If we are in a type expression that refers to a generic type then supply
// the required type parameters. If there were not enough type parameters
// supplied, supply any as the type. Outside a type expression the reference
// should not supply type parameters and be treated as a simple value reference
// to the constructor function itself.
var suppliedTypeParams = typeParams || [];
var missingTypeParamsCount = arity - suppliedTypeParams.length;
var allTypeParams = suppliedTypeParams.concat(util_1.newArray(missingTypeParamsCount, o.DYNAMIC_TYPE));
return members.reduce(function (expr, memberName) { return expr.prop(memberName); }, o.importExpr(new o.ExternalReference(moduleName, name, null), allTypeParams));
};
return { statements: [], genFilePath: genFilePath, importExpr: importExpr, constantPool: new constant_pool_1.ConstantPool() };
};
AotCompiler.prototype._fileNameToModuleName = function (importedFilePath, containingFilePath) {
return this._summaryResolver.getKnownModuleName(importedFilePath) ||
this._symbolResolver.getKnownModuleName(importedFilePath) ||
this._host.fileNameToModuleName(importedFilePath, containingFilePath);
};
AotCompiler.prototype._codegenStyles = function (srcFileUrl, compMeta, stylesheetMetadata, isShimmed, fileSuffix) {
var outputCtx = this._createOutputContext(_stylesModuleUrl(stylesheetMetadata.moduleUrl, isShimmed, fileSuffix));
var compiledStylesheet = this._styleCompiler.compileStyles(outputCtx, compMeta, stylesheetMetadata, isShimmed);
_resolveStyleStatements(this._symbolResolver, compiledStylesheet, isShimmed, fileSuffix);
return this._codegenSourceModule(srcFileUrl, outputCtx);
};
AotCompiler.prototype._codegenSourceModule = function (srcFileUrl, ctx) {
return new generated_file_1.GeneratedFile(srcFileUrl, ctx.genFilePath, ctx.statements);
};
AotCompiler.prototype.listLazyRoutes = function (entryRoute, analyzedModules) {
var e_2, _a, e_3, _b;
var self = this;
if (entryRoute) {
var symbol = lazy_routes_1.parseLazyRoute(entryRoute, this.reflector).referencedModule;
return visitLazyRoute(symbol);
}
else if (analyzedModules) {
var allLazyRoutes = [];
try {
for (var _c = tslib_1.__values(analyzedModules.ngModules), _d = _c.next(); !_d.done; _d = _c.next()) {
var ngModule = _d.value;
var lazyRoutes = lazy_routes_1.listLazyRoutes(ngModule, this.reflector);
try {
for (var lazyRoutes_1 = (e_3 = void 0, tslib_1.__values(lazyRoutes)), lazyRoutes_1_1 = lazyRoutes_1.next(); !lazyRoutes_1_1.done; lazyRoutes_1_1 = lazyRoutes_1.next()) {
var lazyRoute = lazyRoutes_1_1.value;
allLazyRoutes.push(lazyRoute);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (lazyRoutes_1_1 && !lazyRoutes_1_1.done && (_b = lazyRoutes_1.return)) _b.call(lazyRoutes_1);
}
finally { if (e_3) throw e_3.error; }
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_2) throw e_2.error; }
}
return allLazyRoutes;
}
else {
throw new Error("Either route or analyzedModules has to be specified!");
}
function visitLazyRoute(symbol, seenRoutes, allLazyRoutes) {
var e_4, _a;
if (seenRoutes === void 0) { seenRoutes = new Set(); }
if (allLazyRoutes === void 0) { allLazyRoutes = []; }
// Support pointing to default exports, but stop recursing there,
// as the StaticReflector does not yet support default exports.
if (seenRoutes.has(symbol) || !symbol.name) {
return allLazyRoutes;
}
seenRoutes.add(symbol);
var lazyRoutes = lazy_routes_1.listLazyRoutes(self._metadataResolver.getNgModuleMetadata(symbol, true), self.reflector);
try {
for (var lazyRoutes_2 = tslib_1.__values(lazyRoutes), lazyRoutes_2_1 = lazyRoutes_2.next(); !lazyRoutes_2_1.done; lazyRoutes_2_1 = lazyRoutes_2.next()) {
var lazyRoute = lazyRoutes_2_1.value;
allLazyRoutes.push(lazyRoute);
visitLazyRoute(lazyRoute.referencedModule, seenRoutes, allLazyRoutes);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (lazyRoutes_2_1 && !lazyRoutes_2_1.done && (_a = lazyRoutes_2.return)) _a.call(lazyRoutes_2);
}
finally { if (e_4) throw e_4.error; }
}
return allLazyRoutes;
}
};
return AotCompiler;
}());
exports.AotCompiler = AotCompiler;
function _createEmptyStub(outputCtx) {
// Note: We need to produce at least one import statement so that
// TypeScript knows that the file is an es6 module. Otherwise our generated
// exports / imports won't be emitted properly by TypeScript.
outputCtx.statements.push(o.importExpr(identifiers_1.Identifiers.ComponentFactory).toStmt());
}
function _resolveStyleStatements(symbolResolver, compileResult, needsShim, fileSuffix) {
compileResult.dependencies.forEach(function (dep) {
dep.setValue(symbolResolver.getStaticSymbol(_stylesModuleUrl(dep.moduleUrl, needsShim, fileSuffix), dep.name));
});
}
function _stylesModuleUrl(stylesheetUrl, shim, suffix) {
return "" + stylesheetUrl + (shim ? '.shim' : '') + ".ngstyle" + suffix;
}
function analyzeNgModules(fileNames, host, staticSymbolResolver, metadataResolver) {
var files = _analyzeFilesIncludingNonProgramFiles(fileNames, host, staticSymbolResolver, metadataResolver);
return mergeAnalyzedFiles(files);
}
exports.analyzeNgModules = analyzeNgModules;
function analyzeAndValidateNgModules(fileNames, host, staticSymbolResolver, metadataResolver) {
return validateAnalyzedModules(analyzeNgModules(fileNames, host, staticSymbolResolver, metadataResolver));
}
exports.analyzeAndValidateNgModules = analyzeAndValidateNgModules;
function validateAnalyzedModules(analyzedModules) {
if (analyzedModules.symbolsMissingModule && analyzedModules.symbolsMissingModule.length) {
var messages = analyzedModules.symbolsMissingModule.map(function (s) { return "Cannot determine the module for class " + s.name + " in " + s.filePath + "! Add " + s.name + " to the NgModule to fix it."; });
throw util_1.syntaxError(messages.join('\n'));
}
return analyzedModules;
}
// Analyzes all of the program files,
// including files that are not part of the program
// but are referenced by an NgModule.
function _analyzeFilesIncludingNonProgramFiles(fileNames, host, staticSymbolResolver, metadataResolver) {
var seenFiles = new Set();
var files = [];
var visitFile = function (fileName) {
if (seenFiles.has(fileName) || !host.isSourceFile(fileName)) {
return false;
}
seenFiles.add(fileName);
var analyzedFile = analyzeFile(host, staticSymbolResolver, metadataResolver, fileName);
files.push(analyzedFile);
analyzedFile.ngModules.forEach(function (ngModule) {
ngModule.transitiveModule.modules.forEach(function (modMeta) { return visitFile(modMeta.reference.filePath); });
});
};
fileNames.forEach(function (fileName) { return visitFile(fileName); });
return files;
}
function analyzeFile(host, staticSymbolResolver, metadataResolver, fileName) {
var abstractDirectives = [];
var directives = [];
var pipes = [];
var injectables = [];
var ngModules = [];
var hasDecorators = staticSymbolResolver.hasDecorators(fileName);
var exportsNonSourceFiles = false;
var isDeclarationFile = fileName.endsWith('.d.ts');
// Don't analyze .d.ts files that have no decorators as a shortcut
// to speed up the analysis. This prevents us from
// resolving the references in these files.
// Note: exportsNonSourceFiles is only needed when compiling with summaries,
// which is not the case when .d.ts files are treated as input files.
if (!isDeclarationFile || hasDecorators) {
staticSymbolResolver.getSymbolsOf(fileName).forEach(function (symbol) {
var resolvedSymbol = staticSymbolResolver.resolveSymbol(symbol);
var symbolMeta = resolvedSymbol.metadata;
if (!symbolMeta || symbolMeta.__symbolic === 'error') {
return;
}
var isNgSymbol = false;
if (symbolMeta.__symbolic === 'class') {
if (metadataResolver.isDirective(symbol)) {
isNgSymbol = true;
// This directive either has a selector or doesn't. Selector-less directives get tracked
// in abstractDirectives, not directives. The compiler doesn't deal with selector-less
// directives at all, really, other than to persist their metadata. This is done so that
// apps will have an easier time migrating to Ivy, which requires the selector-less
// annotations to be applied.
if (!metadataResolver.isAbstractDirective(symbol)) {
// The directive is an ordinary directive.
directives.push(symbol);
}
else {
// The directive has no selector and is an "abstract" directive, so track it
// accordingly.
abstractDirectives.push(symbol);
}
}
else if (metadataResolver.isPipe(symbol)) {
isNgSymbol = true;
pipes.push(symbol);
}
else if (metadataResolver.isNgModule(symbol)) {
var ngModule = metadataResolver.getNgModuleMetadata(symbol, false);
if (ngModule) {
isNgSymbol = true;
ngModules.push(ngModule);
}
}
else if (metadataResolver.isInjectable(symbol)) {
isNgSymbol = true;
var injectable = metadataResolver.getInjectableMetadata(symbol, null, false);
if (injectable) {
injectables.push(injectable);
}
}
}
if (!isNgSymbol) {
exportsNonSourceFiles =
exportsNonSourceFiles || isValueExportingNonSourceFile(host, symbolMeta);
}
});
}
return {
fileName: fileName,
directives: directives,
abstractDirectives: abstractDirectives,
pipes: pipes,
ngModules: ngModules,
injectables: injectables,
exportsNonSourceFiles: exportsNonSourceFiles,
};
}
exports.analyzeFile = analyzeFile;
function analyzeFileForInjectables(host, staticSymbolResolver, metadataResolver, fileName) {
var injectables = [];
var shallowModules = [];
if (staticSymbolResolver.hasDecorators(fileName)) {
staticSymbolResolver.getSymbolsOf(fileName).forEach(function (symbol) {
var resolvedSymbol = staticSymbolResolver.resolveSymbol(symbol);
var symbolMeta = resolvedSymbol.metadata;
if (!symbolMeta || symbolMeta.__symbolic === 'error') {
return;
}
if (symbolMeta.__symbolic === 'class') {
if (metadataResolver.isInjectable(symbol)) {
var injectable = metadataResolver.getInjectableMetadata(symbol, null, false);
if (injectable) {
injectables.push(injectable);
}
}
else if (metadataResolver.isNgModule(symbol)) {
var module = metadataResolver.getShallowModuleMetadata(symbol);
if (module) {
shallowModules.push(module);