@@ -225,6 +225,8 @@ export class Parser {
225225 private readonly savePropValueAsString : boolean ;
226226 private readonly shouldIncludePropTagMap : boolean ;
227227 private readonly shouldIncludeExpression : boolean ;
228+ private propertiesOfPropsCache : Map < string , PropItem > = new Map ( ) ;
229+ private componentsInfoCache : Map < string , ComponentDoc | null > = new Map ( ) ;
228230
229231 constructor ( program : ts . Program , opts : ParserOptions ) {
230232 const {
@@ -299,11 +301,17 @@ export class Parser {
299301 const typeSymbol = type . symbol || type . aliasSymbol ;
300302 const originalName = rootExp . getName ( ) ;
301303 const filePath = source . fileName ;
304+ const cacheKey = `${ filePath } _${ originalName } ` ;
305+
306+ if ( this . componentsInfoCache . has ( cacheKey ) ) {
307+ return this . componentsInfoCache . get ( cacheKey ) as ComponentDoc | null ;
308+ }
302309
303310 if ( ! rootExp . valueDeclaration ) {
304311 if ( ! typeSymbol && ( rootExp . flags & ts . SymbolFlags . Alias ) !== 0 ) {
305312 commentSource = this . checker . getAliasedSymbol ( commentSource ) ;
306313 } else if ( ! typeSymbol ) {
314+ this . componentsInfoCache . set ( cacheKey , null ) ;
307315 return null ;
308316 } else {
309317 rootExp = typeSymbol ;
@@ -346,6 +354,7 @@ export class Parser {
346354 ( typeSymbol . getEscapedName ( ) === 'Requireable' ||
347355 typeSymbol . getEscapedName ( ) === 'Validator' )
348356 ) {
357+ this . componentsInfoCache . set ( cacheKey , null ) ;
349358 return null ;
350359 }
351360
@@ -365,6 +374,7 @@ export class Parser {
365374 let result : ComponentDoc | null = null ;
366375 if ( propsType ) {
367376 if ( ! commentSource . valueDeclaration ) {
377+ this . componentsInfoCache . set ( cacheKey , null ) ;
368378 return null ;
369379 }
370380 const defaultProps = this . extractDefaultPropsFromComponent (
@@ -404,6 +414,7 @@ export class Parser {
404414 result . rootExpression = exp ;
405415 }
406416
417+ this . componentsInfoCache . set ( cacheKey , result ) ;
407418 return result ;
408419 }
409420
@@ -701,60 +712,73 @@ export class Parser {
701712
702713 propertiesOfProps . forEach ( prop => {
703714 const propName = prop . getName ( ) ;
715+ const parent = getParentType ( prop ) ;
716+ const cacheKey = `${ parent ?. fileName } _${ propName } ` ;
717+ if ( this . propertiesOfPropsCache . has ( cacheKey ) ) {
718+ result [ propName ] = this . propertiesOfPropsCache . get (
719+ cacheKey
720+ ) as PropItem ;
721+ } else {
722+ // Find type of prop by looking in context of the props object itself.
723+ const propType = this . checker . getTypeOfSymbolAtLocation (
724+ prop ,
725+ propsObj . valueDeclaration !
726+ ) ;
704727
705- // Find type of prop by looking in context of the props object itself.
706- const propType = this . checker . getTypeOfSymbolAtLocation (
707- prop ,
708- propsObj . valueDeclaration !
709- ) ;
728+ const jsDocComment = this . findDocComment ( prop ) ;
729+ const hasCodeBasedDefault = defaultProps [ propName ] !== undefined ;
710730
711- const jsDocComment = this . findDocComment ( prop ) ;
712- const hasCodeBasedDefault = defaultProps [ propName ] !== undefined ;
731+ let defaultValue : { value : any } | null = null ;
713732
714- let defaultValue : { value : any } | null = null ;
733+ if ( hasCodeBasedDefault ) {
734+ defaultValue = { value : defaultProps [ propName ] } ;
735+ } else if ( jsDocComment . tags . default ) {
736+ defaultValue = { value : jsDocComment . tags . default } ;
737+ }
715738
716- if ( hasCodeBasedDefault ) {
717- defaultValue = { value : defaultProps [ propName ] } ;
718- } else if ( jsDocComment . tags . default ) {
719- defaultValue = { value : jsDocComment . tags . default } ;
720- }
739+ const parents = getDeclarations ( prop ) ;
740+ const declarations = prop . declarations || [ ] ;
741+ const baseProp = baseProps . find ( p => p . getName ( ) === propName ) ;
721742
722- const parent = getParentType ( prop ) ;
723- const parents = getDeclarations ( prop ) ;
724- const declarations = prop . declarations || [ ] ;
725- const baseProp = baseProps . find ( p => p . getName ( ) === propName ) ;
726-
727- const required =
728- ! isOptional ( prop ) &&
729- ! hasCodeBasedDefault &&
730- // If in a intersection or union check original declaration for "?"
731- // @ts -ignore
732- declarations . every ( d => ! d . questionToken ) &&
733- ( ! baseProp || ! isOptional ( baseProp ) ) ;
734-
735- const type = jsDocComment . tags . type
736- ? {
737- name : jsDocComment . tags . type
738- }
739- : this . getDocgenType ( propType , required ) ;
740-
741- const propTags = this . shouldIncludePropTagMap
742- ? { tags : jsDocComment . tags }
743- : { } ;
744- const description = this . shouldIncludePropTagMap
745- ? jsDocComment . description . replace ( / \r \n / g, '\n' )
746- : jsDocComment . fullComment . replace ( / \r \n / g, '\n' ) ;
747-
748- result [ propName ] = {
749- defaultValue,
750- description : description ,
751- name : propName ,
752- parent,
753- declarations : parents ,
754- required,
755- type,
756- ...propTags
757- } ;
743+ const required =
744+ ! isOptional ( prop ) &&
745+ ! hasCodeBasedDefault &&
746+ // If in a intersection or union check original declaration for "?"
747+ // @ts -ignore
748+ declarations . every ( d => ! d . questionToken ) &&
749+ ( ! baseProp || ! isOptional ( baseProp ) ) ;
750+
751+ const type = jsDocComment . tags . type
752+ ? {
753+ name : jsDocComment . tags . type
754+ }
755+ : this . getDocgenType ( propType , required ) ;
756+
757+ const propTags = this . shouldIncludePropTagMap
758+ ? { tags : jsDocComment . tags }
759+ : { } ;
760+ const description = this . shouldIncludePropTagMap
761+ ? jsDocComment . description . replace ( / \r \n / g, '\n' )
762+ : jsDocComment . fullComment . replace ( / \r \n / g, '\n' ) ;
763+
764+ const propItem : PropItem = {
765+ defaultValue,
766+ description : description ,
767+ name : propName ,
768+ parent,
769+ declarations : parents ,
770+ required,
771+ type,
772+ ...propTags
773+ } ;
774+ if ( parent ?. fileName . includes ( 'node_modules' ) ) {
775+ this . propertiesOfPropsCache . set (
776+ `${ parent . fileName } _${ propName } ` ,
777+ propItem
778+ ) ;
779+ }
780+ result [ propName ] = propItem ;
781+ }
758782 } ) ;
759783
760784 return result ;
0 commit comments