@@ -27,7 +27,10 @@ import {
2727 hasType ,
2828} from "./type-data"
2929import { 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"
3134import { TypeIterable , UNKNOWN_ITERABLE } from "./type-data/iterable"
3235import { getParent } from "../ast-utils"
3336import {
@@ -46,6 +49,7 @@ import {
4649 isUnionOrIntersection ,
4750 isUnknown ,
4851} from "../ts-utils"
52+ import { assertNever } from "../util"
4953
5054const ts = getTypeScript ( ) !
5155
@@ -596,94 +600,152 @@ function typeTextToTypeInfo(typeText?: string): TypeInfo | null {
596600 return jsDocTypeNodeToTypeInfo ( parseTypeText ( typeText ) )
597601}
598602
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 {
601607 if ( node == null ) {
602608 return null
603609 }
604- if ( node . type === "NAME " ) {
605- return typeNameToTypeInfo ( node . name )
610+ if ( node . type === "JsdocTypeName " ) {
611+ return typeNameToTypeInfo ( node . value )
606612 }
607- if ( node . type === "STRING_VALUE " ) {
613+ if ( node . type === "JsdocTypeStringValue " ) {
608614 return STRING
609615 }
610- if ( node . type === "NUMBER_VALUE " ) {
616+ if ( node . type === "JsdocTypeNumber " ) {
611617 return NUMBER
612618 }
613619 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 "
618624 ) {
619- return jsDocTypeNodeToTypeInfo ( node . value )
625+ return jsDocTypeNodeToTypeInfo ( node . element )
620626 }
621- if ( node . type === "VARIADIC " ) {
627+ if ( node . type === "JsdocTypeVariadic " ) {
622628 return new TypeArray ( function * ( ) {
623- if ( node . value ) {
624- yield jsDocTypeNodeToTypeInfo ( node . value )
629+ if ( node . element ) {
630+ yield jsDocTypeNodeToTypeInfo ( node . element )
625631 } else {
626632 yield null
627633 }
628634 } )
629635 }
630- if ( node . type === "UNION" || node . type === "INTERSECTION" ) {
636+ if (
637+ node . type === "JsdocTypeUnion" ||
638+ node . type === "JsdocTypeIntersection"
639+ ) {
631640 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 )
639643 }
640644 } )
641645 }
642- if ( node . type === "GENERIC " ) {
643- const subject = jsDocTypeNodeToTypeInfo ( node . subject )
646+ if ( node . type === "JsdocTypeGeneric " ) {
647+ const subject = jsDocTypeNodeToTypeInfo ( node . left )
644648 if ( hasType ( subject , "Array" ) ) {
645649 return new TypeArray ( function * ( ) {
646- yield jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] )
650+ yield jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] )
647651 } )
648652 }
649653 if ( hasType ( subject , "Map" ) ) {
650654 return new TypeMap (
651- ( ) => jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] ) ,
652- ( ) => jsDocTypeNodeToTypeInfo ( node . objects [ 1 ] ) ,
655+ ( ) => jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] ) ,
656+ ( ) => jsDocTypeNodeToTypeInfo ( node . elements [ 1 ] ) ,
653657 )
654658 }
655659 if ( hasType ( subject , "Set" ) ) {
656- return new TypeSet ( ( ) => jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] ) )
660+ return new TypeSet ( ( ) => jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] ) )
657661 }
658662 if ( subject === UNKNOWN_ITERABLE ) {
659663 return new TypeIterable ( ( ) =>
660- jsDocTypeNodeToTypeInfo ( node . objects [ 0 ] ) ,
664+ jsDocTypeNodeToTypeInfo ( node . elements [ 0 ] ) ,
661665 )
662666 }
663667 return subject
664668 }
665- if ( node . type === "RECORD " ) {
669+ if ( node . type === "JsdocTypeObject " ) {
666670 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 )
669716 }
670717 } )
671718 }
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+ ) {
673735 return null
674736 }
675737 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 "
682744 ) {
683745 return null
684746 }
685747
686- return null
748+ throw assertNever ( node )
687749}
688750
689751/** Get type from type name */
0 commit comments