import * as ts from 'typescript' ; import { ExtraCommandLineOptions , Imports } from '../types' ; import { FromWhat , STAR } from './common' ; import { addDynamicImports , mayContainDynamicImports } from './dynamic' ; import { extractExportFromImport , extractExportNames , extractExportStatement , } from './export' ; import { ENUM_NODE_KINDS } from './kinds' ; import { addImportsFromNamespace } from './imports-from-namespace' ; import { extractImport } from './import' ; import { namespaceBlacklist } from './namespaceBlacklist' ; type NamespaceHolder = { namespace : string ; } ; const hasModifier = ( node , mod ) : boolean | undefined => node . modifiers && node . modifiers . filter ( ( m ) => m . kind === mod ) . length > 0 ; const processExportDeclaration = ( node , addImport , addExport , exportNames , extraOptions ? ) : void => { const exportDecl = node as ts . ExportDeclaration ; if ( ( exportDecl . isTypeOnly && extraOptions ?. allowUnusedTypes ) || ( ENUM_NODE_KINDS . includes ( exportDecl . kind ) && extraOptions ?. allowUnusedEnums ) ) { return ; } const { moduleSpecifier } = exportDecl ; if ( moduleSpecifier === undefined ) { extractExportStatement ( exportDecl ) . forEach ( ( e ) => addExport ( e , node ) ) ; return ; } else { const { exported , imported } = extractExportFromImport ( exportDecl , moduleSpecifier ) ; const key = addImport ( imported ) ; if ( key ) { const { what } = exported ; if ( what == STAR ) { addExport ( `*:${ key }` , node ) ; } if ( what != STAR ) { if ( imported . isExportStarAs ) { addExport ( `*as:${ key }` , node ) ; } what . forEach ( ( w ) => exportNames . push ( w ) ) ; } } return ; } } ; const processExportKeyword = ( node , path , addExport , namespace , processSubNode , extraOptions ? ) : void => { if ( hasModifier ( node , ts . SyntaxKind . DefaultKeyword ) ) { addExport ( 'default' , node ) ; return ; } const decl = node as ts . DeclarationStatement ; const names = decl . name ? [ decl . name . text ] : extractExportNames ( path , node ) ; names . filter ( ( name ) => ! ! name ) . forEach ( ( name ) => { addExport ( namespace . namespace + name , node ) ; if ( extraOptions ?. searchNamespaces ) { const isNamespace = node . getChildren ( ) . some ( ( c ) => c . kind === ts . SyntaxKind . NamespaceKeyword ) ; if ( isNamespace ) { node . getChildren ( ) . filter ( ( c ) => c . kind === ts . SyntaxKind . Identifier ) . forEach ( ( c ) => { processSubNode ( c , namespace . namespace + name + '.' ) ; } ) ; namespace . namespace += name + '.' ; } } } ) ; } ; export const processNode = ( node , path , addImport , addExport , imports , exportNames , extraOptions ? , namespace = '' ) : void => { const { kind } = node ; const processSubNode = ( subNode , namespace ) : void => { processNode ( subNode , path , addImport , addExport , imports , exportNames , extraOptions , namespace ) ; } ; if ( kind === ts . SyntaxKind . ImportDeclaration ) { addImport ( extractImport ( node as ts . ImportDeclaration ) ) ; return ; } if ( kind === ts . SyntaxKind . ExportAssignment ) { addExport ( 'default' , node ) ; return ; } if ( kind === ts . SyntaxKind . ExportDeclaration ) { processExportDeclaration ( node , addImport , addExport , exportNames , extraOptions ) ; } if ( mayContainDynamicImports ( node ) ) { addDynamicImports ( node , addImport ) ; } if ( extraOptions ?. searchNamespaces ) { addImportsFromNamespace ( node , imports , addImport ) ; } if ( hasModifier ( node , ts . SyntaxKind . ExportKeyword ) ) { const nsHolder = { namespace , } ; processExportKeyword ( node , path , addExport , nsHolder , processSubNode , extraOptions ) ; namespace = nsHolder . namespace ; } if ( namespace . length > 0 ) { node . getChildren ( ) . filter ( ( c ) => ! namespaceBlacklist . includes ( c . kind ) ) . forEach ( ( c ) => { processSubNode ( c , namespace ) ; } ) ; } } ;