@angular/compiler
Version:
Angular - the compiler library
914 lines (913 loc) • 175 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/metadata_resolver", ["require", "exports", "tslib", "@angular/compiler/src/aot/static_symbol", "@angular/compiler/src/aot/util", "@angular/compiler/src/assertions", "@angular/compiler/src/compile_metadata", "@angular/compiler/src/core", "@angular/compiler/src/directive_resolver", "@angular/compiler/src/identifiers", "@angular/compiler/src/lifecycle_reflector", "@angular/compiler/src/selector", "@angular/compiler/src/util"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompileMetadataResolver = exports.ERROR_COMPONENT_TYPE = void 0;
var tslib_1 = require("tslib");
var static_symbol_1 = require("@angular/compiler/src/aot/static_symbol");
var util_1 = require("@angular/compiler/src/aot/util");
var assertions_1 = require("@angular/compiler/src/assertions");
var cpl = require("@angular/compiler/src/compile_metadata");
var core_1 = require("@angular/compiler/src/core");
var directive_resolver_1 = require("@angular/compiler/src/directive_resolver");
var identifiers_1 = require("@angular/compiler/src/identifiers");
var lifecycle_reflector_1 = require("@angular/compiler/src/lifecycle_reflector");
var selector_1 = require("@angular/compiler/src/selector");
var util_2 = require("@angular/compiler/src/util");
exports.ERROR_COMPONENT_TYPE = 'ngComponentType';
// Design notes:
// - don't lazily create metadata:
// For some metadata, we need to do async work sometimes,
// so the user has to kick off this loading.
// But we want to report errors even when the async work is
// not required to check that the user would have been able
// to wait correctly.
var CompileMetadataResolver = /** @class */ (function () {
function CompileMetadataResolver(_config, _htmlParser, _ngModuleResolver, _directiveResolver, _pipeResolver, _summaryResolver, _schemaRegistry, _directiveNormalizer, _console, _staticSymbolCache, _reflector, _errorCollector) {
this._config = _config;
this._htmlParser = _htmlParser;
this._ngModuleResolver = _ngModuleResolver;
this._directiveResolver = _directiveResolver;
this._pipeResolver = _pipeResolver;
this._summaryResolver = _summaryResolver;
this._schemaRegistry = _schemaRegistry;
this._directiveNormalizer = _directiveNormalizer;
this._console = _console;
this._staticSymbolCache = _staticSymbolCache;
this._reflector = _reflector;
this._errorCollector = _errorCollector;
this._nonNormalizedDirectiveCache = new Map();
this._directiveCache = new Map();
this._summaryCache = new Map();
this._pipeCache = new Map();
this._ngModuleCache = new Map();
this._ngModuleOfTypes = new Map();
this._shallowModuleCache = new Map();
}
CompileMetadataResolver.prototype.getReflector = function () {
return this._reflector;
};
CompileMetadataResolver.prototype.clearCacheFor = function (type) {
var dirMeta = this._directiveCache.get(type);
this._directiveCache.delete(type);
this._nonNormalizedDirectiveCache.delete(type);
this._summaryCache.delete(type);
this._pipeCache.delete(type);
this._ngModuleOfTypes.delete(type);
// Clear all of the NgModule as they contain transitive information!
this._ngModuleCache.clear();
if (dirMeta) {
this._directiveNormalizer.clearCacheFor(dirMeta);
}
};
CompileMetadataResolver.prototype.clearCache = function () {
this._directiveCache.clear();
this._nonNormalizedDirectiveCache.clear();
this._summaryCache.clear();
this._pipeCache.clear();
this._ngModuleCache.clear();
this._ngModuleOfTypes.clear();
this._directiveNormalizer.clearCache();
};
CompileMetadataResolver.prototype._createProxyClass = function (baseType, name) {
var delegate = null;
var proxyClass = function () {
if (!delegate) {
throw new Error("Illegal state: Class " + name + " for type " + util_2.stringify(baseType) + " is not compiled yet!");
}
return delegate.apply(this, arguments);
};
proxyClass.setDelegate = function (d) {
delegate = d;
proxyClass.prototype = d.prototype;
};
// Make stringify work correctly
proxyClass.overriddenName = name;
return proxyClass;
};
CompileMetadataResolver.prototype.getGeneratedClass = function (dirType, name) {
if (dirType instanceof static_symbol_1.StaticSymbol) {
return this._staticSymbolCache.get(util_1.ngfactoryFilePath(dirType.filePath), name);
}
else {
return this._createProxyClass(dirType, name);
}
};
CompileMetadataResolver.prototype.getComponentViewClass = function (dirType) {
return this.getGeneratedClass(dirType, cpl.viewClassName(dirType, 0));
};
CompileMetadataResolver.prototype.getHostComponentViewClass = function (dirType) {
return this.getGeneratedClass(dirType, cpl.hostViewClassName(dirType));
};
CompileMetadataResolver.prototype.getHostComponentType = function (dirType) {
var name = cpl.identifierName({ reference: dirType }) + "_Host";
if (dirType instanceof static_symbol_1.StaticSymbol) {
return this._staticSymbolCache.get(dirType.filePath, name);
}
return this._createProxyClass(dirType, name);
};
CompileMetadataResolver.prototype.getRendererType = function (dirType) {
if (dirType instanceof static_symbol_1.StaticSymbol) {
return this._staticSymbolCache.get(util_1.ngfactoryFilePath(dirType.filePath), cpl.rendererTypeName(dirType));
}
else {
// returning an object as proxy,
// that we fill later during runtime compilation.
return {};
}
};
CompileMetadataResolver.prototype.getComponentFactory = function (selector, dirType, inputs, outputs) {
if (dirType instanceof static_symbol_1.StaticSymbol) {
return this._staticSymbolCache.get(util_1.ngfactoryFilePath(dirType.filePath), cpl.componentFactoryName(dirType));
}
else {
var hostView = this.getHostComponentViewClass(dirType);
// Note: ngContentSelectors will be filled later once the template is
// loaded.
var createComponentFactory = this._reflector.resolveExternalReference(identifiers_1.Identifiers.createComponentFactory);
return createComponentFactory(selector, dirType, hostView, inputs, outputs, []);
}
};
CompileMetadataResolver.prototype.initComponentFactory = function (factory, ngContentSelectors) {
var _a;
if (!(factory instanceof static_symbol_1.StaticSymbol)) {
(_a = factory.ngContentSelectors).push.apply(_a, tslib_1.__spread(ngContentSelectors));
}
};
CompileMetadataResolver.prototype._loadSummary = function (type, kind) {
var typeSummary = this._summaryCache.get(type);
if (!typeSummary) {
var summary = this._summaryResolver.resolveSummary(type);
typeSummary = summary ? summary.type : null;
this._summaryCache.set(type, typeSummary || null);
}
return typeSummary && typeSummary.summaryKind === kind ? typeSummary : null;
};
CompileMetadataResolver.prototype.getHostComponentMetadata = function (compMeta, hostViewType) {
var hostType = this.getHostComponentType(compMeta.type.reference);
if (!hostViewType) {
hostViewType = this.getHostComponentViewClass(hostType);
}
// Note: ! is ok here as this method should only be called with normalized directive
// metadata, which always fills in the selector.
var template = selector_1.CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate();
var templateUrl = '';
var htmlAst = this._htmlParser.parse(template, templateUrl);
return cpl.CompileDirectiveMetadata.create({
isHost: true,
type: { reference: hostType, diDeps: [], lifecycleHooks: [] },
template: new cpl.CompileTemplateMetadata({
encapsulation: core_1.ViewEncapsulation.None,
template: template,
templateUrl: templateUrl,
htmlAst: htmlAst,
styles: [],
styleUrls: [],
ngContentSelectors: [],
animations: [],
isInline: true,
externalStylesheets: [],
interpolation: null,
preserveWhitespaces: false,
}),
exportAs: null,
changeDetection: core_1.ChangeDetectionStrategy.Default,
inputs: [],
outputs: [],
host: {},
isComponent: true,
selector: '*',
providers: [],
viewProviders: [],
queries: [],
guards: {},
viewQueries: [],
componentViewType: hostViewType,
rendererType: { id: '__Host__', encapsulation: core_1.ViewEncapsulation.None, styles: [], data: {} },
entryComponents: [],
componentFactory: null
});
};
CompileMetadataResolver.prototype.loadDirectiveMetadata = function (ngModuleType, directiveType, isSync) {
var _this = this;
if (this._directiveCache.has(directiveType)) {
return null;
}
directiveType = util_2.resolveForwardRef(directiveType);
var _a = this.getNonNormalizedDirectiveMetadata(directiveType), annotation = _a.annotation, metadata = _a.metadata;
var createDirectiveMetadata = function (templateMetadata) {
var normalizedDirMeta = new cpl.CompileDirectiveMetadata({
isHost: false,
type: metadata.type,
isComponent: metadata.isComponent,
selector: metadata.selector,
exportAs: metadata.exportAs,
changeDetection: metadata.changeDetection,
inputs: metadata.inputs,
outputs: metadata.outputs,
hostListeners: metadata.hostListeners,
hostProperties: metadata.hostProperties,
hostAttributes: metadata.hostAttributes,
providers: metadata.providers,
viewProviders: metadata.viewProviders,
queries: metadata.queries,
guards: metadata.guards,
viewQueries: metadata.viewQueries,
entryComponents: metadata.entryComponents,
componentViewType: metadata.componentViewType,
rendererType: metadata.rendererType,
componentFactory: metadata.componentFactory,
template: templateMetadata
});
if (templateMetadata) {
_this.initComponentFactory(metadata.componentFactory, templateMetadata.ngContentSelectors);
}
_this._directiveCache.set(directiveType, normalizedDirMeta);
_this._summaryCache.set(directiveType, normalizedDirMeta.toSummary());
return null;
};
if (metadata.isComponent) {
var template = metadata.template;
var templateMeta = this._directiveNormalizer.normalizeTemplate({
ngModuleType: ngModuleType,
componentType: directiveType,
moduleUrl: this._reflector.componentModuleUrl(directiveType, annotation),
encapsulation: template.encapsulation,
template: template.template,
templateUrl: template.templateUrl,
styles: template.styles,
styleUrls: template.styleUrls,
animations: template.animations,
interpolation: template.interpolation,
preserveWhitespaces: template.preserveWhitespaces
});
if (util_2.isPromise(templateMeta) && isSync) {
this._reportError(componentStillLoadingError(directiveType), directiveType);
return null;
}
return util_2.SyncAsync.then(templateMeta, createDirectiveMetadata);
}
else {
// directive
createDirectiveMetadata(null);
return null;
}
};
CompileMetadataResolver.prototype.getNonNormalizedDirectiveMetadata = function (directiveType) {
var _this = this;
directiveType = util_2.resolveForwardRef(directiveType);
if (!directiveType) {
return null;
}
var cacheEntry = this._nonNormalizedDirectiveCache.get(directiveType);
if (cacheEntry) {
return cacheEntry;
}
var dirMeta = this._directiveResolver.resolve(directiveType, false);
if (!dirMeta) {
return null;
}
var nonNormalizedTemplateMetadata = undefined;
if (core_1.createComponent.isTypeOf(dirMeta)) {
// component
var compMeta = dirMeta;
assertions_1.assertArrayOfStrings('styles', compMeta.styles);
assertions_1.assertArrayOfStrings('styleUrls', compMeta.styleUrls);
assertions_1.assertInterpolationSymbols('interpolation', compMeta.interpolation);
var animations = compMeta.animations;
nonNormalizedTemplateMetadata = new cpl.CompileTemplateMetadata({
encapsulation: util_2.noUndefined(compMeta.encapsulation),
template: util_2.noUndefined(compMeta.template),
templateUrl: util_2.noUndefined(compMeta.templateUrl),
htmlAst: null,
styles: compMeta.styles || [],
styleUrls: compMeta.styleUrls || [],
animations: animations || [],
interpolation: util_2.noUndefined(compMeta.interpolation),
isInline: !!compMeta.template,
externalStylesheets: [],
ngContentSelectors: [],
preserveWhitespaces: util_2.noUndefined(dirMeta.preserveWhitespaces),
});
}
var changeDetectionStrategy = null;
var viewProviders = [];
var entryComponentMetadata = [];
var selector = dirMeta.selector;
if (core_1.createComponent.isTypeOf(dirMeta)) {
// Component
var compMeta = dirMeta;
changeDetectionStrategy = compMeta.changeDetection;
if (compMeta.viewProviders) {
viewProviders = this._getProvidersMetadata(compMeta.viewProviders, entryComponentMetadata, "viewProviders for \"" + stringifyType(directiveType) + "\"", [], directiveType);
}
if (compMeta.entryComponents) {
entryComponentMetadata = flattenAndDedupeArray(compMeta.entryComponents)
.map(function (type) { return _this._getEntryComponentMetadata(type); })
.concat(entryComponentMetadata);
}
if (!selector) {
selector = this._schemaRegistry.getDefaultComponentElementName();
}
}
else {
// Directive
if (!selector) {
selector = null;
}
}
var providers = [];
if (dirMeta.providers != null) {
providers = this._getProvidersMetadata(dirMeta.providers, entryComponentMetadata, "providers for \"" + stringifyType(directiveType) + "\"", [], directiveType);
}
var queries = [];
var viewQueries = [];
if (dirMeta.queries != null) {
queries = this._getQueriesMetadata(dirMeta.queries, false, directiveType);
viewQueries = this._getQueriesMetadata(dirMeta.queries, true, directiveType);
}
var metadata = cpl.CompileDirectiveMetadata.create({
isHost: false,
selector: selector,
exportAs: util_2.noUndefined(dirMeta.exportAs),
isComponent: !!nonNormalizedTemplateMetadata,
type: this._getTypeMetadata(directiveType),
template: nonNormalizedTemplateMetadata,
changeDetection: changeDetectionStrategy,
inputs: dirMeta.inputs || [],
outputs: dirMeta.outputs || [],
host: dirMeta.host || {},
providers: providers || [],
viewProviders: viewProviders || [],
queries: queries || [],
guards: dirMeta.guards || {},
viewQueries: viewQueries || [],
entryComponents: entryComponentMetadata,
componentViewType: nonNormalizedTemplateMetadata ? this.getComponentViewClass(directiveType) :
null,
rendererType: nonNormalizedTemplateMetadata ? this.getRendererType(directiveType) : null,
componentFactory: null
});
if (nonNormalizedTemplateMetadata) {
metadata.componentFactory =
this.getComponentFactory(selector, directiveType, metadata.inputs, metadata.outputs);
}
cacheEntry = { metadata: metadata, annotation: dirMeta };
this._nonNormalizedDirectiveCache.set(directiveType, cacheEntry);
return cacheEntry;
};
/**
* Gets the metadata for the given directive.
* This assumes `loadNgModuleDirectiveAndPipeMetadata` has been called first.
*/
CompileMetadataResolver.prototype.getDirectiveMetadata = function (directiveType) {
var dirMeta = this._directiveCache.get(directiveType);
if (!dirMeta) {
this._reportError(util_2.syntaxError("Illegal state: getDirectiveMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Directive " + stringifyType(directiveType) + "."), directiveType);
}
return dirMeta;
};
CompileMetadataResolver.prototype.getDirectiveSummary = function (dirType) {
var dirSummary = this._loadSummary(dirType, cpl.CompileSummaryKind.Directive);
if (!dirSummary) {
this._reportError(util_2.syntaxError("Illegal state: Could not load the summary for directive " + stringifyType(dirType) + "."), dirType);
}
return dirSummary;
};
CompileMetadataResolver.prototype.isDirective = function (type) {
return !!this._loadSummary(type, cpl.CompileSummaryKind.Directive) ||
this._directiveResolver.isDirective(type);
};
CompileMetadataResolver.prototype.isAbstractDirective = function (type) {
var summary = this._loadSummary(type, cpl.CompileSummaryKind.Directive);
if (summary && !summary.isComponent) {
return !summary.selector;
}
var meta = this._directiveResolver.resolve(type, false);
if (meta && !core_1.createComponent.isTypeOf(meta)) {
return !meta.selector;
}
return false;
};
CompileMetadataResolver.prototype.isPipe = function (type) {
return !!this._loadSummary(type, cpl.CompileSummaryKind.Pipe) ||
this._pipeResolver.isPipe(type);
};
CompileMetadataResolver.prototype.isNgModule = function (type) {
return !!this._loadSummary(type, cpl.CompileSummaryKind.NgModule) ||
this._ngModuleResolver.isNgModule(type);
};
CompileMetadataResolver.prototype.getNgModuleSummary = function (moduleType, alreadyCollecting) {
if (alreadyCollecting === void 0) { alreadyCollecting = null; }
var moduleSummary = this._loadSummary(moduleType, cpl.CompileSummaryKind.NgModule);
if (!moduleSummary) {
var moduleMeta = this.getNgModuleMetadata(moduleType, false, alreadyCollecting);
moduleSummary = moduleMeta ? moduleMeta.toSummary() : null;
if (moduleSummary) {
this._summaryCache.set(moduleType, moduleSummary);
}
}
return moduleSummary;
};
/**
* Loads the declared directives and pipes of an NgModule.
*/
CompileMetadataResolver.prototype.loadNgModuleDirectiveAndPipeMetadata = function (moduleType, isSync, throwIfNotFound) {
var _this = this;
if (throwIfNotFound === void 0) { throwIfNotFound = true; }
var ngModule = this.getNgModuleMetadata(moduleType, throwIfNotFound);
var loading = [];
if (ngModule) {
ngModule.declaredDirectives.forEach(function (id) {
var promise = _this.loadDirectiveMetadata(moduleType, id.reference, isSync);
if (promise) {
loading.push(promise);
}
});
ngModule.declaredPipes.forEach(function (id) { return _this._loadPipeMetadata(id.reference); });
}
return Promise.all(loading);
};
CompileMetadataResolver.prototype.getShallowModuleMetadata = function (moduleType) {
var compileMeta = this._shallowModuleCache.get(moduleType);
if (compileMeta) {
return compileMeta;
}
var ngModuleMeta = directive_resolver_1.findLast(this._reflector.shallowAnnotations(moduleType), core_1.createNgModule.isTypeOf);
compileMeta = {
type: this._getTypeMetadata(moduleType),
rawExports: ngModuleMeta.exports,
rawImports: ngModuleMeta.imports,
rawProviders: ngModuleMeta.providers,
};
this._shallowModuleCache.set(moduleType, compileMeta);
return compileMeta;
};
CompileMetadataResolver.prototype.getNgModuleMetadata = function (moduleType, throwIfNotFound, alreadyCollecting) {
var _this = this;
if (throwIfNotFound === void 0) { throwIfNotFound = true; }
if (alreadyCollecting === void 0) { alreadyCollecting = null; }
moduleType = util_2.resolveForwardRef(moduleType);
var compileMeta = this._ngModuleCache.get(moduleType);
if (compileMeta) {
return compileMeta;
}
var meta = this._ngModuleResolver.resolve(moduleType, throwIfNotFound);
if (!meta) {
return null;
}
var declaredDirectives = [];
var exportedNonModuleIdentifiers = [];
var declaredPipes = [];
var importedModules = [];
var exportedModules = [];
var providers = [];
var entryComponents = [];
var bootstrapComponents = [];
var schemas = [];
if (meta.imports) {
flattenAndDedupeArray(meta.imports).forEach(function (importedType) {
var importedModuleType = undefined;
if (isValidType(importedType)) {
importedModuleType = importedType;
}
else if (importedType && importedType.ngModule) {
var moduleWithProviders = importedType;
importedModuleType = moduleWithProviders.ngModule;
if (moduleWithProviders.providers) {
providers.push.apply(providers, tslib_1.__spread(_this._getProvidersMetadata(moduleWithProviders.providers, entryComponents, "provider for the NgModule '" + stringifyType(importedModuleType) + "'", [], importedType)));
}
}
if (importedModuleType) {
if (_this._checkSelfImport(moduleType, importedModuleType))
return;
if (!alreadyCollecting)
alreadyCollecting = new Set();
if (alreadyCollecting.has(importedModuleType)) {
_this._reportError(util_2.syntaxError(_this._getTypeDescriptor(importedModuleType) + " '" + stringifyType(importedType) + "' is imported recursively by the module '" + stringifyType(moduleType) + "'."), moduleType);
return;
}
alreadyCollecting.add(importedModuleType);
var importedModuleSummary = _this.getNgModuleSummary(importedModuleType, alreadyCollecting);
alreadyCollecting.delete(importedModuleType);
if (!importedModuleSummary) {
_this._reportError(util_2.syntaxError("Unexpected " + _this._getTypeDescriptor(importedType) + " '" + stringifyType(importedType) + "' imported by the module '" + stringifyType(moduleType) + "'. Please add a @NgModule annotation."), moduleType);
return;
}
importedModules.push(importedModuleSummary);
}
else {
_this._reportError(util_2.syntaxError("Unexpected value '" + stringifyType(importedType) + "' imported by the module '" + stringifyType(moduleType) + "'"), moduleType);
return;
}
});
}
if (meta.exports) {
flattenAndDedupeArray(meta.exports).forEach(function (exportedType) {
if (!isValidType(exportedType)) {
_this._reportError(util_2.syntaxError("Unexpected value '" + stringifyType(exportedType) + "' exported by the module '" + stringifyType(moduleType) + "'"), moduleType);
return;
}
if (!alreadyCollecting)
alreadyCollecting = new Set();
if (alreadyCollecting.has(exportedType)) {
_this._reportError(util_2.syntaxError(_this._getTypeDescriptor(exportedType) + " '" + util_2.stringify(exportedType) + "' is exported recursively by the module '" + stringifyType(moduleType) + "'"), moduleType);
return;
}
alreadyCollecting.add(exportedType);
var exportedModuleSummary = _this.getNgModuleSummary(exportedType, alreadyCollecting);
alreadyCollecting.delete(exportedType);
if (exportedModuleSummary) {
exportedModules.push(exportedModuleSummary);
}
else {
exportedNonModuleIdentifiers.push(_this._getIdentifierMetadata(exportedType));
}
});
}
// Note: This will be modified later, so we rely on
// getting a new instance every time!
var transitiveModule = this._getTransitiveNgModuleMetadata(importedModules, exportedModules);
if (meta.declarations) {
flattenAndDedupeArray(meta.declarations).forEach(function (declaredType) {
if (!isValidType(declaredType)) {
_this._reportError(util_2.syntaxError("Unexpected value '" + stringifyType(declaredType) + "' declared by the module '" + stringifyType(moduleType) + "'"), moduleType);
return;
}
var declaredIdentifier = _this._getIdentifierMetadata(declaredType);
if (_this.isDirective(declaredType)) {
if (_this.isAbstractDirective(declaredType)) {
_this._reportError(util_2.syntaxError("Directive " + stringifyType(declaredType) + " has no selector, please add it!"), declaredType);
}
transitiveModule.addDirective(declaredIdentifier);
declaredDirectives.push(declaredIdentifier);
_this._addTypeToModule(declaredType, moduleType);
}
else if (_this.isPipe(declaredType)) {
transitiveModule.addPipe(declaredIdentifier);
transitiveModule.pipes.push(declaredIdentifier);
declaredPipes.push(declaredIdentifier);
_this._addTypeToModule(declaredType, moduleType);
}
else {
_this._reportError(util_2.syntaxError("Unexpected " + _this._getTypeDescriptor(declaredType) + " '" + stringifyType(declaredType) + "' declared by the module '" + stringifyType(moduleType) + "'. Please add a @Pipe/@Directive/@Component annotation."), moduleType);
return;
}
});
}
var exportedDirectives = [];
var exportedPipes = [];
exportedNonModuleIdentifiers.forEach(function (exportedId) {
if (transitiveModule.directivesSet.has(exportedId.reference)) {
exportedDirectives.push(exportedId);
transitiveModule.addExportedDirective(exportedId);
}
else if (transitiveModule.pipesSet.has(exportedId.reference)) {
exportedPipes.push(exportedId);
transitiveModule.addExportedPipe(exportedId);
}
else {
_this._reportError(util_2.syntaxError("Can't export " + _this._getTypeDescriptor(exportedId.reference) + " " + stringifyType(exportedId.reference) + " from " + stringifyType(moduleType) + " as it was neither declared nor imported!"), moduleType);
return;
}
});
// The providers of the module have to go last
// so that they overwrite any other provider we already added.
if (meta.providers) {
providers.push.apply(providers, tslib_1.__spread(this._getProvidersMetadata(meta.providers, entryComponents, "provider for the NgModule '" + stringifyType(moduleType) + "'", [], moduleType)));
}
if (meta.entryComponents) {
entryComponents.push.apply(entryComponents, tslib_1.__spread(flattenAndDedupeArray(meta.entryComponents)
.map(function (type) { return _this._getEntryComponentMetadata(type); })));
}
if (meta.bootstrap) {
flattenAndDedupeArray(meta.bootstrap).forEach(function (type) {
if (!isValidType(type)) {
_this._reportError(util_2.syntaxError("Unexpected value '" + stringifyType(type) + "' used in the bootstrap property of module '" + stringifyType(moduleType) + "'"), moduleType);
return;
}
bootstrapComponents.push(_this._getIdentifierMetadata(type));
});
}
entryComponents.push.apply(entryComponents, tslib_1.__spread(bootstrapComponents.map(function (type) { return _this._getEntryComponentMetadata(type.reference); })));
if (meta.schemas) {
schemas.push.apply(schemas, tslib_1.__spread(flattenAndDedupeArray(meta.schemas)));
}
compileMeta = new cpl.CompileNgModuleMetadata({
type: this._getTypeMetadata(moduleType),
providers: providers,
entryComponents: entryComponents,
bootstrapComponents: bootstrapComponents,
schemas: schemas,
declaredDirectives: declaredDirectives,
exportedDirectives: exportedDirectives,
declaredPipes: declaredPipes,
exportedPipes: exportedPipes,
importedModules: importedModules,
exportedModules: exportedModules,
transitiveModule: transitiveModule,
id: meta.id || null,
});
entryComponents.forEach(function (id) { return transitiveModule.addEntryComponent(id); });
providers.forEach(function (provider) { return transitiveModule.addProvider(provider, compileMeta.type); });
transitiveModule.addModule(compileMeta.type);
this._ngModuleCache.set(moduleType, compileMeta);
return compileMeta;
};
CompileMetadataResolver.prototype._checkSelfImport = function (moduleType, importedModuleType) {
if (moduleType === importedModuleType) {
this._reportError(util_2.syntaxError("'" + stringifyType(moduleType) + "' module can't import itself"), moduleType);
return true;
}
return false;
};
CompileMetadataResolver.prototype._getTypeDescriptor = function (type) {
if (isValidType(type)) {
if (this.isDirective(type)) {
return 'directive';
}
if (this.isPipe(type)) {
return 'pipe';
}
if (this.isNgModule(type)) {
return 'module';
}
}
if (type.provide) {
return 'provider';
}
return 'value';
};
CompileMetadataResolver.prototype._addTypeToModule = function (type, moduleType) {
var oldModule = this._ngModuleOfTypes.get(type);
if (oldModule && oldModule !== moduleType) {
this._reportError(util_2.syntaxError("Type " + stringifyType(type) + " is part of the declarations of 2 modules: " + stringifyType(oldModule) + " and " + stringifyType(moduleType) + "! " +
("Please consider moving " + stringifyType(type) + " to a higher module that imports " + stringifyType(oldModule) + " and " + stringifyType(moduleType) + ". ") +
("You can also create a new NgModule that exports and includes " + stringifyType(type) + " then import that NgModule in " + stringifyType(oldModule) + " and " + stringifyType(moduleType) + ".")), moduleType);
return;
}
this._ngModuleOfTypes.set(type, moduleType);
};
CompileMetadataResolver.prototype._getTransitiveNgModuleMetadata = function (importedModules, exportedModules) {
// collect `providers` / `entryComponents` from all imported and all exported modules
var result = new cpl.TransitiveCompileNgModuleMetadata();
var modulesByToken = new Map();
importedModules.concat(exportedModules).forEach(function (modSummary) {
modSummary.modules.forEach(function (mod) { return result.addModule(mod); });
modSummary.entryComponents.forEach(function (comp) { return result.addEntryComponent(comp); });
var addedTokens = new Set();
modSummary.providers.forEach(function (entry) {
var tokenRef = cpl.tokenReference(entry.provider.token);
var prevModules = modulesByToken.get(tokenRef);
if (!prevModules) {
prevModules = new Set();
modulesByToken.set(tokenRef, prevModules);
}
var moduleRef = entry.module.reference;
// Note: the providers of one module may still contain multiple providers
// per token (e.g. for multi providers), and we need to preserve these.
if (addedTokens.has(tokenRef) || !prevModules.has(moduleRef)) {
prevModules.add(moduleRef);
addedTokens.add(tokenRef);
result.addProvider(entry.provider, entry.module);
}
});
});
exportedModules.forEach(function (modSummary) {
modSummary.exportedDirectives.forEach(function (id) { return result.addExportedDirective(id); });
modSummary.exportedPipes.forEach(function (id) { return result.addExportedPipe(id); });
});
importedModules.forEach(function (modSummary) {
modSummary.exportedDirectives.forEach(function (id) { return result.addDirective(id); });
modSummary.exportedPipes.forEach(function (id) { return result.addPipe(id); });
});
return result;
};
CompileMetadataResolver.prototype._getIdentifierMetadata = function (type) {
type = util_2.resolveForwardRef(type);
return { reference: type };
};
CompileMetadataResolver.prototype.isInjectable = function (type) {
var annotations = this._reflector.tryAnnotations(type);
return annotations.some(function (ann) { return core_1.createInjectable.isTypeOf(ann); });
};
CompileMetadataResolver.prototype.getInjectableSummary = function (type) {
return {
summaryKind: cpl.CompileSummaryKind.Injectable,
type: this._getTypeMetadata(type, null, false)
};
};
CompileMetadataResolver.prototype.getInjectableMetadata = function (type, dependencies, throwOnUnknownDeps) {
if (dependencies === void 0) { dependencies = null; }
if (throwOnUnknownDeps === void 0) { throwOnUnknownDeps = true; }
var typeSummary = this._loadSummary(type, cpl.CompileSummaryKind.Injectable);
var typeMetadata = typeSummary ?
typeSummary.type :
this._getTypeMetadata(type, dependencies, throwOnUnknownDeps);
var annotations = this._reflector.annotations(type).filter(function (ann) { return core_1.createInjectable.isTypeOf(ann); });
if (annotations.length === 0) {
return null;
}
var meta = annotations[annotations.length - 1];
return {
symbol: type,
type: typeMetadata,
providedIn: meta.providedIn,
useValue: meta.useValue,
useClass: meta.useClass,
useExisting: meta.useExisting,
useFactory: meta.useFactory,
deps: meta.deps,
};
};
CompileMetadataResolver.prototype._getTypeMetadata = function (type, dependencies, throwOnUnknownDeps) {
if (dependencies === void 0) { dependencies = null; }
if (throwOnUnknownDeps === void 0) { throwOnUnknownDeps = true; }
var identifier = this._getIdentifierMetadata(type);
return {
reference: identifier.reference,
diDeps: this._getDependenciesMetadata(identifier.reference, dependencies, throwOnUnknownDeps),
lifecycleHooks: lifecycle_reflector_1.getAllLifecycleHooks(this._reflector, identifier.reference),
};
};
CompileMetadataResolver.prototype._getFactoryMetadata = function (factory, dependencies) {
if (dependencies === void 0) { dependencies = null; }
factory = util_2.resolveForwardRef(factory);
return { reference: factory, diDeps: this._getDependenciesMetadata(factory, dependencies) };
};
/**
* Gets the metadata for the given pipe.
* This assumes `loadNgModuleDirectiveAndPipeMetadata` has been called first.
*/
CompileMetadataResolver.prototype.getPipeMetadata = function (pipeType) {
var pipeMeta = this._pipeCache.get(pipeType);
if (!pipeMeta) {
this._reportError(util_2.syntaxError("Illegal state: getPipeMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Pipe " + stringifyType(pipeType) + "."), pipeType);
}
return pipeMeta || null;
};
CompileMetadataResolver.prototype.getPipeSummary = function (pipeType) {
var pipeSummary = this._loadSummary(pipeType, cpl.CompileSummaryKind.Pipe);
if (!pipeSummary) {
this._reportError(util_2.syntaxError("Illegal state: Could not load the summary for pipe " + stringifyType(pipeType) + "."), pipeType);
}
return pipeSummary;
};
CompileMetadataResolver.prototype.getOrLoadPipeMetadata = function (pipeType) {
var pipeMeta = this._pipeCache.get(pipeType);
if (!pipeMeta) {
pipeMeta = this._loadPipeMetadata(pipeType);
}
return pipeMeta;
};
CompileMetadataResolver.prototype._loadPipeMetadata = function (pipeType) {
pipeType = util_2.resolveForwardRef(pipeType);
var pipeAnnotation = this._pipeResolver.resolve(pipeType);
var pipeMeta = new cpl.CompilePipeMetadata({
type: this._getTypeMetadata(pipeType),
name: pipeAnnotation.name,
pure: !!pipeAnnotation.pure
});
this._pipeCache.set(pipeType, pipeMeta);
this._summaryCache.set(pipeType, pipeMeta.toSummary());
return pipeMeta;
};
CompileMetadataResolver.prototype._getDependenciesMetadata = function (typeOrFunc, dependencies, throwOnUnknownDeps) {
var _this = this;
if (throwOnUnknownDeps === void 0) { throwOnUnknownDeps = true; }
var hasUnknownDeps = false;
var params = dependencies || this._reflector.parameters(typeOrFunc) || [];
var dependenciesMetadata = params.map(function (param) {
var isAttribute = false;
var isHost = false;
var isSelf = false;
var isSkipSelf = false;
var isOptional = false;
var token = null;
if (Array.isArray(param)) {
param.forEach(function (paramEntry) {
if (core_1.createHost.isTypeOf(paramEntry)) {
isHost = true;
}
else if (core_1.createSelf.isTypeOf(paramEntry)) {
isSelf = true;
}
else if (core_1.createSkipSelf.isTypeOf(paramEntry)) {
isSkipSelf = true;
}
else if (core_1.createOptional.isTypeOf(paramEntry)) {
isOptional = true;
}
else if (core_1.createAttribute.isTypeOf(paramEntry)) {
isAttribute = true;
token = paramEntry.attributeName;
}
else if (core_1.createInject.isTypeOf(paramEntry)) {
token = paramEntry.token;
}
else if (core_1.createInjectionToken.isTypeOf(paramEntry) ||
paramEntry instanceof static_symbol_1.StaticSymbol) {
token = paramEntry;
}
else if (isValidType(paramEntry) && token == null) {
token = paramEntry;
}
});
}
else {
token = param;
}
if (token == null) {
hasUnknownDeps = true;
return {};
}
return {
isAttribute: isAttribute,
isHost: isHost,
isSelf: isSelf,
isSkipSelf: isSkipSelf,
isOptional: isOptional,
token: _this._getTokenMetadata(token)
};
});
if (hasUnknownDeps) {
var depsTokens = dependenciesMetadata.map(function (dep) { return dep.token ? stringifyType(dep.token) : '?'; }).join(', ');
var message = "Can't resolve all parameters for " + stringifyType(typeOrFunc) + ": (" + depsTokens + ").";
if (throwOnUnknownDeps || this._config.strictInjectionParameters) {
this._reportError(util_2.syntaxError(message), typeOrFunc);
}
}
return dependenciesMetadata;
};
CompileMetadataResolver.prototype._getTokenMetadata = function (token) {
token = util_2.resolveForwardRef(token);
var compileToken;
if (typeof token === 'string') {
compileToken = { value: token };
}
else {
compileToken = { identifier: { reference: token } };
}
return compileToken;
};
CompileMetadataResolver.prototype._getProvidersMetadata = function (providers, targetEntryComponents, debugInfo, compileProviders, type) {
var _this = this;
if (compileProviders === void 0) { compileProviders = []; }
providers.forEach(function (provider, providerIdx) {
if (Array.isArray(provider)) {
_this._getProvidersMetadata(provider, targetEntryComponents, debugInfo, compileProviders);
}
else {
provider = util_2.resolveForwardRef(provider);
var providerMeta = undefined;
if (provider && typeof provider === 'object' && provider.hasOwnProperty('provide')) {
_this._validateProvider(provider);
providerMeta = new cpl.ProviderMeta(provider.provide, provider);
}
else if (isValidType(provider)) {
providerMeta = new cpl.ProviderMeta(provider, { useClass: provider });
}
else if (provider === void 0) {
_this._reportError(util_2.syntaxError("Encountered undefined provider! Usually this means you have a circular dependencies. This might be caused by using 'barrel' index.ts files."));
return;
}
else {
var providersInfo = providers
.reduce(function (soFar, seenProvider, seenProviderIdx) {
if (seenProviderIdx < providerIdx) {
soFar.push("" + stringifyType(seenProvider));
}
else if (seenProviderIdx == providerIdx) {
soFar.push("?" + stringifyType(seenProvider) + "?");
}
else if (seenProviderIdx == providerIdx + 1) {
soFar.push('...');
}
return soFar;
}, [])
.join(', ');
_this._reportError(util_2.syntaxError("Invalid " + (debugInfo ?
debugInfo :
'provider') + " - only instances of Provider and Type are allowed, got: [" + providersInfo + "]"), type);
return;
}
if (providerMeta.token ===
_this._reflector.resolveExternalReference(identifiers_1.Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS)) {
targetEntryComponents.push.apply(targetEntryComponents, tslib_1.__spread(_this._getEntryComponentsFromProvider(providerMeta, type)));
}
else {
compileProviders.push(_this.getProviderMetadata(providerMeta));