@@ -27,7 +27,10 @@ import {
27
27
hasType ,
28
28
} from "./type-data"
29
29
import { getJSDoc , parseTypeText } from "./jsdoc"
30
- import type { JSDocTypeNode } from "./jsdoc/jsdoctypeparser-ast"
30
+ import type {
31
+ RootResult as JSDocTypeRootResult ,
32
+ KeyValueResult ,
33
+ } from "jsdoc-type-pratt-parser"
31
34
import { TypeIterable , UNKNOWN_ITERABLE } from "./type-data/iterable"
32
35
import { getParent } from "../ast-utils"
33
36
import {
@@ -46,6 +49,7 @@ import {
46
49
isUnionOrIntersection ,
47
50
isUnknown ,
48
51
} from "../ts-utils"
52
+ import { assertNever } from "../util"
49
53
50
54
const ts = getTypeScript ( ) !
51
55
@@ -596,94 +600,152 @@ function typeTextToTypeInfo(typeText?: string): TypeInfo | null {
596
600
return jsDocTypeNodeToTypeInfo ( parseTypeText ( typeText ) )
597
601
}
598
602
599
- /** Get type from JSDocTypeNode */
600
- function jsDocTypeNodeToTypeInfo ( node : JSDocTypeNode | null ) : TypeInfo | null {
603
+ /** Get type from jsdoc-type-pratt-parser's RootResult */
604
+ function jsDocTypeNodeToTypeInfo (
605
+ node : JSDocTypeRootResult | null ,
606
+ ) : TypeInfo | null {
601
607
if ( node == null ) {
602
608
return null
603
609
}
604
- if ( node . type === "NAME " ) {
605
- return typeNameToTypeInfo ( node . name )
610
+ if ( node . type === "JsdocTypeName " ) {
611
+ return typeNameToTypeInfo ( node . value )
606
612
}
607
- if ( node . type === "STRING_VALUE " ) {
613
+ if ( node . type === "JsdocTypeStringValue " ) {
608
614
return STRING
609
615
}
610
- if ( node . type === "NUMBER_VALUE " ) {
616
+ if ( node . type === "JsdocTypeNumber " ) {
611
617
return NUMBER
612
618
}
613
619
if (
614
- node . type === "OPTIONAL " ||
615
- node . type === "NULLABLE " ||
616
- node . type === "NOT_NULLABLE " ||
617
- node . type === "PARENTHESIS "
620
+ node . type === "JsdocTypeOptional " ||
621
+ node . type === "JsdocTypeNullable " ||
622
+ node . type === "JsdocTypeNotNullable " ||
623
+ node . type === "JsdocTypeParenthesis "
618
624
) {
619
- return jsDocTypeNodeToTypeInfo ( node . value )
625
+ return jsDocTypeNodeToTypeInfo ( node . element )
620
626
}
621
- if ( node . type === "VARIADIC " ) {
627
+ if ( node . type === "JsdocTypeVariadic " ) {
622
628
return new TypeArray ( function * ( ) {
623
- if ( node . value ) {
624
- yield jsDocTypeNodeToTypeInfo ( node . value )
629
+ if ( node . element ) {
630
+ yield jsDocTypeNodeToTypeInfo ( node . element )
625
631
} else {
626
632
yield null
627
633
}
628
634
} )
629
635
}
630
- if ( node . type === "UNION" || node . type === "INTERSECTION" ) {
636
+ if (
637
+ node . type === "JsdocTypeUnion" ||
638
+ node . type === "JsdocTypeIntersection"
639
+ ) {
631
640
return TypeUnionOrIntersection . buildType ( function * ( ) {
632
- const left = jsDocTypeNodeToTypeInfo ( node . left )
633
- if ( left ) {
634
- yield left
635
- }
636
- const right = jsDocTypeNodeToTypeInfo ( node . right )
637
- if ( right ) {
638
- yield right
641
+ for ( const e of node . elements ) {
642
+ yield jsDocTypeNodeToTypeInfo ( e )
639
643
}
640
644
} )
641
645
}
642
- if ( node . type === "GENERIC " ) {
643
- const subject = jsDocTypeNodeToTypeInfo ( node . subject )
646
+ if ( node . type === "JsdocTypeGeneric " ) {
647
+ const subject = jsDocTypeNodeToTypeInfo ( node . left )
644
648
if ( hasType ( subject , "Array" ) ) {
645
649
return new TypeArray ( function * ( ) {
646
- yield jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] )
650
+ yield jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] )
647
651
} )
648
652
}
649
653
if ( hasType ( subject , "Map" ) ) {
650
654
return new TypeMap (
651
- ( ) => jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] ) ,
652
- ( ) => jsDocTypeNodeToTypeInfo ( node . objects [ 1 ] ) ,
655
+ ( ) => jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] ) ,
656
+ ( ) => jsDocTypeNodeToTypeInfo ( node . elements [ 1 ] ) ,
653
657
)
654
658
}
655
659
if ( hasType ( subject , "Set" ) ) {
656
- return new TypeSet ( ( ) => jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] ) )
660
+ return new TypeSet ( ( ) => jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] ) )
657
661
}
658
662
if ( subject === UNKNOWN_ITERABLE ) {
659
663
return new TypeIterable ( ( ) =>
660
- jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] ) ,
664
+ jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] ) ,
661
665
)
662
666
}
663
667
return subject
664
668
}
665
- if ( node . type === "RECORD " ) {
669
+ if ( node . type === "JsdocTypeObject " ) {
666
670
return new TypeObject ( function * ( ) {
667
- for ( const entry of node . entries ) {
668
- yield [ entry . key , ( ) => jsDocTypeNodeToTypeInfo ( entry . value ) ]
671
+ for ( const element of node . elements ) {
672
+ if ( element . type === "JsdocTypeObjectField" ) {
673
+ if ( typeof element . key !== "string" ) {
674
+ // unknown key
675
+ continue
676
+ }
677
+ yield [
678
+ element . key ,
679
+ ( ) =>
680
+ element . right
681
+ ? jsDocTypeNodeToTypeInfo ( element . right )
682
+ : null ,
683
+ ]
684
+ } else if ( element . type === "JsdocTypeJsdocObjectField" ) {
685
+ if (
686
+ element . left . type === "JsdocTypeNullable" &&
687
+ element . left . element . type === "JsdocTypeName"
688
+ ) {
689
+ yield [
690
+ element . left . element . value ,
691
+ ( ) =>
692
+ element . right
693
+ ? jsDocTypeNodeToTypeInfo ( element . right )
694
+ : null ,
695
+ ]
696
+ }
697
+ }
698
+ }
699
+ } )
700
+ }
701
+ if ( node . type === "JsdocTypeTuple" ) {
702
+ if ( node . elements [ 0 ] . type === "JsdocTypeKeyValue" ) {
703
+ const elements = node . elements as KeyValueResult [ ]
704
+ return new TypeArray ( function * ( ) {
705
+ for ( const element of elements ) {
706
+ if ( element . right ) {
707
+ yield jsDocTypeNodeToTypeInfo ( element . right )
708
+ }
709
+ }
710
+ } )
711
+ }
712
+ const elements = node . elements as JSDocTypeRootResult [ ]
713
+ return new TypeArray ( function * ( ) {
714
+ for ( const element of elements ) {
715
+ yield jsDocTypeNodeToTypeInfo ( element )
669
716
}
670
717
} )
671
718
}
672
- if ( node . type === "ANY" || node . type === "UNKNOWN" ) {
719
+ if ( node . type === "JsdocTypeFunction" ) {
720
+ if ( node . returnType ) {
721
+ const returnType = node . returnType
722
+ return new TypeFunction ( ( ) => jsDocTypeNodeToTypeInfo ( returnType ) )
723
+ }
724
+ return UNKNOWN_FUNCTION
725
+ }
726
+ if ( node . type === "JsdocTypeTypeof" ) {
727
+ return new TypeFunction ( ( ) => jsDocTypeNodeToTypeInfo ( node . element ) )
728
+ }
729
+ if (
730
+ node . type === "JsdocTypeAny" ||
731
+ node . type === "JsdocTypeUnknown" ||
732
+ node . type === "JsdocTypeNull" ||
733
+ node . type === "JsdocTypeUndefined"
734
+ ) {
673
735
return null
674
736
}
675
737
if (
676
- node . type === "MEMBER " ||
677
- node . type === "INNER_MEMBER " ||
678
- node . type === "INSTANCE_MEMBER " ||
679
- node . type === "EXTERNAL " ||
680
- node . type === "FILE_PATH " ||
681
- node . type === "MODULE "
738
+ node . type === "JsdocTypeImport " ||
739
+ node . type === "JsdocTypeKeyof " ||
740
+ node . type === "JsdocTypeNamePath " ||
741
+ node . type === "JsdocTypePredicate " ||
742
+ node . type === "JsdocTypeSpecialNamePath " ||
743
+ node . type === "JsdocTypeSymbol "
682
744
) {
683
745
return null
684
746
}
685
747
686
- return null
748
+ throw assertNever ( node )
687
749
}
688
750
689
751
/** Get type from type name */
0 commit comments