44
55import {
66 type BabelNodeFlow ,
7+ type BabelNodeMemberExpression ,
8+ type BabelNodeQualifiedName ,
79 type BabelNodeTSTypeAnnotation ,
810 type BabelNodeTypeAnnotation ,
911 type ClassDeclaration ,
@@ -15,6 +17,7 @@ import {
1517 type ObjectMethod ,
1618 type TSInterfaceDeclaration ,
1719 type TSMethodSignature ,
20+ type TSQualifiedName ,
1821 type TSType ,
1922 type TSTypeAnnotation ,
2023 isAnyTypeAnnotation ,
@@ -31,6 +34,7 @@ import {
3134 isGenericTypeAnnotation ,
3235 isIdentifier ,
3336 isIntersectionTypeAnnotation ,
37+ isMemberExpression ,
3438 isMixedTypeAnnotation ,
3539 isNullLiteralTypeAnnotation ,
3640 isNullableTypeAnnotation ,
@@ -47,6 +51,7 @@ import {
4751 isStringTypeAnnotation ,
4852 isTSAnyKeyword ,
4953 isTSArrayType ,
54+ isTSAsExpression ,
5055 isTSBigIntKeyword ,
5156 isTSBooleanKeyword ,
5257 isTSConstructSignatureDeclaration ,
@@ -81,6 +86,7 @@ import {
8186 isTSUnionType ,
8287 isTSUnknownKeyword ,
8388 isTSVoidKeyword ,
89+ isThisExpression ,
8490 isThisTypeAnnotation ,
8591 isTupleTypeAnnotation ,
8692 isTypeAnnotation ,
@@ -116,6 +122,9 @@ export function extractExtends(
116122 if ( isIdentifier ( node . superClass ) ) {
117123 return [ node . superClass . name ] ;
118124 }
125+ if ( isMemberExpression ( node . superClass ) ) {
126+ return [ reduceMemberExpression ( node . superClass ) ] ;
127+ }
119128
120129 return null ;
121130 }
@@ -127,6 +136,15 @@ export function extractExtends(
127136 if ( isIdentifier ( exs . id ) ) {
128137 return exs . id . name ;
129138 }
139+ if ( isQualifiedTypeIdentifier ( exs . id ) ) {
140+ return reduceQualifiedName ( exs . id ) ;
141+ }
142+ if ( isIdentifier ( exs . expression ) ) {
143+ return exs . expression . name ;
144+ }
145+ if ( isTSQualifiedName ( exs . expression ) ) {
146+ return reduceTSQualifiedName ( exs . expression ) ;
147+ }
130148
131149 // TODO: QualifiedTypeIdentifier
132150 return "" ;
@@ -144,10 +162,18 @@ export function extractImplements(
144162 if ( isTSExpressionWithTypeArguments ( impls ) ) {
145163 if ( isIdentifier ( impls . expression ) ) {
146164 return impls . expression . name ;
147- } else {
148- // TODO: TSQualifiedName
149- return "" ;
150165 }
166+ if ( isQualifiedTypeIdentifier ( impls . id ) ) {
167+ return reduceQualifiedName ( impls . id ) ;
168+ }
169+ if ( isIdentifier ( impls . expression ) ) {
170+ return impls . expression . name ;
171+ }
172+ if ( isTSQualifiedName ( impls . expression ) ) {
173+ return reduceTSQualifiedName ( impls . expression ) ;
174+ }
175+
176+ return "" ;
151177 }
152178 } ) : null ;
153179}
@@ -255,6 +281,60 @@ export function extractType(
255281 }
256282}
257283
284+ // Helper to resolve assignment to object chain, e.g. [Class.prototype].property
285+ function reduceMemberExpression ( expression : BabelNodeMemberExpression ) : string {
286+ let longname = "";
287+
288+ if ( isTSAsExpression ( expression ) ) {
289+ expression = expression . expression ;
290+ }
291+ if ( isThisExpression ( expression ) ) {
292+ return "this ";
293+ }
294+
295+ while ( expression . object ) {
296+ longname = expression . property . name + ( longname ? "." + longname : "" ) ;
297+ expression = expression . object ;
298+ }
299+
300+ longname = ( isThisExpression ( expression ) ? "this" : expression . name ) +
301+ ( longname ? "." : "" ) + longname ;
302+
303+ return longname ;
304+ }
305+
306+ // Reduce the qualified name into a string
307+ function reduceQualifiedName ( type : BabelNodeQualifiedName ) : string {
308+ let name = "" ;
309+
310+ while ( type && ! isIdentifier ( type ) ) {
311+ name = type . id . name + ( name ? "." : "" ) + name ;
312+ type = type . qualification ;
313+ }
314+
315+ if ( type ) {
316+ name = type . name + "." + name ;
317+ }
318+
319+ return name ;
320+ }
321+
322+ // Reduce the qualified name node into a string
323+ function reduceTSQualifiedName ( type : TSQualifiedName ) : string {
324+ let name = "";
325+
326+ while ( type && ! isIdentifier ( type ) ) {
327+ name = type . right . name + ( name ? "." : "" ) + name ;
328+ type = type . left ;
329+ }
330+
331+ if ( type ) {
332+ name = type . name + "." + name ;
333+ }
334+
335+ return name ;
336+ }
337+
258338// Resolve a flow type-annotation into a parsed DataType
259339function resolveFlowDataType ( type : BabelNodeTypeAnnotation | BabelNodeFlow | any ) : DataType {
260340 if ( isTypeAnnotation ( type ) ) {
@@ -290,18 +370,7 @@ function resolveFlowDataType(type: BabelNodeTypeAnnotation | BabelNodeFlow | any
290370 return dataType ;
291371 }
292372 if ( isQualifiedTypeIdentifier ( type ) ) {
293- let name = "" ;
294-
295- while ( type && ! isIdentifier ( type ) ) {
296- name = type . id . name + ( name ? "." : "" ) + name ;
297- type = type . qualification ;
298- }
299-
300- if ( type ) {
301- name = type . id + "." + name ;
302- }
303-
304- return createSimpleDocumentedType ( name ) ;
373+ return createSimpleDocumentedType ( reduceQualifiedName ( type ) ) ;
305374 }
306375 if ( isObjectTypeIndexer ( type ) ) {
307376 const id = type . id ? type . id . name : null ;
@@ -440,18 +509,7 @@ function resolveTSDataType(type: TSTypeAnnotation | TSType | any): DataType {
440509 if ( isIdentifier ( type ) ) {
441510 return createSimpleDocumentedType ( type . name ) ;
442511 } else if ( isTSQualifiedName ( type ) ) { // TSQualifiedName
443- let name = "";
444-
445- while ( type && ! isIdentifier ( type ) ) {
446- name = type . right . name + ( name ? "." : "" ) + name ;
447- type = type . left ;
448- }
449-
450- if ( type ) {
451- name = type . name + "." + name ;
452- }
453-
454- return createSimpleDocumentedType ( name ) ;
512+ return createSimpleDocumentedType ( reduceTSQualifiedName ( type ) ) ;
455513 }
456514
457515 if ( isTSType ( type ) ) {
0 commit comments