11import * as ts from 'typescript' ;
22import * as t from './types' ;
3+ import { Documentation } from './types/documentation' ;
34
45/**
56 * Options that specify how the parser should act
@@ -295,24 +296,28 @@ export function parseFromProgram(
295296 if ( node . name === componentName ) {
296297 const usedProps : Set < string > = new Set ( ) ;
297298 // squash props
298- node . types . forEach ( ( typeNode ) => {
299- usedProps . add ( typeNode . name ) ;
299+ node . props . forEach ( ( propNode ) => {
300+ usedProps . add ( propNode . name ) ;
300301
301- let { [ typeNode . name ] : currentTypeNode } = props ;
302+ let { [ propNode . name ] : currentTypeNode } = props ;
302303 if ( currentTypeNode === undefined ) {
303- currentTypeNode = typeNode ;
304- } else if ( currentTypeNode . $$id !== typeNode . $$id ) {
304+ currentTypeNode = propNode ;
305+ } else if ( currentTypeNode . $$id !== propNode . $$id ) {
305306 currentTypeNode = t . propNode (
306307 currentTypeNode . name ,
307- currentTypeNode . jsDoc ,
308- t . unionNode ( [ currentTypeNode . propType , typeNode . propType ] ) ,
309- currentTypeNode . optional || typeNode . optional ,
310- new Set ( Array . from ( currentTypeNode . filenames ) . concat ( Array . from ( typeNode . filenames ) ) ) ,
308+ {
309+ description : currentTypeNode . description ,
310+ defaultValue : currentTypeNode . defaultValue ,
311+ visibility : currentTypeNode . visibility ,
312+ } ,
313+ t . unionNode ( [ currentTypeNode . propType , propNode . propType ] ) ,
314+ currentTypeNode . optional || propNode . optional ,
315+ new Set ( Array . from ( currentTypeNode . filenames ) . concat ( Array . from ( propNode . filenames ) ) ) ,
311316 undefined ,
312317 ) ;
313318 }
314319
315- props [ typeNode . name ] = currentTypeNode ;
320+ props [ propNode . name ] = currentTypeNode ;
316321 } ) ;
317322
318323 usedPropsPerSignature . push ( usedProps ) ;
@@ -337,6 +342,7 @@ export function parseFromProgram(
337342 }
338343 return propType ;
339344 } ) ,
345+ getDocumentation ( symbol ) ,
340346 node . getSourceFile ( ) . fileName ,
341347 ) ,
342348 ) ;
@@ -356,6 +362,7 @@ export function parseFromProgram(
356362 t . componentNode (
357363 name ,
358364 properties . map ( ( x ) => checkSymbol ( x , new Set ( [ ( type as any ) . id ] ) ) ) ,
365+ getDocumentation ( checker . getSymbolAtLocation ( type . symbol ?. valueDeclaration ! ) ) ,
359366 propsFilename ,
360367 ) ,
361368 ) ;
@@ -460,9 +467,9 @@ export function parseFromProgram(
460467 }
461468
462469 {
463- const typeNode = type as any ;
470+ const propNode = type as any ;
464471
465- const symbol = typeNode . aliasSymbol ? typeNode . aliasSymbol : typeNode . symbol ;
472+ const symbol = propNode . aliasSymbol ? propNode . aliasSymbol : propNode . symbol ;
466473 const typeName = symbol ? checker . getFullyQualifiedName ( symbol ) : null ;
467474 switch ( typeName ) {
468475 case 'global.JSX.Element' :
@@ -526,7 +533,7 @@ export function parseFromProgram(
526533 if ( type . isLiteral ( ) ) {
527534 return t . literalNode (
528535 type . isStringLiteral ( ) ? `"${ type . value } "` : type . value ,
529- getDocumentation ( type . symbol ) ,
536+ getDocumentation ( type . symbol ) ?. description ,
530537 ) ;
531538 }
532539 return t . literalNode ( checker . typeToString ( type ) ) ;
@@ -607,7 +614,7 @@ export function parseFromProgram(
607614 return t . simpleTypeNode ( 'any' ) ;
608615 }
609616
610- function getDocumentation ( symbol ?: ts . Symbol ) : string | undefined {
617+ function getDocumentation ( symbol ?: ts . Symbol ) : Documentation | undefined {
611618 if ( ! symbol ) {
612619 return undefined ;
613620 }
@@ -619,17 +626,17 @@ export function parseFromProgram(
619626 if ( comments && comments . length === 1 ) {
620627 const commentNode = comments [ 0 ] ;
621628 if ( ts . isJSDoc ( commentNode ) ) {
622- if ( Array . isArray ( commentNode . comment ) ) {
623- return commentNode . comment . map ( ( x ) => x . text ) . join ( '\n' ) ;
624- }
625-
626- return commentNode . comment as string | undefined ;
629+ return {
630+ description : commentNode . comment as string | undefined ,
631+ defaultValue : commentNode . tags ?. find ( ( t ) => t . tagName . text === 'default' ) ?. comment ,
632+ visibility : getVisibilityFromJSDoc ( commentNode ) ,
633+ } ;
627634 }
628635 }
629636 }
630637
631638 const comment = ts . displayPartsToString ( symbol . getDocumentationComment ( checker ) ) ;
632- return comment ? comment : undefined ;
639+ return comment ? { description : comment } : undefined ;
633640 }
634641
635642 function getSymbolFileNames ( symbol : ts . Symbol ) : Set < string > {
@@ -642,3 +649,19 @@ export function parseFromProgram(
642649function hasFlag ( typeFlags : number , flag : number ) {
643650 return ( typeFlags & flag ) === flag ;
644651}
652+
653+ function getVisibilityFromJSDoc ( doc : ts . JSDoc ) : Documentation [ 'visibility' ] | undefined {
654+ if ( doc . tags ?. some ( ( tag ) => tag . tagName . text === 'public' ) ) {
655+ return 'public' ;
656+ }
657+
658+ if ( doc . tags ?. some ( ( tag ) => tag . tagName . text === 'internal' ) ) {
659+ return 'internal' ;
660+ }
661+
662+ if ( doc . tags ?. some ( ( tag ) => tag . tagName . text === 'private' ) ) {
663+ return 'private' ;
664+ }
665+
666+ return undefined ;
667+ }
0 commit comments