import * as ts from 'typescript' ; import { ReflectedType , TypeKind } from './types' ; function getExpressionForPropertyName ( name ) { if ( ts . isIdentifier ( name ) ) { return ts . createLiteral ( ts . idText ( name ) ) ; } return name ; } export function makeLiteral ( type ) { const assigns = [ ] ; const kindAssign = ts . createPropertyAssignment ( "kind" , ts . createLiteral ( type . kind ) ) ; const kindAssignComment = ts . addSyntheticTrailingComment ( kindAssign , ts . SyntaxKind . MultiLineCommentTrivia , TypeKind [ type . kind ] , false ) ; assigns . push ( kindAssignComment ) ; if ( type . initializer !== undefined ) { assigns . push ( ts . createPropertyAssignment ( "initializer" , type . initializer ) ) ; } switch ( type . kind ) { case TypeKind . Object : case TypeKind . Class : if ( type . name ) { assigns . push ( ts . createPropertyAssignment ( "name" , ts . createLiteral ( type . name ) ) ) ; } assigns . push ( ts . createPropertyAssignment ( "properties" , ts . createObjectLiteral ( type . properties . map ( ( { name , type } ) => ts . createPropertyAssignment ( getExpressionForPropertyName ( name ) , makeLiteral ( type ) ) ) ) ) ) ; if ( type . kind === TypeKind . Class ) { assigns . push ( ts . createPropertyAssignment ( "constructors" , ts . createArrayLiteral ( ( type ) . constructors . map ( ( { modifiers , parameters } ) => ts . createObjectLiteral ( [ ts . createPropertyAssignment ( "modifiers" , ts . createLiteral ( modifiers ) ) , ts . createPropertyAssignment ( "parameters" , ts . createArrayLiteral ( parameters . map ( ( { name , modifiers , type } ) => ts . createObjectLiteral ( [ ts . createPropertyAssignment ( "name" , ts . createLiteral ( name ) ) , ts . createPropertyAssignment ( "modifiers" , ts . createLiteral ( modifiers ) ) , ts . createPropertyAssignment ( "type" , makeLiteral ( type ) ) , ] ) ) ) ) ] ) ) ) ) ) ; } break ; } switch ( type . kind ) { case TypeKind . Tuple : assigns . push ( ts . createPropertyAssignment ( "elementTypes" , ts . createArrayLiteral ( type . elementTypes . map ( makeLiteral ) ) ) ) ; break ; case TypeKind . Union : assigns . push ( ts . createPropertyAssignment ( "types" , ts . createArrayLiteral ( type . types . map ( makeLiteral ) ) ) ) ; break ; case TypeKind . StringLiteral : case TypeKind . NumberLiteral : assigns . push ( ts . createPropertyAssignment ( 'value' , ts . createLiteral ( type . value ) ) ) ; break ; case TypeKind . Reference : assigns . push ( ts . createPropertyAssignment ( "type" , type . type ) ) ; assigns . push ( ts . createPropertyAssignment ( "arguments" , ts . createArrayLiteral ( type . arguments . map ( makeLiteral ) ) ) ) ; break ; case TypeKind . Class : if ( type . extends !== undefined ) { assigns . push ( ts . createPropertyAssignment ( "extends" , makeLiteral ( type . extends ) ) ) ; } break ; } return ts . createObjectLiteral ( assigns ) ; }