UNPKG

@code-to-json/core

Version:

[![Build Status](https://travis-ci.org/code-to-json/code-to-json.svg?branch=master)](https://travis-ci.org/code-to-json/code-to-json) [![Build Status](https://dev.azure.com/code-to-json/code-to-json/_apis/build/status/code-to-json.code-to-json)](https://d

140 lines (130 loc) 4.49 kB
import { isRef, refId } from '@code-to-json/utils'; import { mapUem } from '@code-to-json/utils-ts'; import { displayPartsToString, Symbol as Sym, SyntaxKind, TypeChecker, UnderscoreEscapedMap, } from 'typescript'; import { flagsToString } from '../flags'; import { ProcessingQueue } from '../processing-queue'; import { SymbolRef, TypeRef } from '../processing-queue/ref'; import { HasPosition, SerializedEntity } from '../types'; import serializeLocation from './location'; import serializeSignature, { SerializedSignature } from './signature'; export interface SerializedHeritageClause { clauseType: string; } export interface SerializedSymbol extends SerializedEntity<'symbol'>, Partial<HasPosition> { name: string; documentation?: string; external?: boolean; type?: TypeRef; members?: SymbolRef[]; exports?: SymbolRef[]; decorators?: string[]; modifiers?: string[]; globalExports?: SymbolRef[]; // declarations?: DeclarationRef[]; constructorSignatures?: SerializedSignature[]; callSignatures?: SerializedSignature[]; heritageClauses?: SerializedHeritageClause[]; jsDocTags?: Array<{ name: string; text?: string; }>; } function appendSymbolMap( uem: UnderscoreEscapedMap<Sym> | undefined, queue: ProcessingQueue, checker: TypeChecker, ): SymbolRef[] | undefined { if (uem && uem.size > 0) { return mapUem(uem, (val: Sym) => queue.queue(val, 'symbol', checker)).filter(isRef); } return undefined; } function conditionallyAppendTransformed<H extends {}, B, A extends H[K], K extends keyof H>( host: H, property: B | undefined, propertyName: K, transform: (b: B) => A, condition?: (prop: B) => prop is B, ): void { if (property && (condition ? condition(property) : true)) { const x: Partial<Pick<H, K>> = {}; /* eslint-disable no-param-reassign */ host[propertyName] = transform(property); } } /** * Serialize a TS Symbol * @param symbol Symbol to serialize * @param checker an instance of the TS type checker * @param ref Reference to the symbol * @param queue Processing queue */ export default function serializeSymbol( symbol: Sym, checker: TypeChecker, ref: SymbolRef, queue: ProcessingQueue, ): SerializedSymbol { const { exports, globalExports, members, flags, valueDeclaration } = symbol; const details: SerializedSymbol = { id: refId(ref), entity: 'symbol', name: symbol.getName(), flags: flagsToString(flags, 'symbol'), }; const typ = checker.getTypeOfSymbolAtLocation(symbol, valueDeclaration); if (valueDeclaration && valueDeclaration.getSourceFile().isDeclarationFile) { details.external = true; return details; } details.type = queue.queue(typ, 'type', checker); if (members) { details.members = appendSymbolMap(members, queue, checker); } conditionallyAppendTransformed(details, exports, 'exports', exps => appendSymbolMap(exps, queue, checker), ); conditionallyAppendTransformed(details, globalExports, 'globalExports', gexps => appendSymbolMap(gexps, queue, checker), ); const docComment = symbol.getDocumentationComment(checker); if (docComment.length > 0) { details.documentation = displayPartsToString(docComment); } if (valueDeclaration) { const { modifiers, decorators, pos, end } = valueDeclaration; const valDeclType = checker.getTypeOfSymbolAtLocation(symbol, valueDeclaration); const sourceFile = valueDeclaration.getSourceFile(); details.location = serializeLocation(sourceFile, pos, end); details.sourceFile = queue.queue(sourceFile, 'sourceFile', checker); conditionallyAppendTransformed(details, modifiers, 'modifiers', mods => mods.map(m => SyntaxKind[m.kind]), ); conditionallyAppendTransformed(details, decorators, 'decorators', decs => decs.map(d => SyntaxKind[d.kind]), ); const constructorSignatures = valDeclType .getConstructSignatures() .map(s => serializeSignature(s, checker, queue)); if (constructorSignatures && constructorSignatures.length > 0) { details.constructorSignatures = constructorSignatures; } const callSignatures = valDeclType .getCallSignatures() .map(s => serializeSignature(s, checker, queue)); if (callSignatures && callSignatures.length > 0) { details.callSignatures = callSignatures; } } const jsDocTags = symbol.getJsDocTags(); if (jsDocTags.length > 0) { details.jsDocTags = [...jsDocTags]; } return details; }