@@ -401,3 +401,118 @@ impl ESTree for TSFunctionTypeParams<'_, '_> {
401401 Concat2 ( & fn_type. this_param , fn_type. params . as_ref ( ) ) . serialize ( serializer) ;
402402 }
403403}
404+
405+ /// Serializer for `qualifier` field of `TSImportType`.
406+ ///
407+ /// Our AST represents the qualifier as `TSImportTypeQualifier` with `IdentifierName` nodes.
408+ /// TS-ESTree represents it as `TSQualifiedName` with `Identifier` nodes.
409+ #[ ast_meta]
410+ #[ estree(
411+ ts_type = "TSQualifiedName | IdentifierName | null" ,
412+ raw_deser = "
413+ let qualifier = DESER[Option<TSImportTypeQualifier>](POS_OFFSET.qualifier);
414+ if (qualifier !== null) {
415+ if (qualifier.type === 'IdentifierName') {
416+ qualifier = {
417+ type: 'Identifier',
418+ decorators: [],
419+ name: qualifier.name,
420+ optional: false,
421+ typeAnnotation: null,
422+ start: qualifier.start,
423+ end: qualifier.end,
424+ };
425+ } else if (qualifier.type === 'TSImportTypeQualifiedName') {
426+ // Convert TSImportTypeQualifiedName to TSQualifiedName
427+ const convertQualifier = (q) => {
428+ if (q.type === 'IdentifierName') {
429+ return {
430+ type: 'Identifier',
431+ decorators: [],
432+ name: q.name,
433+ optional: false,
434+ typeAnnotation: null,
435+ start: q.start,
436+ end: q.end,
437+ };
438+ } else if (q.type === 'TSImportTypeQualifiedName') {
439+ return {
440+ type: 'TSQualifiedName',
441+ left: convertQualifier(q.left),
442+ right: {
443+ type: 'Identifier',
444+ decorators: [],
445+ name: q.right.name,
446+ optional: false,
447+ typeAnnotation: null,
448+ start: q.right.start,
449+ end: q.right.end,
450+ },
451+ start: q.start,
452+ end: q.end,
453+ };
454+ }
455+ return q;
456+ };
457+ qualifier = convertQualifier(qualifier);
458+ }
459+ }
460+ qualifier
461+ "
462+ ) ]
463+ pub struct TSImportTypeQualifierConverter < ' a , ' b > ( pub & ' b TSImportType < ' a > ) ;
464+
465+ impl ESTree for TSImportTypeQualifierConverter < ' _ , ' _ > {
466+ fn serialize < S : Serializer > ( & self , serializer : S ) {
467+ match & self . 0 . qualifier {
468+ None => None :: < ( ) > . serialize ( serializer) ,
469+ Some ( qualifier) => {
470+ TSImportTypeQualifierAsQualifiedName ( qualifier) . serialize ( serializer) ;
471+ }
472+ }
473+ }
474+ }
475+
476+ struct TSImportTypeQualifierAsQualifiedName < ' a , ' b > ( & ' b TSImportTypeQualifier < ' a > ) ;
477+
478+ impl ESTree for TSImportTypeQualifierAsQualifiedName < ' _ , ' _ > {
479+ fn serialize < S : Serializer > ( & self , serializer : S ) {
480+ match self . 0 {
481+ TSImportTypeQualifier :: Identifier ( ident) => {
482+ // Convert IdentifierName to Identifier
483+ let mut state = serializer. serialize_struct ( ) ;
484+ state. serialize_field ( "type" , & JsonSafeString ( "Identifier" ) ) ;
485+ state. serialize_field ( "decorators" , & Vec :: < Decorator > :: new ( ) . as_slice ( ) ) ;
486+ state. serialize_field ( "name" , & ident. name ) ;
487+ state. serialize_field ( "optional" , & false ) ;
488+ state. serialize_field ( "typeAnnotation" , & None :: < ( ) > ) ;
489+ state. serialize_span ( ident. span ) ;
490+ state. end ( ) ;
491+ }
492+ TSImportTypeQualifier :: QualifiedName ( name) => {
493+ // Convert TSImportTypeQualifiedName to TSQualifiedName
494+ let mut state = serializer. serialize_struct ( ) ;
495+ state. serialize_field ( "type" , & JsonSafeString ( "TSQualifiedName" ) ) ;
496+ state. serialize_field ( "left" , & TSImportTypeQualifierAsQualifiedName ( & name. left ) ) ;
497+ state. serialize_field ( "right" , & IdentifierAsIdentifier ( & name. right ) ) ;
498+ state. serialize_span ( name. span ) ;
499+ state. end ( ) ;
500+ }
501+ }
502+ }
503+ }
504+
505+ struct IdentifierAsIdentifier < ' a , ' b > ( & ' b IdentifierName < ' a > ) ;
506+
507+ impl ESTree for IdentifierAsIdentifier < ' _ , ' _ > {
508+ fn serialize < S : Serializer > ( & self , serializer : S ) {
509+ let mut state = serializer. serialize_struct ( ) ;
510+ state. serialize_field ( "type" , & JsonSafeString ( "Identifier" ) ) ;
511+ state. serialize_field ( "decorators" , & Vec :: < Decorator > :: new ( ) . as_slice ( ) ) ;
512+ state. serialize_field ( "name" , & self . 0 . name ) ;
513+ state. serialize_field ( "optional" , & false ) ;
514+ state. serialize_field ( "typeAnnotation" , & None :: < ( ) > ) ;
515+ state. serialize_span ( self . 0 . span ) ;
516+ state. end ( ) ;
517+ }
518+ }
0 commit comments