import * as ts from "typescript" ; import { Ast } from "../Ast/Ast" ; import { IdentifierInfo } from "./IdentifierInfo" ; import { Logger } from "../Reporting/Logger" ; import { Utils } from "../Utils/Utilities" ; class ContainerIdGenerator { static nextId = 1 ; static getNextId ( ) { return this . nextId ++ ; } } export class Container { private id : number ; private container : ts . Node ; private blockScopeContainer : ts . Node ; private containerFlags : Ast . ContainerFlags ; private parent : Container ; private childContainers : Container [ ] = [ ] ; private isBlockScope : boolean ; private baseClass : ts . Symbol = undefined ; private nameIndex : number ; public namesExcluded : ts . MapLike < boolean > = { } ; public localIdentifiers : ts . MapLike < IdentifierInfo > = { } ; public classifiableSymbols : ts . MapLike < ts . Symbol > = { } ; public excludedIdentifiers : ts . MapLike < IdentifierInfo > = { } ; public excludedProperties : ts . Symbol [ ] = [ ] ; public shortenedIdentifierCount = 0 ; constructor ( node , containerFlags , parentContainer ) { this . id = ContainerIdGenerator . getNextId ( ) ; this . containerFlags = containerFlags ; if ( containerFlags & Ast . ContainerFlags . IsBlockScopedContainer ) { this . blockScopeContainer = node ; this . isBlockScope = true ; this . parent = parentContainer . getParent ( ) ; } else { this . container = this . blockScopeContainer = node ; this . isBlockScope = false ; this . parent = this ; } this . nameIndex = 0 ; } public getId ( ) { return this . id ; } public addChildContainer ( container ) { this . childContainers . push ( container ) ; } public getChildren ( ) { return this . childContainers ; } public getParent ( ) { return this . parent ; } public getNameIndex ( ) { if ( this . isBlockScope ) { return this . parent . getNameIndex ( ) ; } return this . nameIndex ++ ; } public getNode ( ) { return this . isBlockScope ? this . blockScopeContainer : this . container ; } public getMembers ( ) { if ( this . container ) { switch ( this . container . kind ) { case ts . SyntaxKind . ClassDeclaration : return ( < ts . ClassDeclaration > this . container ) . members ; case ts . SyntaxKind . EnumDeclaration : return ( < ts . EnumDeclaration > this . container ) . members ; default : Logger . trace ( "Container::getMembers() unprocessed container kind: " , this . container . kind , this . getId ( ) ) ; } } return undefined ; } public getLocals ( ) { if ( this . container && this . containerFlags & Ast . ContainerFlags . HasLocals ) { switch ( this . container . kind ) { case ts . SyntaxKind . ModuleDeclaration : return ( < any > this . container ) . locals ; default : Logger . warn ( "Container::getLocals() unprocessed container kind: " , this . container . kind , this . getId ( ) ) ; } } return undefined ; } public isBlockScoped ( ) { return this . isBlockScope ; } public isFunctionScoped ( ) { if ( this . containerFlags & ( Ast . ContainerFlags . IsContainer | Ast . ContainerFlags . IsContainerWithLocals ) ) { return true ; } return false ; } public setBaseClass ( baseClass ) { if ( baseClass . flags & ts . SymbolFlags . Class ) { this . baseClass = baseClass ; } } public getBaseClass ( ) { return this . baseClass ; } public hasChild ( container ) { for ( let i = 0 ; i < this . childContainers . length ; i ++ ) { if ( container . getId ( ) === this . childContainers [ i ] . getId ( ) ) return true ; } return false ; } }