2016-10-23 22:37:15 +02: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-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								import  *  as  ts  from  'typescript' ;  
						 
					
						
							
								
									
										
										
										
											2016-05-26 10:45:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-02 09:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  { Evaluator ,  errorSymbol }  from  './evaluator' ;  
						 
					
						
							
								
									
										
										
										
											2017-03-15 09:24:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  { ClassMetadata ,  ConstructorMetadata ,  FunctionMetadata ,  InterfaceMetadata ,  MemberMetadata ,  MetadataEntry ,  MetadataError ,  MetadataMap ,  MetadataSymbolicBinaryExpression ,  MetadataSymbolicCallExpression ,  MetadataSymbolicExpression ,  MetadataSymbolicIfExpression ,  MetadataSymbolicIndexExpression ,  MetadataSymbolicPrefixExpression ,  MetadataSymbolicReferenceExpression ,  MetadataSymbolicSelectExpression ,  MetadataSymbolicSpreadExpression ,  MetadataValue ,  MethodMetadata ,  ModuleExportMetadata ,  ModuleMetadata ,  VERSION ,  isClassMetadata ,  isConstructorMetadata ,  isFunctionMetadata ,  isMetadataError ,  isMetadataGlobalReferenceExpression ,  isMetadataSymbolicExpression ,  isMetadataSymbolicReferenceExpression ,  isMetadataSymbolicSelectExpression ,  isMethodMetadata }  from  './schema' ;  
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								import  { Symbols }  from  './symbols' ;  
						 
					
						
							
								
									
										
										
										
											2016-05-26 10:45:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// In TypeScript 2.1 these flags moved
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// These helpers work for both 2.0 and 2.1.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  isExport  =  ( ts  as  any ) . ModifierFlags  ?  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( ( node : ts.Node )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								         ! ! ( ( ts  as  any ) . getCombinedModifierFlags ( node )  &  ( ts  as  any ) . ModifierFlags . Export ) )  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( ( node : ts.Node )  = >  ! ! ( ( node . flags  &  ( ts  as  any ) . NodeFlags . Export ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  isStatic  =  ( ts  as  any ) . ModifierFlags  ?  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( ( node : ts.Node )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								         ! ! ( ( ts  as  any ) . getCombinedModifierFlags ( node )  &  ( ts  as  any ) . ModifierFlags . Static ) )  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( ( node : ts.Node )  = >  ! ! ( ( node . flags  &  ( ts  as  any ) . NodeFlags . Static ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 11:14:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-12 10:49:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  A  set  of  collector  options  to  use  when  collecting  metadata . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								export  class  CollectorOptions  {  
						 
					
						
							
								
									
										
										
										
											2016-12-14 15:28:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   *  Version  of  the  metadata  to  collect . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  version? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-12 10:49:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   *  Collect  a  hidden  field  "$quoted$"  in  objects  literals  that  record  when  the  key  was  quoted  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   *  the  source . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  quotedNames? : boolean ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 13:23:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   *  Do  not  simplify  invalid  expressions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  verboseInvalidExpression? : boolean ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-12 10:49:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Collect  decorator  metadata  from  a  TypeScript  module . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								export  class  MetadataCollector  {  
						 
					
						
							
								
									
										
										
										
											2016-12-12 10:49:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  constructor ( private  options : CollectorOptions  =  { } )  { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-25 21:29:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   *  Returns  a  JSON . stringify  friendly  form  describing  the  decorators  of  the  exported  classes  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   *  the  source  file  that  is  expected  to  correspond  to  a  module . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   * / 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  public  getMetadata ( sourceFile : ts.SourceFile ,  strict : boolean  =  false ) :  ModuleMetadata  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  locals  =  new  Symbols ( sourceFile ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 09:24:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  nodeMap  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        new  Map < MetadataValue | ClassMetadata | InterfaceMetadata | FunctionMetadata ,  ts.Node > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-12 10:49:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  evaluator  =  new  Evaluator ( locals ,  nodeMap ,  this . options ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-29 09:10:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    let  metadata :  { [ name : string ] :  MetadataValue  |  ClassMetadata  |  FunctionMetadata } | undefined ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 11:45:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    let  exports : ModuleExportMetadata [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    function  objFromDecorator ( decoratorNode : ts.Decorator ) :  MetadataSymbolicExpression  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  < MetadataSymbolicExpression > evaluator . evaluateNode ( decoratorNode . expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    function  recordEntry < T  extends  MetadataEntry > ( entry : T ,  node : ts.Node ) :  T  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nodeMap . set ( entry ,  node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-03 15:43:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    function  errorSym ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        message : string ,  node? : ts.Node ,  context ? :  { [ name : string ] :  string } ) :  MetadataError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  errorSymbol ( message ,  node ,  context ,  sourceFile ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    function  maybeGetSimpleFunction ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        functionDeclaration : ts.FunctionDeclaration  | 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-29 09:10:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ts . MethodDeclaration ) :  { func : FunctionMetadata ,  name : string } | undefined  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( functionDeclaration . name . kind  ==  ts . SyntaxKind . Identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  nameNode  =  < ts.Identifier > functionDeclaration . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  functionName  =  nameNode . text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  functionBody  =  functionDeclaration . body ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( functionBody  &&  functionBody . statements . length  ==  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  statement  =  functionBody . statements [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( statement . kind  ===  ts . SyntaxKind . ReturnStatement )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  returnStatement  =  < ts.ReturnStatement > statement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( returnStatement . expression )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-29 09:10:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              const  func : FunctionMetadata  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                __symbolic :  'function' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parameters : namesOf ( functionDeclaration . parameters ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                value : evaluator.evaluateNode ( returnStatement . expression ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( functionDeclaration . parameters . some ( p  = >  p . initializer  !=  null ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                func . defaults  =  functionDeclaration . parameters . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    p  = >  p . initializer  &&  evaluator . evaluateNode ( p . initializer ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              return  recordEntry ( { func ,  name : functionName } ,  functionDeclaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    function  classMetadataOf ( classDeclaration : ts.ClassDeclaration ) :  ClassMetadata  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      const  result : ClassMetadata  =  { __symbolic :  'class' } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-19 19:37:57 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      function  getDecorators ( decorators : ts.Decorator [ ] ) :  MetadataSymbolicExpression [ ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( decorators  &&  decorators . length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return  decorators . map ( decorator  = >  objFromDecorator ( decorator ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 17:26:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      function  referenceFrom ( node : ts.Node ) :  MetadataSymbolicReferenceExpression | MetadataError | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          MetadataSymbolicSelectExpression  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  result  =  evaluator . evaluateNode ( node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 17:26:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( isMetadataError ( result )  ||  isMetadataSymbolicReferenceExpression ( result )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            isMetadataSymbolicSelectExpression ( result ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-03 15:43:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          return  errorSym ( 'Symbol reference expected' ,  node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-18 15:17:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      // Add class parents
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( classDeclaration . heritageClauses )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        classDeclaration . heritageClauses . forEach ( ( hc )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( hc . token  ===  ts . SyntaxKind . ExtendsKeyword  &&  hc . types )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            hc . types . forEach ( type  = >  result . extends  =  referenceFrom ( type . expression ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-25 13:40:55 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      // Add arity if the type is generic
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  typeParameters  =  classDeclaration . typeParameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( typeParameters  &&  typeParameters . length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . arity  =  typeParameters . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      // Add class decorators
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( classDeclaration . decorators )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . decorators  =  getDecorators ( classDeclaration . decorators ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // member decorators
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      let  members : MetadataMap  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      function  recordMember ( name : string ,  metadata : MemberMetadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! members )  members  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  data  =  members . hasOwnProperty ( name )  ?  members [ name ]  :  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        data . push ( metadata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        members [ name ]  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // static member
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-29 09:10:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      let  statics :  { [ name : string ] :  MetadataValue  |  FunctionMetadata }  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      function  recordStaticMember ( name : string ,  value : MetadataValue  |  FunctionMetadata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! statics )  statics  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        statics [ name ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      for  ( const  member  of  classDeclaration . members )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let  isConstructor  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( member . kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          case  ts . SyntaxKind . Constructor : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          case  ts . SyntaxKind . MethodDeclaration : 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 15:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            isConstructor  =  member . kind  ===  ts . SyntaxKind . Constructor ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-26 10:45:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  method  =  < ts.MethodDeclaration | ts.ConstructorDeclaration > member ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( isStatic ( method ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              const  maybeFunc  =  maybeGetSimpleFunction ( < ts.MethodDeclaration > method ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( maybeFunc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                recordStaticMember ( maybeFunc . name ,  maybeFunc . func ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            const  methodDecorators  =  getDecorators ( method . decorators ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  parameters  =  method . parameters ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  parameterDecoratorData :  ( MetadataSymbolicExpression  |  MetadataError ) [ ] [ ]  =  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 17:26:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  parametersData : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ( MetadataSymbolicReferenceExpression  |  MetadataError  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                 MetadataSymbolicSelectExpression  |  null ) [ ]  =  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            let  hasDecoratorData : boolean  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  hasParameterData : boolean  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( const  parameter  of  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              const  parameterData  =  getDecorators ( parameter . decorators ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              parameterDecoratorData . push ( parameterData ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              hasDecoratorData  =  hasDecoratorData  ||  ! ! parameterData ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( isConstructor )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( parameter . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  parametersData . push ( referenceFrom ( parameter . type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  parametersData . push ( null ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                hasParameterData  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-26 10:45:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  data : MethodMetadata  =  { __symbolic : isConstructor  ?  'constructor'  :  'method' } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  name  =  isConstructor  ?  '__ctor__'  :  evaluator . nameOf ( member . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-04 09:11:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( methodDecorators )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              data . decorators  =  methodDecorators ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( hasDecoratorData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              data . parameterDecorators  =  parameterDecoratorData ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( hasParameterData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              ( < ConstructorMetadata > data ) . parameters  =  parametersData ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! isMetadataError ( name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              recordMember ( name ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          case  ts . SyntaxKind . PropertyDeclaration : 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-25 10:16:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          case  ts . SyntaxKind . GetAccessor : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          case  ts . SyntaxKind . SetAccessor : 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            const  property  =  < ts.PropertyDeclaration > member ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( isStatic ( property ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-27 19:26:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              const  name  =  evaluator . nameOf ( property . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( ! isMetadataError ( name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( property . initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  const  value  =  evaluator . evaluateNode ( property . initializer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  recordStaticMember ( name ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  recordStaticMember ( name ,  errorSym ( 'Variable not initialized' ,  property . name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            const  propertyDecorators  =  getDecorators ( property . decorators ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( propertyDecorators )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-27 19:26:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              const  name  =  evaluator . nameOf ( property . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              if  ( ! isMetadataError ( name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                recordMember ( name ,  { __symbolic :  'property' ,  decorators : propertyDecorators } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( members )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . members  =  members ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( statics )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result . statics  =  statics ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-18 15:17:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  recordEntry ( result ,  classDeclaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Collect all exported symbols from an exports clause.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  exportMap  =  new  Map < string ,  string > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ts . forEachChild ( sourceFile ,  node  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( node . kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . ExportDeclaration : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  exportDeclaration  =  < ts.ExportDeclaration > node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  { moduleSpecifier ,  exportClause }  =  exportDeclaration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( ! moduleSpecifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            exportClause . elements . forEach ( spec  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              const  exportedAs  =  spec . name . text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              const  name  =  ( spec . propertyName  ||  spec . name ) . text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              exportMap . set ( name ,  exportedAs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  isExportedIdentifier  =  ( identifier : ts.Identifier )  = >  exportMap . has ( identifier . text ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 09:24:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  isExported  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ( node : ts.FunctionDeclaration  |  ts . ClassDeclaration  |  ts . InterfaceDeclaration  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								         ts . EnumDeclaration )  = >  isExport ( node )  ||  isExportedIdentifier ( node . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  exportedIdentifierName  =  ( identifier : ts.Identifier )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        exportMap . get ( identifier . text )  ||  identifier . text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  exportedName  = 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 09:24:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ( node : ts.FunctionDeclaration  |  ts . ClassDeclaration  |  ts . InterfaceDeclaration  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								         ts . EnumDeclaration )  = >  exportedIdentifierName ( node . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Predeclare classes and functions
 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ts . forEachChild ( sourceFile ,  node  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( node . kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . ClassDeclaration : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  classDeclaration  =  < ts.ClassDeclaration > node ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 11:58:55 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if  ( classDeclaration . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  className  =  classDeclaration . name . text ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( isExported ( classDeclaration ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              locals . define ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  className ,  { __symbolic :  'reference' ,  name : exportedName ( classDeclaration ) } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 11:58:55 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              locals . define ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  className ,  errorSym ( 'Reference to non-exported class' ,  node ,  { className } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 09:24:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . InterfaceDeclaration : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  interfaceDeclaration  =  < ts.InterfaceDeclaration > node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( interfaceDeclaration . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  interfaceName  =  interfaceDeclaration . name . text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // All references to interfaces should be converted to references to `any`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            locals . define ( interfaceName ,  { __symbolic :  'reference' ,  name :  'any' } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . FunctionDeclaration : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          const  functionDeclaration  =  < ts.FunctionDeclaration > node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( ! isExported ( functionDeclaration ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Report references to this function as an error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  nameNode  =  functionDeclaration . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 11:58:55 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( nameNode  &&  nameNode . text )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              locals . define ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  nameNode . text , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  errorSym ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      'Reference to a non-exported function' ,  nameNode ,  { name : nameNode.text } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ts . forEachChild ( sourceFile ,  node  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( node . kind )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 11:45:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . ExportDeclaration : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // Record export declarations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  exportDeclaration  =  < ts.ExportDeclaration > node ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          const  { moduleSpecifier ,  exportClause }  =  exportDeclaration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( ! moduleSpecifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // no module specifier -> export {propName as name};
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( exportClause )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              exportClause . elements . forEach ( spec  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  name  =  spec . name . text ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // If the symbol was not already exported, export a reference since it is a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // reference to an import
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! metadata  ||  ! metadata [ name ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  const  propNode  =  spec . propertyName  ||  spec . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  const  value : MetadataValue  =  evaluator . evaluateNode ( propNode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  if  ( ! metadata )  metadata  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  metadata [ name ]  =  recordEntry ( value ,  node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 11:45:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if  ( moduleSpecifier  &&  moduleSpecifier . kind  ==  ts . SyntaxKind . StringLiteral )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Ignore exports that don't have string literals as exports.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // This is allowed by the syntax but will be flagged as an error by the type checker.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  from  =  ( < ts.StringLiteral > moduleSpecifier ) . text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  moduleExport : ModuleExportMetadata  =  { from } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( exportClause )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              moduleExport . export  =  exportClause . elements . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  spec  = >  spec . propertyName  ?  { name : spec.propertyName.text ,  as :  spec . name . text }  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                              spec . name . text ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 11:45:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! exports )  exports  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            exports . push ( moduleExport ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . ClassDeclaration : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  classDeclaration  =  < ts.ClassDeclaration > node ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 11:58:55 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if  ( classDeclaration . name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( isExported ( classDeclaration ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 09:52:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              if  ( ! metadata )  metadata  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              metadata [ exportedName ( classDeclaration ) ]  =  classMetadataOf ( classDeclaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // Otherwise don't record metadata for the class.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 09:24:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . InterfaceDeclaration : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  interfaceDeclaration  =  < ts.InterfaceDeclaration > node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( interfaceDeclaration . name  &&  isExported ( interfaceDeclaration ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! metadata )  metadata  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            metadata [ exportedName ( interfaceDeclaration ) ]  =  { __symbolic :  'interface' } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 15:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . FunctionDeclaration : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // Record functions that return a single value. Record the parameter
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // names substitution will be performed by the StaticReflector.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          const  functionDeclaration  =  < ts.FunctionDeclaration > node ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if  ( isExported ( functionDeclaration ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 09:52:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! metadata )  metadata  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  name  =  exportedName ( functionDeclaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 10:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  maybeFunc  =  maybeGetSimpleFunction ( functionDeclaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            metadata [ name ]  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                maybeFunc  ?  recordEntry ( maybeFunc . func ,  node )  :  { __symbolic :  'function' } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 15:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 11:50:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . EnumDeclaration : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          const  enumDeclaration  =  < ts.EnumDeclaration > node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( isExported ( enumDeclaration ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  enumValueHolder :  { [ name : string ] :  MetadataValue }  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  enumName  =  exportedName ( enumDeclaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 10:26:22 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            let  nextDefaultValue : MetadataValue  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  writtenMembers  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( const  member  of  enumDeclaration . members )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              let  enumValue : MetadataValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( ! member . initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                enumValue  =  nextDefaultValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                enumValue  =  evaluator . evaluateNode ( member . initializer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              let  name : string  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( member . name . kind  ==  ts . SyntaxKind . Identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  identifier  =  < ts.Identifier > member . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                name  =  identifier . text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                enumValueHolder [ name ]  =  enumValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                writtenMembers ++ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( typeof  enumValue  ===  'number' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                nextDefaultValue  =  enumValue  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              }  else  if  ( name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                nextDefaultValue  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  __symbolic :  'binary' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  operator :  '+' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  left :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    __symbolic :  'select' , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    expression : recordEntry ( { __symbolic :  'reference' ,  name : enumName } ,  node ) ,  name 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 10:26:22 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                  } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 22:52:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 10:26:22 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                nextDefaultValue  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    recordEntry ( errorSym ( 'Unsuppported enum member name' ,  member . name ) ,  node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 11:50:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 10:26:22 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( writtenMembers )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( ! metadata )  metadata  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              metadata [ enumName ]  =  recordEntry ( enumValueHolder ,  node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 11:50:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        case  ts . SyntaxKind . VariableStatement : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  variableStatement  =  < ts.VariableStatement > node ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          for  ( const  variableDeclaration  of  variableStatement . declarationList . declarations )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( variableDeclaration . name . kind  ==  ts . SyntaxKind . Identifier )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              const  nameNode  =  < ts.Identifier > variableDeclaration . name ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              let  varValue : MetadataValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              if  ( variableDeclaration . initializer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                varValue  =  evaluator . evaluateNode ( variableDeclaration . initializer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                varValue  =  recordEntry ( errorSym ( 'Variable not initialized' ,  nameNode ) ,  nameNode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 14:38:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              let  exported  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              if  ( isExport ( variableStatement )  ||  isExport ( variableDeclaration )  || 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                  isExportedIdentifier ( nameNode ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                if  ( ! metadata )  metadata  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:33:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                metadata [ exportedIdentifierName ( nameNode ) ]  =  recordEntry ( varValue ,  node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 14:38:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                exported  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-02 09:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              if  ( typeof  varValue  ==  'string'  ||  typeof  varValue  ==  'number'  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  typeof  varValue  ==  'boolean' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                locals . define ( nameNode . text ,  varValue ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 14:38:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              }  else  if  ( ! exported )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( varValue  &&  ! isMetadataError ( varValue ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  locals . define ( nameNode . text ,  recordEntry ( varValue ,  node ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  locals . define ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      nameNode . text , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      recordEntry ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                          errorSym ( 'Reference to a local symbol' ,  nameNode ,  { name : nameNode.text } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                          node ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								              } 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              // Destructuring (or binding) declarations are not supported,
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 11:37:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              // var {<identifier>[, <identifier>]+} = <expression>;
 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              //   or
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              // var [<identifier>[, <identifier}+] = <expression>;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              // are not supported.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              const  report :  ( nameNode : ts.Node )  = >  void  =  ( nameNode : ts.Node )  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                switch  ( nameNode . kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  case  ts . SyntaxKind . Identifier : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  name  =  < ts.Identifier > nameNode ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    const  varValue  =  errorSym ( 'Destructuring not supported' ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    locals . define ( name . text ,  varValue ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( isExport ( node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                      if  ( ! metadata )  metadata  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      metadata [ name . text ]  =  varValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  case  ts . SyntaxKind . BindingElement : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  bindingElement  =  < ts.BindingElement > nameNode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    report ( bindingElement . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  case  ts . SyntaxKind . ObjectBindingPattern : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  case  ts . SyntaxKind . ArrayBindingPattern : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  bindings  =  < ts.BindingPattern > nameNode ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    ( bindings  as  any ) . elements . forEach ( report ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              report ( variableDeclaration . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-31 11:00:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-25 21:29:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 11:45:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( metadata  ||  exports )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( ! metadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        metadata  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else  if  ( strict )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        validateMetadata ( sourceFile ,  nodeMap ,  metadata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 15:28:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      const  result : ModuleMetadata  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        __symbolic :  'module' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        version : this.options.version  ||  VERSION ,  metadata 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 11:45:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( exports )  result . exports  =  exports ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 17:11:42 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-06-13 15:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// This will throw if the metadata entry given contains an error node.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  validateMetadata (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sourceFile : ts.SourceFile ,  nodeMap : Map < MetadataEntry ,  ts.Node > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    metadata :  { [ name : string ] :  MetadataEntry } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  let  locals : Set < string >  =  new  Set ( [ 'Array' ,  'Object' ,  'Set' ,  'Map' ,  'string' ,  'number' ,  'any' ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  validateExpression ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      expression : MetadataValue  |  MetadataSymbolicExpression  |  MetadataError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! expression )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( Array . isArray ( expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      expression . forEach ( validateExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( typeof  expression  ===  'object'  &&  ! expression . hasOwnProperty ( '__symbolic' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Object . getOwnPropertyNames ( expression ) . forEach ( v  = >  validateExpression ( ( < any > expression ) [ v ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( isMetadataError ( expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      reportError ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( isMetadataGlobalReferenceExpression ( expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! locals . has ( expression . name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  reference  =  < MetadataValue > metadata [ expression . name ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( reference )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( isFunctionMetadata ( expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      validateFunction ( < any > expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( isMetadataSymbolicExpression ( expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( expression . __symbolic )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'binary' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  binaryExpression  =  < MetadataSymbolicBinaryExpression > expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( binaryExpression . left ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( binaryExpression . right ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'call' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'new' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  callExpression  =  < MetadataSymbolicCallExpression > expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( callExpression . expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( callExpression . arguments )  callExpression . arguments . forEach ( validateExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'index' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  indexExpression  =  < MetadataSymbolicIndexExpression > expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( indexExpression . expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( indexExpression . index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'pre' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  prefixExpression  =  < MetadataSymbolicPrefixExpression > expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( prefixExpression . operand ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'select' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  selectExpression  =  < MetadataSymbolicSelectExpression > expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( selectExpression . expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'spread' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  spreadExpression  =  < MetadataSymbolicSpreadExpression > expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( spreadExpression . expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  'if' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  ifExpression  =  < MetadataSymbolicIfExpression > expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( ifExpression . condition ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( ifExpression . elseExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( ifExpression . thenExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-18 15:17:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  function  validateMember ( classData : ClassMetadata ,  member : MemberMetadata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( member . decorators )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      member . decorators . forEach ( validateExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( isMethodMetadata ( member )  &&  member . parameterDecorators )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      member . parameterDecorators . forEach ( validateExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-18 15:17:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Only validate parameters of classes for which we know that are used with our DI
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( classData . decorators  &&  isConstructorMetadata ( member )  &&  member . parameters )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      member . parameters . forEach ( validateExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  validateClass ( classData : ClassMetadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( classData . decorators )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      classData . decorators . forEach ( validateExpression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( classData . members )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Object . getOwnPropertyNames ( classData . members ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-18 15:17:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          . forEach ( name  = >  classData . members [ name ] . forEach ( ( m )  = >  validateMember ( classData ,  m ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 14:45:00 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( classData . statics )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Object . getOwnPropertyNames ( classData . statics ) . forEach ( name  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  staticMember  =  classData . statics [ name ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( isFunctionMetadata ( staticMember ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( staticMember . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          validateExpression ( staticMember ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  validateFunction ( functionDeclaration : FunctionMetadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( functionDeclaration . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  oldLocals  =  locals ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( functionDeclaration . parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        locals  =  new  Set ( oldLocals . values ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( functionDeclaration . parameters ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          functionDeclaration . parameters . forEach ( n  = >  locals . add ( n ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      validateExpression ( functionDeclaration . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      locals  =  oldLocals ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  shouldReportNode ( node : ts.Node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  nodeStart  =  node . getStart ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  ! ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          node . pos  !=  nodeStart  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          sourceFile . text . substring ( node . pos ,  nodeStart ) . indexOf ( '@dynamic' )  >=  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  reportError ( error : MetadataError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  node  =  nodeMap . get ( error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( shouldReportNode ( node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  lineInfo  =  error . line  !=  undefined  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          error . character  !=  undefined  ?  ` : ${ error . line  +  1 } : ${ error . character  +  1 } `  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                         ` : ${ error . line  +  1 } `  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          ` ${ sourceFile . fileName } ${ lineInfo } : Metadata collected contains an error that will be reported at runtime:  ${ expandedMessage ( error ) } . \ n   ${ JSON . stringify ( error ) } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Object . getOwnPropertyNames ( metadata ) . forEach ( name  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  entry  =  metadata [ name ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( isClassMetadata ( entry ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 22:52:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        validateClass ( entry ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  catch  ( e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  node  =  nodeMap . get ( entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( shouldReportNode ( node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( node )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          const  { line ,  character }  =  sourceFile . getLineAndCharacterOfPosition ( node . getStart ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              ` ${ sourceFile . fileName } : ${ line  +  1 } : ${ character  +  1 } : Error encountered in metadata generated for exported symbol ' ${ name } ':  \ n  ${ e . message } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ` Error encountered in metadata generated for exported symbol  ${ name } :  \ n  ${ e . message } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 15:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Collect parameter names from a function.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  namesOf ( parameters : ts.NodeArray < ts.ParameterDeclaration > ) :  string [ ]  {  
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  const  result : string [ ]  =  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 15:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  addNamesOf ( name : ts.Identifier  |  ts . BindingPattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( name . kind  ==  ts . SyntaxKind . Identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  identifier  =  < ts.Identifier > name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      result . push ( identifier . text ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  bindingPattern  =  < ts.BindingPattern > name ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      for  ( const  element  of  bindingPattern . elements )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 11:34:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  name  =  ( element  as  any ) . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          addNamesOf ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 15:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 14:08:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  ( const  parameter  of  parameters )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 15:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    addNamesOf ( parameter . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  expandedMessage ( error : any ) :  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( error . message )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'Reference to non-exported class' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( error . context  &&  error . context . className )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ` Reference to a non-exported class  ${ error . context . className } . Consider exporting the class ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'Variable not initialized' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  'Only initialized variables and constants can be referenced because the value of this variable is needed by the template compiler' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'Destructuring not supported' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  'Referencing an exported destructured variable or constant is not supported by the template compiler. Consider simplifying this to avoid destructuring' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'Could not resolve type' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( error . context  &&  error . context . typeName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ` Could not resolve type  ${ error . context . typeName } ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'Function call not supported' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      let  prefix  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          error . context  &&  error . context . name  ?  ` Calling function ' ${ error . context . name } ', f `  :  'F' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  prefix  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          'unction calls are not supported. Consider replacing the function or lambda with a reference to an exported function' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  'Reference to a local symbol' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( error . context  &&  error . context . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ` Reference to a local (non-exported) symbol ' ${ error . context . name } '. Consider exporting the symbol ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  error . message ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}