import * as ts from "typescript" ; import { Container } from "./ContainerContext" ; import { Ast } from "../Ast/Ast" ; import { Utils } from "../Utils/Utilities" ; import { Logger } from "../Reporting/Logger" ; export class IdentifierInfo { private identifier : ts . Identifier ; private symbol : ts . Symbol ; private containers : ts . MapLike < Container > = { } ; private identifiers : ts . Identifier [ ] = [ ] ; public shortenedName : string = undefined ; public isMinified : boolean = false ; constructor ( identifier , symbol , container ) { this . identifier = identifier ; this . symbol = symbol ; this . identifiers = [ identifier ] ; this . containers [ container . getId ( ) . toString ( ) ] = container ; } public getSymbol ( ) { return this . symbol ; } public getName ( ) { return this . symbol . name ; } public getId ( ) { let id = ( < any > this . symbol ) . id ; if ( id === undefined && this . symbol . valueDeclaration ) { id = ( < any > this . symbol . valueDeclaration ) . symbol . id ; } return id ? id . toString ( ) : undefined ; } public getContainers ( ) { return this . containers ; } public getIdentifiers ( ) { return this . identifiers ; } public addRef ( identifier , container ) { this . identifiers . push ( identifier ) ; if ( ! Utils . hasProperty ( this . containers , container . getId ( ) . toString ( ) ) ) { this . containers [ container . getId ( ) . toString ( ) ] = container ; } } public isNamespaceImportAlias ( ) { if ( ( this . symbol . flags & ts . SymbolFlags . Alias ) > 0 ) { if ( this . symbol . declarations [ 0 ] . kind === ts . SyntaxKind . NamespaceImport ) { return true ; } } return false ; } public isFunctionScopedVariable ( ) { if ( ( this . symbol . flags & ts . SymbolFlags . FunctionScopedVariable ) > 0 ) { let variableDeclaration = this . getVariableDeclaration ( ) ; if ( variableDeclaration ) { let flags = Ast . getSyntacticModifierFlagsNoCache ( variableDeclaration . parent . parent ) ; if ( flags & ts . ModifierFlags . Export ) { return false ; } return true ; } } return false ; } public isBlockScopedVariable ( ) { if ( ( this . symbol . flags & ts . SymbolFlags . BlockScopedVariable ) > 0 ) { let variableDeclaration = this . getVariableDeclaration ( ) ; if ( variableDeclaration ) { return ( ( variableDeclaration . parent . flags & ts . NodeFlags . Let ) !== 0 ) || ( ( variableDeclaration . parent . flags & ts . NodeFlags . Const ) !== 0 ) ; } } return false ; } public isParameter ( ) { if ( ( this . symbol . flags & ts . SymbolFlags . FunctionScopedVariable ) > 0 ) { if ( this . symbol . valueDeclaration . kind === ts . SyntaxKind . Parameter ) { return true ; } } return false ; } public isInternalClass ( ) { return Ast . isClassInternal ( this . symbol ) ; } public isInternalInterface ( ) { return Ast . isInterfaceInternal ( this . symbol ) ; } public isInternalFunction ( packageNamespace ) { if ( this . symbol . flags & ts . SymbolFlags . Function ) { if ( this . symbol . valueDeclaration . kind === ts . SyntaxKind . FunctionDeclaration ) { let flags = Ast . getSyntacticModifierFlagsNoCache ( this . symbol . valueDeclaration ) ; if ( Ast . isExportContext ( this . symbol ) || Ast . isAmbientContext ( this . symbol ) ) { return false ; } if ( ! ( flags & ts . ModifierFlags . Export ) ) { return true ; } if ( packageNamespace ) { let node = this . symbol . valueDeclaration ; while ( node ) { if ( node . flags & ts . NodeFlags . Namespace ) { let nodeNamespaceName = ( < any > node ) . name . text ; if ( nodeNamespaceName !== packageNamespace ) { return true ; } } node = node . parent ; } } } } return false ; } public isPrivateMethod ( ) { if ( ( this . symbol . flags & ts . SymbolFlags . Method ) > 0 ) { if ( this . symbol . valueDeclaration === undefined ) { return false ; } let flags = Ast . getSyntacticModifierFlagsNoCache ( this . symbol . valueDeclaration ) ; if ( ( flags & ts . ModifierFlags . Private ) > 0 ) { return true ; } let parent = ( < any > this . symbol ) . parent ; if ( parent && Ast . isClassInternal ( parent ) ) { if ( ! Ast . isClassAbstract ( parent ) ) { return true ; } } if ( parent && Ast . isInterfaceInternal ( parent ) ) { return false ; } } return false ; } public isPrivateProperty ( ) { if ( ( this . symbol . flags & ts . SymbolFlags . Property ) > 0 ) { if ( this . symbol . valueDeclaration === undefined ) { return false ; } let flags = Ast . getSyntacticModifierFlagsNoCache ( this . symbol . valueDeclaration ) ; if ( ( flags & ts . ModifierFlags . Private ) > 0 ) { return true ; } let parent = ( < any > this . symbol ) . parent ; if ( parent && Ast . isClassInternal ( parent ) ) { if ( ! Ast . isClassAbstract ( parent ) ) { return true ; } } } return false ; } private getVariableDeclaration ( ) { switch ( ( < ts . Node > this . identifier ) . parent . kind ) { case ts . SyntaxKind . VariableDeclaration : return < ts . VariableDeclaration > this . identifier . parent ; case ts . SyntaxKind . VariableDeclarationList : Logger . warn ( "VariableDeclaratioList in getVariableDeclaration() - returning null" ) ; break ; case ts . SyntaxKind . VariableStatement : Logger . warn ( "VariableStatement in getVariableDeclaration() - returning null" ) ; break ; } return null ; } }