@@ -395,6 +395,34 @@ converters.NewExpression = (path, context): K.New => {
395395 } ;
396396} ;
397397
398+ converters . InterfaceDeclaration = ( path , context ) : K . InterfaceDeclaration => {
399+ return { kind : 'interfaceDeclaration' , id : convert ( path . get ( 'id' ) , context ) } ;
400+ } ;
401+
402+ converters . OpaqueType = ( path , context ) : K . OpaqueType => {
403+ // OpaqueTypes have several optional nodes that exist as a null when not present
404+ // We need to convert these when they exist, and ignore them when they don't;
405+ let supertypePath = path . get ( 'supertype' ) ;
406+ let impltypePath = path . get ( 'impltype' ) ;
407+ let typeParametersPath = path . get ( 'typeParameters' ) ;
408+
409+ // TODO we are having a fight at the moment with id returning a binding, not a node,
410+ // and don't have time to solve this properly - I am pathing it to being working-ish
411+ // here, and will come back to this later. If you find this comment still here and
412+ // want to fix this problem, I encourage you to do is.
413+
414+ let supertype ;
415+ let impltype ;
416+ let typeParameters ;
417+ let id = convert ( path . get ( 'id' ) , context ) ;
418+
419+ if ( supertypePath . node ) supertype = convert ( supertypePath , context ) ;
420+ if ( impltypePath . node ) impltype = convert ( impltypePath , context ) ;
421+ if ( typeParametersPath . node ) typeParameters = convert ( typeParametersPath , context ) ;
422+
423+ return { kind : 'opaqueType' , id, supertype, impltype, typeParameters } ;
424+ } ;
425+
398426converters . TypeofTypeAnnotation = ( path , context ) : K . Typeof => {
399427 let type = convert ( path . get ( 'argument' ) , { ...context , mode : 'value' } ) ;
400428 let ungeneric = resolveFromGeneric ( type ) ;
@@ -742,7 +770,6 @@ converters.Identifier = (path, context): K.Id => {
742770 } else if ( context . mode === 'type' ) {
743771 if ( kind === 'reference' ) {
744772 let bindingPath ;
745-
746773 if ( isFlowIdentifier ( path ) ) {
747774 let flowBinding = getTypeBinding ( path , name ) ;
748775 if ( ! flowBinding ) throw new Error ( ) ;
@@ -771,15 +798,21 @@ converters.Identifier = (path, context): K.Id => {
771798 }
772799
773800 if ( bindingPath ) {
774- if ( bindingPath . kind === 'module' ) {
775- bindingPath = bindingPath . path ;
776- }
801+ if ( name === 'SomethingId' )
802+ if ( bindingPath . kind === 'module' ) {
803+ bindingPath = bindingPath . path ;
804+ }
777805
778806 // If path is a descendant of bindingPath and share the same name, this is a recursive type.
779807 if ( path . isDescendant ( bindingPath ) && bindingPath . get ( 'id' ) . node . name === name ) {
780808 return { kind : 'id' , name } ;
781809 }
782810
811+ // This is a hack that stops horrible regression errors and problems
812+ if ( bindingPath . kind === 'unknown' ) {
813+ return { kind : 'id' , name } ;
814+ }
815+
783816 if ( bindingPath . kind !== 'module' ) {
784817 const convertedValue = convert ( bindingPath , context ) ;
785818 return {
@@ -1435,9 +1468,31 @@ function attachComments(source, dest) {
14351468 attachCommentProperty ( source , dest , 'innerComments' ) ;
14361469}
14371470
1471+ // This function is from mdn:
1472+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#Examples
1473+ const getCircularReplacer = ( ) => {
1474+ const seen = new WeakSet ( ) ;
1475+ return ( key , value ) => {
1476+ if ( typeof value === 'object' && value !== null ) {
1477+ if ( seen . has ( value ) ) {
1478+ return ;
1479+ }
1480+ seen . add ( value ) ;
1481+ }
1482+ return value ;
1483+ } ;
1484+ } ;
1485+
14381486function convert ( path , context ) {
1439- if ( typeof path . get !== 'function' )
1440- throw new Error ( `Did not pass a NodePath to convert() ${ JSON . stringify ( path ) } ` ) ;
1487+ if ( typeof path . get !== 'function' ) {
1488+ // We were getting incredible unhelpful errors here at times, so we have a circular replacement
1489+ // throw path.identifier;
1490+ let stringedPath = JSON . stringify ( path , getCircularReplacer ( ) , 2 ) ;
1491+ throw new Error ( `Did not pass a NodePath to convert() ${ stringedPath } ` ) ;
1492+ }
1493+
1494+ // console.log(path.node);
1495+
14411496 let converter = converters [ path . type ] ;
14421497 if ( ! converter ) throw new Error ( `Missing converter for: ${ path . type } ` ) ;
14431498 let result = converter ( path , context ) ;
0 commit comments