2016-06-23 09:47:54 -07:00
/**
* @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
*/
2016-09-12 19:14:17 -07:00
import { AnimationAnimateMetadata , AnimationEntryMetadata , AnimationGroupMetadata , AnimationKeyframesSequenceMetadata , AnimationMetadata , AnimationStateDeclarationMetadata , AnimationStateMetadata , AnimationStateTransitionMetadata , AnimationStyleMetadata , AnimationWithStepsMetadata , Attribute , ChangeDetectionStrategy , Component , Host , Inject , Injectable , ModuleWithProviders , Optional , Provider , Query , SchemaMetadata , Self , SkipSelf , Type , resolveForwardRef } from '@angular/core' ;
2016-06-08 16:38:52 -07:00
2016-06-20 09:52:41 -07:00
import { assertArrayOfStrings , assertInterpolationSymbols } from './assertions' ;
2016-01-06 14:13:44 -08:00
import * as cpl from './compile_metadata' ;
import { DirectiveResolver } from './directive_resolver' ;
2016-10-19 13:42:39 -07:00
import { isBlank , isPresent , stringify } from './facade/lang' ;
2016-08-24 17:39:49 -07:00
import { Identifiers , resolveIdentifierToken } from './identifiers' ;
2016-08-02 01:37:42 -07:00
import { hasLifecycleHook } from './lifecycle_reflector' ;
2016-07-18 03:50:31 -07:00
import { NgModuleResolver } from './ng_module_resolver' ;
2016-01-06 14:13:44 -08:00
import { PipeResolver } from './pipe_resolver' ;
2016-08-30 18:07:40 -07:00
import { LIFECYCLE_HOOKS_VALUES , ReflectorReader , reflector } from './private_import_core' ;
2016-07-28 19:39:10 +02:00
import { ElementSchemaRegistry } from './schema/element_schema_registry' ;
2016-04-28 17:50:03 -07:00
import { getUrlScheme } from './url_resolver' ;
2016-06-08 16:38:52 -07:00
import { MODULE_SUFFIX , ValueTransformer , sanitizeIdentifier , visitValue } from './util' ;
2016-04-28 17:50:03 -07:00
2015-09-14 15:59:09 -07:00
@Injectable ()
2016-02-18 10:53:21 -08:00
export class CompileMetadataResolver {
2016-08-10 18:21:28 -07:00
private _directiveCache = new Map < Type < any >, cpl.CompileDirectiveMetadata >();
private _pipeCache = new Map < Type < any >, cpl.CompilePipeMetadata >();
private _ngModuleCache = new Map < Type < any >, cpl.CompileNgModuleMetadata >();
private _ngModuleOfTypes = new Map < Type < any >, Type < any >>();
2016-03-29 17:15:07 -07:00
private _anonymousTypes = new Map < Object , number >();
private _anonymousTypeIndex = 0 ;
2015-09-14 15:59:09 -07:00
2016-06-08 16:38:52 -07:00
constructor (
2016-07-18 03:50:31 -07:00
private _ngModuleResolver : NgModuleResolver , private _directiveResolver : DirectiveResolver ,
2016-08-19 13:51:45 -07:00
private _pipeResolver : PipeResolver , private _schemaRegistry : ElementSchemaRegistry ,
2016-07-29 02:10:30 -07:00
private _reflector : ReflectorReader = reflector ) {}
2015-09-14 15:59:09 -07:00
2016-04-20 18:10:19 -07:00
private sanitizeTokenName ( token : any ) : string {
let identifier = stringify ( token );
if ( identifier . indexOf ( '(' ) >= 0 ) {
// case: anonymous functions!
let found = this . _anonymousTypes . get ( token );
2016-09-14 15:58:18 -07:00
if ( ! found ) {
2016-04-20 18:10:19 -07:00
this . _anonymousTypes . set ( token , this . _anonymousTypeIndex ++ );
found = this . _anonymousTypes . get ( token );
}
identifier = `anonymous_token_ ${ found } _` ;
2016-03-29 17:15:07 -07:00
}
2016-04-20 18:10:19 -07:00
return sanitizeIdentifier ( identifier );
2016-03-29 17:15:07 -07:00
}
2016-08-10 18:21:28 -07:00
clearCacheFor ( type : Type < any >) {
2016-06-28 09:54:42 -07:00
this . _directiveCache . delete ( type );
this . _pipeCache . delete ( type );
2016-07-18 03:50:31 -07:00
this . _ngModuleOfTypes . delete ( type );
2016-09-12 19:14:17 -07:00
// Clear all of the NgModule as they contain transitive information!
2016-07-18 03:50:31 -07:00
this . _ngModuleCache . clear ();
2016-06-24 08:46:43 -07:00
}
clearCache() {
this . _directiveCache . clear ();
this . _pipeCache . clear ();
2016-07-18 03:50:31 -07:00
this . _ngModuleCache . clear ();
this . _ngModuleOfTypes . clear ();
2016-06-24 08:46:43 -07:00
}
2016-05-26 15:07:51 -07:00
getAnimationEntryMetadata ( entry : AnimationEntryMetadata ) : cpl . CompileAnimationEntryMetadata {
2016-09-14 15:58:18 -07:00
const defs = entry . definitions . map ( def => this . getAnimationStateMetadata ( def ));
2016-05-25 12:46:22 -07:00
return new cpl . CompileAnimationEntryMetadata ( entry . name , defs );
}
2016-05-26 15:07:51 -07:00
getAnimationStateMetadata ( value : AnimationStateMetadata ) : cpl . CompileAnimationStateMetadata {
if ( value instanceof AnimationStateDeclarationMetadata ) {
2016-09-14 15:58:18 -07:00
const styles = this . getAnimationStyleMetadata ( value . styles );
2016-05-25 12:46:22 -07:00
return new cpl . CompileAnimationStateDeclarationMetadata ( value . stateNameExpr , styles );
2016-09-14 15:58:18 -07:00
}
if ( value instanceof AnimationStateTransitionMetadata ) {
2016-06-08 16:38:52 -07:00
return new cpl . CompileAnimationStateTransitionMetadata (
value . stateChangeExpr , this . getAnimationMetadata ( value . steps ));
2016-05-25 12:46:22 -07:00
}
2016-09-14 15:58:18 -07:00
2016-05-25 12:46:22 -07:00
return null ;
}
2016-05-26 15:07:51 -07:00
getAnimationStyleMetadata ( value : AnimationStyleMetadata ) : cpl . CompileAnimationStyleMetadata {
2016-05-25 12:46:22 -07:00
return new cpl . CompileAnimationStyleMetadata ( value . offset , value . styles );
}
2016-05-26 15:07:51 -07:00
getAnimationMetadata ( value : AnimationMetadata ) : cpl . CompileAnimationMetadata {
if ( value instanceof AnimationStyleMetadata ) {
2016-05-25 12:46:22 -07:00
return this . getAnimationStyleMetadata ( value );
2016-09-14 15:58:18 -07:00
}
if ( value instanceof AnimationKeyframesSequenceMetadata ) {
2016-06-08 16:38:52 -07:00
return new cpl . CompileAnimationKeyframesSequenceMetadata (
value . steps . map ( entry => this . getAnimationStyleMetadata ( entry )));
2016-09-14 15:58:18 -07:00
}
if ( value instanceof AnimationAnimateMetadata ) {
const animateData =
2016-06-08 16:38:52 -07:00
< cpl.CompileAnimationStyleMetadata | cpl.CompileAnimationKeyframesSequenceMetadata > this
. getAnimationMetadata ( value . styles );
2016-05-25 12:46:22 -07:00
return new cpl . CompileAnimationAnimateMetadata ( value . timings , animateData );
2016-09-14 15:58:18 -07:00
}
if ( value instanceof AnimationWithStepsMetadata ) {
const steps = value . steps . map ( step => this . getAnimationMetadata ( step ));
2016-05-26 15:07:51 -07:00
if ( value instanceof AnimationGroupMetadata ) {
2016-05-25 12:46:22 -07:00
return new cpl . CompileAnimationGroupMetadata ( steps );
}
2016-09-14 15:58:18 -07:00
return new cpl . CompileAnimationSequenceMetadata ( steps );
2016-05-25 12:46:22 -07:00
}
return null ;
}
2016-10-13 16:34:37 -07:00
getDirectiveMetadata ( directiveType : any , throwIfNotFound = true ) : cpl . CompileDirectiveMetadata {
2016-06-28 09:54:42 -07:00
directiveType = resolveForwardRef ( directiveType );
2016-09-14 15:58:18 -07:00
let meta = this . _directiveCache . get ( directiveType );
if ( ! meta ) {
const dirMeta = this . _directiveResolver . resolve ( directiveType , throwIfNotFound );
2016-07-18 03:50:31 -07:00
if ( ! dirMeta ) {
return null ;
}
2016-09-14 15:58:18 -07:00
let templateMeta : cpl.CompileTemplateMetadata = null ;
let changeDetectionStrategy : ChangeDetectionStrategy = null ;
let viewProviders : Array < cpl.CompileProviderMetadata | cpl.CompileTypeMetadata | any [] > = [];
let moduleUrl = staticTypeModuleUrl ( directiveType );
let entryComponentMetadata : cpl.CompileTypeMetadata [] = [];
2016-07-28 19:39:10 +02:00
let selector = dirMeta . selector ;
2016-09-14 15:58:18 -07:00
2016-09-12 19:14:17 -07:00
if ( dirMeta instanceof Component ) {
2016-09-14 15:58:18 -07:00
// Component
assertArrayOfStrings ( 'styles' , dirMeta . styles );
assertArrayOfStrings ( 'styleUrls' , dirMeta . styleUrls );
assertInterpolationSymbols ( 'interpolation' , dirMeta . interpolation );
const animations = dirMeta . animations ?
dirMeta . animations . map ( e => this . getAnimationEntryMetadata ( e )) :
2016-06-08 16:38:52 -07:00
null ;
2016-05-25 12:46:22 -07:00
2015-09-18 10:33:23 -07:00
templateMeta = new cpl . CompileTemplateMetadata ({
2016-09-14 15:58:18 -07:00
encapsulation : dirMeta.encapsulation ,
template : dirMeta.template ,
templateUrl : dirMeta.templateUrl ,
styles : dirMeta.styles ,
styleUrls : dirMeta.styleUrls ,
2016-06-20 09:52:41 -07:00
animations : animations ,
2016-09-14 15:58:18 -07:00
interpolation : dirMeta.interpolation
2015-09-14 15:59:09 -07:00
});
2016-09-14 15:58:18 -07:00
changeDetectionStrategy = dirMeta . changeDetection ;
if ( dirMeta . viewProviders ) {
2016-06-22 02:27:27 +02:00
viewProviders = this . getProvidersMetadata (
2016-08-24 01:18:41 +02:00
dirMeta . viewProviders , entryComponentMetadata ,
`viewProviders for " ${ stringify ( directiveType ) } "` );
2016-01-06 14:13:44 -08:00
}
2016-09-14 15:58:18 -07:00
moduleUrl = componentModuleUrl ( this . _reflector , directiveType , dirMeta );
if ( dirMeta . entryComponents ) {
2016-08-19 13:51:45 -07:00
entryComponentMetadata =
2016-10-28 14:08:54 -07:00
flattenAndDedupeArray ( dirMeta . entryComponents )
2016-08-19 13:51:45 -07:00
. map (( type ) => this . getTypeMetadata ( type , staticTypeModuleUrl ( type )))
. concat ( entryComponentMetadata );
2016-06-22 14:06:23 -07:00
}
2016-07-28 19:39:10 +02:00
if ( ! selector ) {
selector = this . _schemaRegistry . getDefaultComponentElementName ();
}
} else {
2016-09-14 15:58:18 -07:00
// Directive
2016-07-28 19:39:10 +02:00
if ( ! selector ) {
2016-08-25 00:50:16 -07:00
throw new Error ( `Directive ${ stringify ( directiveType ) } has no selector, please add it!` );
2016-07-28 19:39:10 +02:00
}
2016-01-06 14:13:44 -08:00
}
2016-09-14 15:58:18 -07:00
let providers : Array < cpl.CompileProviderMetadata | cpl.CompileTypeMetadata | any [] > = [];
2016-01-06 14:13:44 -08:00
if ( isPresent ( dirMeta . providers )) {
2016-06-22 02:27:27 +02:00
providers = this . getProvidersMetadata (
2016-08-24 01:18:41 +02:00
dirMeta . providers , entryComponentMetadata ,
`providers for " ${ stringify ( directiveType ) } "` );
2016-01-06 14:13:44 -08:00
}
2016-09-14 15:58:18 -07:00
let queries : cpl.CompileQueryMetadata [] = [];
let viewQueries : cpl.CompileQueryMetadata [] = [];
2016-01-06 14:13:44 -08:00
if ( isPresent ( dirMeta . queries )) {
2016-06-05 04:46:03 +02:00
queries = this . getQueriesMetadata ( dirMeta . queries , false , directiveType );
viewQueries = this . getQueriesMetadata ( dirMeta . queries , true , directiveType );
2015-09-14 15:59:09 -07:00
}
2016-09-14 15:58:18 -07:00
2015-09-18 10:33:23 -07:00
meta = cpl . CompileDirectiveMetadata . create ({
2016-07-28 19:39:10 +02:00
selector : selector ,
2015-10-23 15:55:48 -07:00
exportAs : dirMeta.exportAs ,
2016-09-14 15:58:18 -07:00
isComponent : !! templateMeta ,
2016-05-02 16:45:43 -07:00
type : this . getTypeMetadata ( directiveType , moduleUrl ),
2015-09-14 15:59:09 -07:00
template : templateMeta ,
2015-09-18 10:33:23 -07:00
changeDetection : changeDetectionStrategy ,
2015-10-23 15:55:48 -07:00
inputs : dirMeta.inputs ,
outputs : dirMeta.outputs ,
host : dirMeta.host ,
2016-01-06 14:13:44 -08:00
providers : providers ,
viewProviders : viewProviders ,
queries : queries ,
2016-06-22 14:06:23 -07:00
viewQueries : viewQueries ,
2016-08-19 13:51:45 -07:00
entryComponents : entryComponentMetadata
2015-09-14 15:59:09 -07:00
});
2015-12-02 10:35:51 -08:00
this . _directiveCache . set ( directiveType , meta );
}
return meta ;
}
2016-07-18 03:50:31 -07:00
getNgModuleMetadata ( moduleType : any , throwIfNotFound = true ) : cpl . CompileNgModuleMetadata {
2016-06-28 09:54:42 -07:00
moduleType = resolveForwardRef ( moduleType );
2016-09-14 15:58:18 -07:00
let compileMeta = this . _ngModuleCache . get ( moduleType );
2016-07-18 03:50:31 -07:00
if ( ! compileMeta ) {
const meta = this . _ngModuleResolver . resolve ( moduleType , throwIfNotFound );
2016-06-28 09:54:42 -07:00
if ( ! meta ) {
2016-07-18 03:50:31 -07:00
return null ;
2016-06-28 09:54:42 -07:00
}
2016-07-18 03:50:31 -07:00
const declaredDirectives : cpl.CompileDirectiveMetadata [] = [];
const exportedDirectives : cpl.CompileDirectiveMetadata [] = [];
const declaredPipes : cpl.CompilePipeMetadata [] = [];
const exportedPipes : cpl.CompilePipeMetadata [] = [];
const importedModules : cpl.CompileNgModuleMetadata [] = [];
const exportedModules : cpl.CompileNgModuleMetadata [] = [];
2016-07-25 01:39:50 -07:00
const providers : any [] = [];
const entryComponents : cpl.CompileTypeMetadata [] = [];
2016-08-02 06:54:08 -07:00
const bootstrapComponents : cpl.CompileTypeMetadata [] = [];
2016-07-25 03:02:57 -07:00
const schemas : SchemaMetadata [] = [];
2016-07-18 03:50:31 -07:00
if ( meta . imports ) {
2016-10-28 14:08:54 -07:00
flattenAndDedupeArray ( meta . imports ). forEach (( importedType ) => {
2016-08-10 18:21:28 -07:00
let importedModuleType : Type < any >;
2016-07-25 01:39:50 -07:00
if ( isValidType ( importedType )) {
importedModuleType = importedType ;
} else if ( importedType && importedType . ngModule ) {
const moduleWithProviders : ModuleWithProviders = importedType ;
importedModuleType = moduleWithProviders . ngModule ;
if ( moduleWithProviders . providers ) {
2016-08-24 01:18:41 +02:00
providers . push (... this . getProvidersMetadata (
moduleWithProviders . providers , entryComponents ,
`provider for the NgModule ' ${ stringify ( importedModuleType ) } '` ));
2016-07-25 01:39:50 -07:00
}
2016-07-18 03:50:31 -07:00
}
2016-09-14 15:58:18 -07:00
2016-07-25 01:39:50 -07:00
if ( importedModuleType ) {
2016-09-14 15:58:18 -07:00
const importedMeta = this . getNgModuleMetadata ( importedModuleType , false );
2016-08-17 15:57:02 -07:00
if ( importedMeta === null ) {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-08-17 15:57:02 -07:00
`Unexpected ${ this . _getTypeDescriptor ( importedType ) } ' ${ stringify ( importedType ) } ' imported by the module ' ${ stringify ( moduleType ) } '` );
}
importedModules . push ( importedMeta );
2016-07-18 03:50:31 -07:00
} else {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-07-18 03:50:31 -07:00
`Unexpected value ' ${ stringify ( importedType ) } ' imported by the module ' ${ stringify ( moduleType ) } '` );
}
2016-06-28 09:54:42 -07:00
});
}
2016-07-18 03:50:31 -07:00
if ( meta . exports ) {
2016-10-28 14:08:54 -07:00
flattenAndDedupeArray ( meta . exports ). forEach (( exportedType ) => {
2016-07-18 03:50:31 -07:00
if ( ! isValidType ( exportedType )) {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-07-18 03:50:31 -07:00
`Unexpected value ' ${ stringify ( exportedType ) } ' exported by the module ' ${ stringify ( moduleType ) } '` );
}
let exportedDirMeta : cpl.CompileDirectiveMetadata ;
let exportedPipeMeta : cpl.CompilePipeMetadata ;
let exportedModuleMeta : cpl.CompileNgModuleMetadata ;
if ( exportedDirMeta = this . getDirectiveMetadata ( exportedType , false )) {
exportedDirectives . push ( exportedDirMeta );
} else if ( exportedPipeMeta = this . getPipeMetadata ( exportedType , false )) {
exportedPipes . push ( exportedPipeMeta );
} else if ( exportedModuleMeta = this . getNgModuleMetadata ( exportedType , false )) {
exportedModules . push ( exportedModuleMeta );
} else {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-08-17 15:57:02 -07:00
`Unexpected ${ this . _getTypeDescriptor ( exportedType ) } ' ${ stringify ( exportedType ) } ' exported by the module ' ${ stringify ( moduleType ) } '` );
2016-07-18 03:50:31 -07:00
}
});
}
// Note: This will be modified later, so we rely on
// getting a new instance every time!
const transitiveModule =
this . _getTransitiveNgModuleMetadata ( importedModules , exportedModules );
if ( meta . declarations ) {
2016-10-28 14:08:54 -07:00
flattenAndDedupeArray ( meta . declarations ). forEach (( declaredType ) => {
2016-07-18 03:50:31 -07:00
if ( ! isValidType ( declaredType )) {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-07-18 03:50:31 -07:00
`Unexpected value ' ${ stringify ( declaredType ) } ' declared by the module ' ${ stringify ( moduleType ) } '` );
}
let declaredDirMeta : cpl.CompileDirectiveMetadata ;
let declaredPipeMeta : cpl.CompilePipeMetadata ;
if ( declaredDirMeta = this . getDirectiveMetadata ( declaredType , false )) {
this . _addDirectiveToModule (
declaredDirMeta , moduleType , transitiveModule , declaredDirectives , true );
} else if ( declaredPipeMeta = this . getPipeMetadata ( declaredType , false )) {
this . _addPipeToModule (
declaredPipeMeta , moduleType , transitiveModule , declaredPipes , true );
} else {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-08-17 15:57:02 -07:00
`Unexpected ${ this . _getTypeDescriptor ( declaredType ) } ' ${ stringify ( declaredType ) } ' declared by the module ' ${ stringify ( moduleType ) } '` );
2016-07-18 03:50:31 -07:00
}
});
}
2016-07-27 01:52:31 -07:00
// The providers of the module have to go last
// so that they overwrite any other provider we already added.
if ( meta . providers ) {
2016-08-24 01:18:41 +02:00
providers . push (... this . getProvidersMetadata (
meta . providers , entryComponents ,
`provider for the NgModule ' ${ stringify ( moduleType ) } '` ));
2016-07-27 01:52:31 -07:00
}
2016-09-14 15:58:18 -07:00
2016-07-27 01:52:31 -07:00
if ( meta . entryComponents ) {
entryComponents . push (
2016-10-28 14:08:54 -07:00
... flattenAndDedupeArray ( meta . entryComponents )
2016-07-27 01:52:31 -07:00
. map ( type => this . getTypeMetadata ( type , staticTypeModuleUrl ( type ))));
}
2016-09-14 15:58:18 -07:00
2016-08-02 06:54:08 -07:00
if ( meta . bootstrap ) {
2016-10-28 14:08:54 -07:00
const typeMetadata = flattenAndDedupeArray ( meta . bootstrap ). map ( type => {
2016-09-06 09:55:48 -07:00
if ( ! isValidType ( type )) {
throw new Error (
`Unexpected value ' ${ stringify ( type ) } ' used in the bootstrap property of module ' ${ stringify ( moduleType ) } '` );
}
return this . getTypeMetadata ( type , staticTypeModuleUrl ( type ));
});
bootstrapComponents . push (... typeMetadata );
2016-08-02 06:54:08 -07:00
}
2016-09-14 15:58:18 -07:00
2016-08-02 06:54:08 -07:00
entryComponents . push (... bootstrapComponents );
2016-09-14 15:58:18 -07:00
2016-07-27 01:52:31 -07:00
if ( meta . schemas ) {
2016-10-28 14:08:54 -07:00
schemas . push (... flattenAndDedupeArray ( meta . schemas ));
2016-07-27 01:52:31 -07:00
}
2016-07-25 00:36:30 -07:00
transitiveModule . entryComponents . push (... entryComponents );
2016-07-18 03:50:31 -07:00
transitiveModule . providers . push (... providers );
compileMeta = new cpl . CompileNgModuleMetadata ({
2016-06-28 09:54:42 -07:00
type : this . getTypeMetadata ( moduleType , staticTypeModuleUrl ( moduleType )),
2016-09-14 15:58:18 -07:00
providers ,
entryComponents ,
bootstrapComponents ,
schemas ,
declaredDirectives ,
exportedDirectives ,
declaredPipes ,
exportedPipes ,
importedModules ,
exportedModules ,
transitiveModule ,
2016-09-01 13:46:08 -07:00
id : meta.id ,
2016-06-28 09:54:42 -07:00
});
2016-09-14 15:58:18 -07:00
2016-07-18 03:50:31 -07:00
transitiveModule . modules . push ( compileMeta );
this . _verifyModule ( compileMeta );
this . _ngModuleCache . set ( moduleType , compileMeta );
2016-06-28 09:54:42 -07:00
}
return compileMeta ;
}
2016-07-18 03:50:31 -07:00
private _verifyModule ( moduleMeta : cpl.CompileNgModuleMetadata ) {
moduleMeta . exportedDirectives . forEach (( dirMeta ) => {
2016-08-29 08:52:25 -07:00
if ( ! moduleMeta . transitiveModule . directivesSet . has ( dirMeta . type . reference )) {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-08-29 08:52:25 -07:00
`Can't export directive ${ stringify ( dirMeta . type . reference ) } from ${ stringify ( moduleMeta . type . reference ) } as it was neither declared nor imported!` );
2016-02-18 10:53:21 -08:00
}
2016-07-18 03:50:31 -07:00
});
2016-09-14 15:58:18 -07:00
2016-07-18 03:50:31 -07:00
moduleMeta . exportedPipes . forEach (( pipeMeta ) => {
2016-08-29 08:52:25 -07:00
if ( ! moduleMeta . transitiveModule . pipesSet . has ( pipeMeta . type . reference )) {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-08-29 08:52:25 -07:00
`Can't export pipe ${ stringify ( pipeMeta . type . reference ) } from ${ stringify ( moduleMeta . type . reference ) } as it was neither declared nor imported!` );
2016-07-18 03:50:31 -07:00
}
});
}
2016-08-17 15:57:02 -07:00
private _getTypeDescriptor ( type : Type < any >) : string {
2016-10-24 13:28:23 -07:00
if ( this . _directiveResolver . resolve ( type , false )) {
2016-08-17 15:57:02 -07:00
return 'directive' ;
}
2016-09-14 15:58:18 -07:00
2016-10-24 13:28:23 -07:00
if ( this . _pipeResolver . resolve ( type , false )) {
2016-09-14 15:58:18 -07:00
return 'pipe' ;
}
2016-10-24 13:28:23 -07:00
if ( this . _ngModuleResolver . resolve ( type , false )) {
2016-09-14 15:58:18 -07:00
return 'module' ;
}
if (( type as any ). provide ) {
return 'provider' ;
}
return 'value' ;
2016-08-17 15:57:02 -07:00
}
2016-08-10 18:21:28 -07:00
private _addTypeToModule ( type : Type < any >, moduleType : Type < any >) {
2016-07-18 03:50:31 -07:00
const oldModule = this . _ngModuleOfTypes . get ( type );
if ( oldModule && oldModule !== moduleType ) {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-09-07 14:09:25 -07:00
`Type ${ stringify ( type ) } is part of the declarations of 2 modules: ${ stringify ( oldModule ) } and ${ stringify ( moduleType ) } ! ` +
`Please consider moving ${ stringify ( type ) } to a higher module that imports ${ stringify ( oldModule ) } and ${ stringify ( moduleType ) } . ` +
`You can also create a new NgModule that exports and includes ${ stringify ( type ) } then import that NgModule in ${ stringify ( oldModule ) } and ${ stringify ( moduleType ) } .` );
2016-02-18 10:53:21 -08:00
}
2016-07-18 03:50:31 -07:00
this . _ngModuleOfTypes . set ( type , moduleType );
}
private _getTransitiveNgModuleMetadata (
importedModules : cpl.CompileNgModuleMetadata [],
exportedModules : cpl.CompileNgModuleMetadata []) : cpl . TransitiveCompileNgModuleMetadata {
2016-07-25 00:36:30 -07:00
// collect `providers` / `entryComponents` from all imported and all exported modules
2016-07-18 03:50:31 -07:00
const transitiveModules = getTransitiveModules ( importedModules . concat ( exportedModules ), true );
const providers = flattenArray ( transitiveModules . map (( ngModule ) => ngModule . providers ));
2016-07-25 00:36:30 -07:00
const entryComponents =
flattenArray ( transitiveModules . map (( ngModule ) => ngModule . entryComponents ));
2016-07-18 03:50:31 -07:00
const transitiveExportedModules = getTransitiveModules ( importedModules , false );
const directives =
flattenArray ( transitiveExportedModules . map (( ngModule ) => ngModule . exportedDirectives ));
const pipes = flattenArray ( transitiveExportedModules . map (( ngModule ) => ngModule . exportedPipes ));
return new cpl . TransitiveCompileNgModuleMetadata (
2016-07-25 00:36:30 -07:00
transitiveModules , providers , entryComponents , directives , pipes );
2016-07-18 03:50:31 -07:00
}
private _addDirectiveToModule (
dirMeta : cpl.CompileDirectiveMetadata , moduleType : any ,
transitiveModule : cpl.TransitiveCompileNgModuleMetadata ,
declaredDirectives : cpl.CompileDirectiveMetadata [], force : boolean = false ) : boolean {
2016-08-29 08:52:25 -07:00
if ( force || ! transitiveModule . directivesSet . has ( dirMeta . type . reference )) {
transitiveModule . directivesSet . add ( dirMeta . type . reference );
2016-07-18 03:50:31 -07:00
transitiveModule . directives . push ( dirMeta );
declaredDirectives . push ( dirMeta );
2016-08-29 08:52:25 -07:00
this . _addTypeToModule ( dirMeta . type . reference , moduleType );
2016-07-18 03:50:31 -07:00
return true ;
}
return false ;
}
private _addPipeToModule (
pipeMeta : cpl.CompilePipeMetadata , moduleType : any ,
transitiveModule : cpl.TransitiveCompileNgModuleMetadata ,
declaredPipes : cpl.CompilePipeMetadata [], force : boolean = false ) : boolean {
2016-08-29 08:52:25 -07:00
if ( force || ! transitiveModule . pipesSet . has ( pipeMeta . type . reference )) {
transitiveModule . pipesSet . add ( pipeMeta . type . reference );
2016-07-18 03:50:31 -07:00
transitiveModule . pipes . push ( pipeMeta );
declaredPipes . push ( pipeMeta );
2016-08-29 08:52:25 -07:00
this . _addTypeToModule ( pipeMeta . type . reference , moduleType );
2016-07-18 03:50:31 -07:00
return true ;
}
return false ;
2016-02-18 10:53:21 -08:00
}
2016-08-10 18:21:28 -07:00
getTypeMetadata ( type : Type < any >, moduleUrl : string , dependencies : any [] = null ) :
2016-06-18 18:42:34 +02:00
cpl . CompileTypeMetadata {
2016-06-28 09:54:42 -07:00
type = resolveForwardRef ( type );
2016-01-06 14:13:44 -08:00
return new cpl . CompileTypeMetadata ({
2016-04-20 18:10:19 -07:00
name : this.sanitizeTokenName ( type ),
2016-09-14 15:58:18 -07:00
moduleUrl ,
2016-08-29 08:52:25 -07:00
reference : type ,
2016-08-02 01:12:24 -07:00
diDeps : this.getDependenciesMetadata ( type , dependencies ),
lifecycleHooks : LIFECYCLE_HOOKS_VALUES.filter ( hook => hasLifecycleHook ( hook , type )),
2016-01-06 14:13:44 -08:00
});
}
2016-06-18 18:42:34 +02:00
getFactoryMetadata ( factory : Function , moduleUrl : string , dependencies : any [] = null ) :
cpl . CompileFactoryMetadata {
2016-06-28 09:54:42 -07:00
factory = resolveForwardRef ( factory );
2016-01-06 14:13:44 -08:00
return new cpl . CompileFactoryMetadata ({
2016-04-20 18:10:19 -07:00
name : this.sanitizeTokenName ( factory ),
2016-09-14 15:58:18 -07:00
moduleUrl ,
2016-08-29 08:52:25 -07:00
reference : factory ,
2016-06-18 18:42:34 +02:00
diDeps : this.getDependenciesMetadata ( factory , dependencies )
2016-01-06 14:13:44 -08:00
});
}
2016-08-10 18:21:28 -07:00
getPipeMetadata ( pipeType : Type < any >, throwIfNotFound = true ) : cpl . CompilePipeMetadata {
2016-06-28 09:54:42 -07:00
pipeType = resolveForwardRef ( pipeType );
2016-09-14 15:58:18 -07:00
let meta = this . _pipeCache . get ( pipeType );
if ( ! meta ) {
const pipeMeta = this . _pipeResolver . resolve ( pipeType , throwIfNotFound );
2016-07-18 03:50:31 -07:00
if ( ! pipeMeta ) {
return null ;
}
2016-09-14 15:58:18 -07:00
2015-12-02 10:35:51 -08:00
meta = new cpl . CompilePipeMetadata ({
2016-02-18 10:53:21 -08:00
type : this . getTypeMetadata ( pipeType , staticTypeModuleUrl ( pipeType )),
2015-12-02 10:35:51 -08:00
name : pipeMeta.name ,
2016-08-02 01:12:24 -07:00
pure : pipeMeta.pure
2015-12-02 10:35:51 -08:00
});
this . _pipeCache . set ( pipeType , meta );
2015-09-14 15:59:09 -07:00
}
return meta ;
}
2016-08-10 18:21:28 -07:00
getDependenciesMetadata ( typeOrFunc : Type < any > | Function , dependencies : any []) :
2016-06-08 16:38:52 -07:00
cpl . CompileDiDependencyMetadata [] {
2016-06-10 01:07:06 +02:00
let hasUnknownDeps = false ;
2016-09-14 15:58:18 -07:00
let params = dependencies || this . _reflector . parameters ( typeOrFunc ) || [];
2016-06-10 01:07:06 +02:00
let dependenciesMetadata : cpl.CompileDiDependencyMetadata [] = params . map (( param ) => {
2016-02-18 10:53:21 -08:00
let isAttribute = false ;
let isHost = false ;
let isSelf = false ;
let isSkipSelf = false ;
let isOptional = false ;
2016-10-24 13:28:23 -07:00
let token : any = null ;
2016-09-14 15:58:18 -07:00
if ( Array . isArray ( param )) {
param . forEach (( paramEntry ) => {
2016-09-12 19:14:17 -07:00
if ( paramEntry instanceof Host ) {
2016-06-08 16:38:52 -07:00
isHost = true ;
2016-09-12 19:14:17 -07:00
} else if ( paramEntry instanceof Self ) {
2016-06-08 16:38:52 -07:00
isSelf = true ;
2016-09-12 19:14:17 -07:00
} else if ( paramEntry instanceof SkipSelf ) {
2016-06-08 16:38:52 -07:00
isSkipSelf = true ;
2016-09-12 19:14:17 -07:00
} else if ( paramEntry instanceof Optional ) {
2016-06-08 16:38:52 -07:00
isOptional = true ;
2016-09-12 19:14:17 -07:00
} else if ( paramEntry instanceof Attribute ) {
2016-06-08 16:38:52 -07:00
isAttribute = true ;
token = paramEntry . attributeName ;
2016-09-12 19:14:17 -07:00
} else if ( paramEntry instanceof Inject ) {
2016-06-08 16:38:52 -07:00
token = paramEntry . token ;
} else if ( isValidType ( paramEntry ) && isBlank ( token )) {
token = paramEntry ;
}
});
2016-02-18 10:53:21 -08:00
} else {
token = param ;
}
if ( isBlank ( token )) {
2016-06-10 01:07:06 +02:00
hasUnknownDeps = true ;
2016-02-18 10:53:21 -08:00
return null ;
2016-01-06 14:13:44 -08:00
}
2016-09-14 15:58:18 -07:00
2016-01-06 14:13:44 -08:00
return new cpl . CompileDiDependencyMetadata ({
2016-09-14 15:58:18 -07:00
isAttribute ,
isHost ,
isSelf ,
isSkipSelf ,
isOptional ,
2016-02-18 10:53:21 -08:00
token : this.getTokenMetadata ( token )
2016-01-06 14:13:44 -08:00
});
2016-02-18 10:53:21 -08:00
2016-01-06 14:13:44 -08:00
});
2016-06-10 01:07:06 +02:00
if ( hasUnknownDeps ) {
2016-06-08 16:38:52 -07:00
let depsTokens =
2016-09-14 15:58:18 -07:00
dependenciesMetadata . map (( dep ) => dep ? stringify ( dep . token ) : '?' ). join ( ', ' );
2016-08-25 00:50:16 -07:00
throw new Error (
2016-06-08 16:38:52 -07:00
`Can't resolve all parameters for ${ stringify ( typeOrFunc ) } : ( ${ depsTokens } ).` );
2016-06-10 01:07:06 +02:00
}
return dependenciesMetadata ;
2016-01-06 14:13:44 -08:00
}
getTokenMetadata ( token : any ) : cpl . CompileTokenMetadata {
token = resolveForwardRef ( token );
2016-09-14 15:58:18 -07:00
let compileToken : cpl.CompileTokenMetadata ;
2016-10-19 13:42:39 -07:00
if ( typeof token === 'string' ) {
2016-01-06 14:13:44 -08:00
compileToken = new cpl . CompileTokenMetadata ({ value : token });
} else {
2016-04-20 18:10:19 -07:00
compileToken = new cpl . CompileTokenMetadata ({
2016-02-18 10:53:21 -08:00
identifier : new cpl . CompileIdentifierMetadata ({
2016-08-29 08:52:25 -07:00
reference : token ,
2016-02-18 10:53:21 -08:00
name : this.sanitizeTokenName ( token ),
moduleUrl : staticTypeModuleUrl ( token )
})
2016-04-20 18:10:19 -07:00
});
2016-01-06 14:13:44 -08:00
}
return compileToken ;
}
2016-08-24 01:18:41 +02:00
getProvidersMetadata (
providers : Provider [], targetEntryComponents : cpl.CompileTypeMetadata [],
debugInfo? : string ) : Array < cpl.CompileProviderMetadata | cpl.CompileTypeMetadata | any [] > {
2016-07-07 10:05:55 -07:00
const compileProviders : Array < cpl.CompileProviderMetadata | cpl.CompileTypeMetadata | any [] > = [];
2016-08-24 01:18:41 +02:00
providers . forEach (( provider : any , providerIdx : number ) => {
2016-01-06 14:13:44 -08:00
provider = resolveForwardRef ( provider );
2016-08-15 19:37:42 -07:00
if ( provider && typeof provider == 'object' && provider . hasOwnProperty ( 'provide' )) {
provider = new cpl . ProviderMeta ( provider . provide , provider );
2016-07-07 10:05:55 -07:00
}
let compileProvider : cpl.CompileProviderMetadata | cpl . CompileTypeMetadata | any [];
2016-09-14 15:58:18 -07:00
if ( Array . isArray ( provider )) {
2016-08-24 01:18:41 +02:00
compileProvider = this . getProvidersMetadata ( provider , targetEntryComponents , debugInfo );
2016-08-15 19:37:42 -07:00
} else if ( provider instanceof cpl . ProviderMeta ) {
2016-07-07 10:05:55 -07:00
let tokenMeta = this . getTokenMetadata ( provider . token );
2016-08-29 08:52:25 -07:00
if ( tokenMeta . reference ===
resolveIdentifierToken ( Identifiers . ANALYZE_FOR_ENTRY_COMPONENTS ). reference ) {
2016-07-25 00:36:30 -07:00
targetEntryComponents . push (... this . _getEntryComponentsFromProvider ( provider ));
2016-07-07 10:05:55 -07:00
} else {
compileProvider = this . getProviderMetadata ( provider );
}
2016-06-28 09:54:42 -07:00
} else if ( isValidType ( provider )) {
2016-07-07 10:05:55 -07:00
compileProvider = this . getTypeMetadata ( provider , staticTypeModuleUrl ( provider ));
2016-06-28 09:54:42 -07:00
} else {
2016-10-24 13:28:23 -07:00
const providersInfo =
(< string [] > providers . reduce (
( soFar : string [], seenProvider : any , seenProviderIdx : number ) => {
if ( seenProviderIdx < providerIdx ) {
soFar . push ( ` ${ stringify ( seenProvider ) } ` );
} else if ( seenProviderIdx == providerIdx ) {
soFar . push ( `? ${ stringify ( seenProvider ) } ?` );
} else if ( seenProviderIdx == providerIdx + 1 ) {
soFar . push ( '...' );
}
return soFar ;
},
[]))
. join ( ', ' );
2016-08-24 01:18:41 +02:00
2016-08-25 00:50:16 -07:00
throw new Error (
2016-08-24 01:18:41 +02:00
`Invalid ${ debugInfo ? debugInfo : 'provider' } - only instances of Provider and Type are allowed, got: [ ${ providersInfo } ]` );
2016-01-06 14:13:44 -08:00
}
2016-07-07 10:05:55 -07:00
if ( compileProvider ) {
compileProviders . push ( compileProvider );
}
2016-01-06 14:13:44 -08:00
});
2016-07-07 10:05:55 -07:00
return compileProviders ;
}
2016-08-15 19:37:42 -07:00
private _getEntryComponentsFromProvider ( provider : cpl.ProviderMeta ) : cpl . CompileTypeMetadata [] {
2016-09-14 15:58:18 -07:00
const components : cpl.CompileTypeMetadata [] = [];
const collectedIdentifiers : cpl.CompileIdentifierMetadata [] = [];
2016-07-07 10:05:55 -07:00
if ( provider . useFactory || provider . useExisting || provider . useClass ) {
2016-08-25 00:50:16 -07:00
throw new Error ( `The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!` );
2016-07-07 10:05:55 -07:00
}
2016-09-14 15:58:18 -07:00
2016-07-07 10:05:55 -07:00
if ( ! provider . multi ) {
2016-08-25 00:50:16 -07:00
throw new Error ( `The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!` );
2016-07-07 10:05:55 -07:00
}
2016-09-14 15:58:18 -07:00
2016-07-07 10:05:55 -07:00
convertToCompileValue ( provider . useValue , collectedIdentifiers );
collectedIdentifiers . forEach (( identifier ) => {
2016-09-14 15:58:18 -07:00
const dirMeta = this . getDirectiveMetadata ( identifier . reference , false );
2016-07-07 10:05:55 -07:00
if ( dirMeta ) {
components . push ( dirMeta . type );
}
});
return components ;
2016-01-06 14:13:44 -08:00
}
2016-08-15 19:37:42 -07:00
getProviderMetadata ( provider : cpl.ProviderMeta ) : cpl . CompileProviderMetadata {
2016-09-14 15:58:18 -07:00
let compileDeps : cpl.CompileDiDependencyMetadata [];
let compileTypeMetadata : cpl.CompileTypeMetadata = null ;
let compileFactoryMetadata : cpl.CompileFactoryMetadata = null ;
2016-06-18 18:42:34 +02:00
2016-09-14 15:58:18 -07:00
if ( provider . useClass ) {
2016-06-18 18:42:34 +02:00
compileTypeMetadata = this . getTypeMetadata (
provider . useClass , staticTypeModuleUrl ( provider . useClass ), provider . dependencies );
compileDeps = compileTypeMetadata . diDeps ;
2016-09-14 15:58:18 -07:00
} else if ( provider . useFactory ) {
2016-06-18 18:42:34 +02:00
compileFactoryMetadata = this . getFactoryMetadata (
provider . useFactory , staticTypeModuleUrl ( provider . useFactory ), provider . dependencies );
compileDeps = compileFactoryMetadata . diDeps ;
2016-01-06 14:13:44 -08:00
}
2016-06-18 18:42:34 +02:00
2016-01-06 14:13:44 -08:00
return new cpl . CompileProviderMetadata ({
token : this.getTokenMetadata ( provider . token ),
2016-06-18 18:42:34 +02:00
useClass : compileTypeMetadata ,
2016-07-07 10:05:55 -07:00
useValue : convertToCompileValue ( provider . useValue , []),
2016-06-18 18:42:34 +02:00
useFactory : compileFactoryMetadata ,
2016-09-14 15:58:18 -07:00
useExisting : provider.useExisting ? this . getTokenMetadata ( provider . useExisting ) : null ,
2016-01-06 14:13:44 -08:00
deps : compileDeps ,
multi : provider.multi
});
}
2016-06-08 16:38:52 -07:00
getQueriesMetadata (
2016-09-12 19:14:17 -07:00
queries : {[ key : string ] : Query }, isViewQuery : boolean ,
2016-08-10 18:21:28 -07:00
directiveType : Type < any >) : cpl . CompileQueryMetadata [] {
2016-09-14 15:58:18 -07:00
const res : cpl.CompileQueryMetadata [] = [];
Object . keys ( queries ). forEach (( propertyName : string ) => {
const query = queries [ propertyName ];
2016-06-22 17:25:42 -07:00
if ( query . isViewQuery === isViewQuery ) {
res . push ( this . getQueryMetadata ( query , propertyName , directiveType ));
}
});
2016-09-14 15:58:18 -07:00
2016-06-22 17:25:42 -07:00
return res ;
2016-01-06 14:13:44 -08:00
}
2016-09-14 15:58:18 -07:00
private _queryVarBindings ( selector : any ) : string [] { return selector . split ( /\s*,\s*/ ); }
2016-09-12 09:44:20 -07:00
2016-09-12 19:14:17 -07:00
getQueryMetadata ( q : Query , propertyName : string , typeOrFunc : Type < any > | Function ) :
2016-06-08 16:38:52 -07:00
cpl . CompileQueryMetadata {
2016-06-17 10:57:50 -07:00
var selectors : cpl.CompileTokenMetadata [];
2016-09-14 15:58:18 -07:00
if ( typeof q . selector === 'string' ) {
2016-09-12 09:44:20 -07:00
selectors = this . _queryVarBindings ( q . selector ). map ( varName => this . getTokenMetadata ( varName ));
2016-01-06 14:13:44 -08:00
} else {
2016-09-14 15:58:18 -07:00
if ( ! q . selector ) {
2016-08-25 00:50:16 -07:00
throw new Error (
2016-06-08 16:38:52 -07:00
`Can't construct a query for the property " ${ propertyName } " of " ${ stringify ( typeOrFunc ) } " since the query selector wasn't defined.` );
2016-06-05 04:46:03 +02:00
}
2016-01-06 14:13:44 -08:00
selectors = [ this . getTokenMetadata ( q . selector )];
}
2016-09-14 15:58:18 -07:00
2016-01-06 14:13:44 -08:00
return new cpl . CompileQueryMetadata ({
2016-09-14 15:58:18 -07:00
selectors ,
2016-01-06 14:13:44 -08:00
first : q.first ,
2016-09-14 15:58:18 -07:00
descendants : q.descendants , propertyName ,
read : q.read ? this . getTokenMetadata ( q . read ) : null
2016-01-06 14:13:44 -08:00
});
}
2015-09-14 15:59:09 -07:00
}
2016-07-18 03:50:31 -07:00
function getTransitiveModules (
modules : cpl.CompileNgModuleMetadata [], includeImports : boolean ,
targetModules : cpl.CompileNgModuleMetadata [] = [],
2016-08-10 18:21:28 -07:00
visitedModules = new Set < Type < any >>()) : cpl . CompileNgModuleMetadata [] {
2016-07-18 03:50:31 -07:00
modules . forEach (( ngModule ) => {
2016-08-29 08:52:25 -07:00
if ( ! visitedModules . has ( ngModule . type . reference )) {
visitedModules . add ( ngModule . type . reference );
2016-07-18 03:50:31 -07:00
const nestedModules = includeImports ?
ngModule . importedModules . concat ( ngModule . exportedModules ) :
ngModule . exportedModules ;
getTransitiveModules ( nestedModules , includeImports , targetModules , visitedModules );
// Add after recursing so imported/exported modules are before the module itself.
// This is important for overwriting providers of imported modules!
targetModules . push ( ngModule );
}
});
return targetModules ;
2015-09-14 15:59:09 -07:00
}
2016-07-18 03:50:31 -07:00
function flattenArray ( tree : any [], out : Array < any > = []) : Array < any > {
if ( tree ) {
2016-09-14 15:58:18 -07:00
for ( let i = 0 ; i < tree . length ; i ++ ) {
const item = resolveForwardRef ( tree [ i ]);
if ( Array . isArray ( item )) {
2016-07-18 03:50:31 -07:00
flattenArray ( item , out );
} else {
out . push ( item );
}
2015-09-14 15:59:09 -07:00
}
}
2016-06-22 14:06:23 -07:00
return out ;
2015-09-14 15:59:09 -07:00
}
2016-10-28 14:08:54 -07:00
function dedupeArray ( array : any []) : Array < any > {
if ( array ) {
return Array . from ( new Set ( array ));
}
return [];
}
function flattenAndDedupeArray ( tree : any []) : Array < any > {
return dedupeArray ( flattenArray ( tree ));
}
2016-02-18 10:53:21 -08:00
function isValidType ( value : any ) : boolean {
2016-06-28 09:54:42 -07:00
return cpl . isStaticSymbol ( value ) || ( value instanceof Type );
2016-02-18 10:53:21 -08:00
}
function staticTypeModuleUrl ( value : any ) : string {
2016-06-28 09:54:42 -07:00
return cpl . isStaticSymbol ( value ) ? value.filePath : null ;
2015-09-14 15:59:09 -07:00
}
2016-09-14 16:49:13 -07:00
function componentModuleUrl (
reflector : ReflectorReader , type : Type < any >, cmpMetadata : Component ) : string {
2016-06-28 09:54:42 -07:00
if ( cpl . isStaticSymbol ( type )) {
2016-05-02 09:38:46 -07:00
return staticTypeModuleUrl ( type );
2016-04-28 21:54:02 -07:00
}
2016-09-14 16:49:13 -07:00
const moduleId = cmpMetadata . moduleId ;
if ( typeof moduleId === 'string' ) {
2016-09-14 15:58:18 -07:00
const scheme = getUrlScheme ( moduleId );
return scheme ? moduleId : `package: ${ moduleId }${ MODULE_SUFFIX } ` ;
2016-09-14 16:49:13 -07:00
} else if ( moduleId !== null && moduleId !== void 0 ) {
throw new Error (
`moduleId should be a string in " ${ stringify ( type ) } ". See https://goo.gl/wIDDiL for more information. \ n` +
`If you're using Webpack you should inline the template and the styles, see https://goo.gl/X2J8zc.` );
2015-09-14 15:59:09 -07:00
}
2016-04-28 21:54:02 -07:00
return reflector . importUri ( type );
2015-09-14 15:59:09 -07:00
}
2016-04-30 16:13:03 -07:00
2016-07-07 10:05:55 -07:00
function convertToCompileValue (
value : any , targetIdentifiers : cpl.CompileIdentifierMetadata []) : any {
return visitValue ( value , new _CompileValueConverter (), targetIdentifiers );
2016-04-30 16:13:03 -07:00
}
class _CompileValueConverter extends ValueTransformer {
2016-07-07 10:05:55 -07:00
visitOther ( value : any , targetIdentifiers : cpl.CompileIdentifierMetadata []) : any {
let identifier : cpl.CompileIdentifierMetadata ;
2016-06-28 09:54:42 -07:00
if ( cpl . isStaticSymbol ( value )) {
2016-07-07 10:05:55 -07:00
identifier = new cpl . CompileIdentifierMetadata (
2016-08-29 08:52:25 -07:00
{ name : value.name , moduleUrl : value.filePath , reference : value });
2016-04-30 16:13:03 -07:00
} else {
2016-08-29 08:52:25 -07:00
identifier = new cpl . CompileIdentifierMetadata ({ reference : value });
2016-04-30 16:13:03 -07:00
}
2016-07-07 10:05:55 -07:00
targetIdentifiers . push ( identifier );
return identifier ;
2016-04-30 16:13:03 -07:00
}
}