@@ -129,6 +129,7 @@ public void TestInterfaceWithInstanceType()
129129 ParseAssert ( """
130130 @interface MyInterface
131131 + (instancetype)getInstance;
132+ - (instancetype)get;
132133 @end
133134 """ ,
134135 compilation =>
@@ -138,12 +139,19 @@ @interface MyInterface
138139 var myInterface = compilation . Classes [ 0 ] ;
139140 Assert . AreEqual ( CppClassKind . ObjCInterface , myInterface . ClassKind ) ;
140141 Assert . AreEqual ( "MyInterface" , myInterface . Name ) ;
141- Assert . AreEqual ( 1 , myInterface . Functions . Count ) ;
142+ Assert . AreEqual ( 2 , myInterface . Functions . Count ) ;
143+
142144 Assert . AreEqual ( "getInstance" , myInterface . Functions [ 0 ] . Name ) ;
143145 Assert . IsTrue ( ( myInterface . Functions [ 0 ] . Flags & CppFunctionFlags . ClassMethod ) != 0 ) ;
144- var pointerType = myInterface . Functions [ 0 ] . ReturnType as CppPointerType ;
145- Assert . IsNotNull ( pointerType ) ;
146- Assert . AreEqual ( myInterface , pointerType ! . ElementType ) ;
146+ var typedef = myInterface . Functions [ 0 ] . ReturnType as CppTypedef ;
147+ Assert . IsTrue ( typedef is not null && typedef . ElementType is CppPrimitiveType prim && prim . Kind == CppPrimitiveKind . ObjCObject , $ "Invalid return type found for getInstance { myInterface . Functions [ 0 ] . ReturnType } ") ;
148+
149+ Assert . AreEqual ( "get" , myInterface . Functions [ 1 ] . Name ) ;
150+ Assert . IsTrue ( ( myInterface . Functions [ 1 ] . Flags & CppFunctionFlags . Method ) != 0 ) ;
151+ Assert . IsTrue ( ( myInterface . Functions [ 1 ] . Flags & CppFunctionFlags . ClassMethod ) == 0 ) ;
152+ var typedef2 = myInterface . Functions [ 1 ] . ReturnType as CppTypedef ;
153+ Assert . IsTrue ( typedef2 is not null && typedef2 . ElementType is CppPrimitiveType prim2 && prim2 . Kind == CppPrimitiveKind . ObjCObject , $ "Invalid return type found for getInstance { myInterface . Functions [ 1 ] . ReturnType } ") ;
154+
147155 } , GetDefaultObjCOptions ( )
148156 ) ;
149157 }
@@ -357,7 +365,92 @@ @interface MyInterface (MyCategory)
357365 } , GetDefaultObjCOptions ( )
358366 ) ;
359367 }
360-
368+
369+ [ Test ]
370+ public void TestInterfaceWithMethodsReturningObjects ( )
371+ {
372+ ParseAssert ( """
373+ @interface MyInterface1
374+ + (MyInterface1*)getInstance1;
375+ @end
376+
377+ @interface MyInterface2<T1> : MyInterface1
378+ @end
379+
380+ @interface MyInterface2NoGeneric
381+ @end
382+
383+ @protocol MyProtocol
384+ @end
385+
386+ @interface MyInterface3
387+ + (MyInterface2<MyInterface1*>*)getInstance2;
388+ + (MyInterface2NoGeneric<MyProtocol>*)getInstanceWithProtocol3;
389+ + (id<MyProtocol>)getInstanceWithProtocol4;
390+ @end
391+ """ ,
392+ compilation =>
393+ {
394+ Assert . False ( compilation . HasErrors ) ;
395+
396+ Assert . AreEqual ( 5 , compilation . Classes . Count ) ;
397+
398+ var myInterface1 = compilation . Classes [ 0 ] ;
399+ Assert . AreEqual ( CppClassKind . ObjCInterface , myInterface1 . ClassKind ) ;
400+ Assert . AreEqual ( "MyInterface1" , myInterface1 . Name ) ;
401+
402+ var myInterface2 = compilation . Classes [ 1 ] ;
403+ Assert . AreEqual ( CppClassKind . ObjCInterface , myInterface2 . ClassKind ) ;
404+ Assert . AreEqual ( "MyInterface2" , myInterface2 . Name ) ;
405+
406+ var myInterface2NoGeneric = compilation . Classes [ 2 ] ;
407+ Assert . AreEqual ( CppClassKind . ObjCInterface , myInterface2NoGeneric . ClassKind ) ;
408+ Assert . AreEqual ( "MyInterface2NoGeneric" , myInterface2NoGeneric . Name ) ;
409+
410+ var myProtocol = compilation . Classes [ 3 ] ;
411+ Assert . AreEqual ( CppClassKind . ObjCProtocol , myProtocol . ClassKind ) ;
412+ Assert . AreEqual ( "MyProtocol" , myProtocol . Name ) ;
413+
414+ var myInterface3 = compilation . Classes [ 4 ] ;
415+
416+ Assert . AreEqual ( CppClassKind . ObjCInterface , myInterface3 . ClassKind ) ;
417+ Assert . AreEqual ( "MyInterface3" , myInterface3 . Name ) ;
418+ Assert . AreEqual ( 3 , myInterface3 . Functions . Count ) ;
419+ Assert . AreEqual ( "getInstance2" , myInterface3 . Functions [ 0 ] . Name ) ;
420+ Assert . AreEqual ( "getInstanceWithProtocol3" , myInterface3 . Functions [ 1 ] . Name ) ;
421+ Assert . AreEqual ( "getInstanceWithProtocol4" , myInterface3 . Functions [ 2 ] . Name ) ;
422+
423+ Assert . IsTrue ( myInterface3 . Functions [ 0 ] . ReturnType is CppPointerType pointerType &&
424+ pointerType . ElementType is CppObjCGenericType genericType &&
425+ ReferenceEquals ( genericType . BaseType , myInterface2 ) &&
426+ genericType . GenericArguments . Count == 1 &&
427+ genericType . GenericArguments [ 0 ] is CppPointerType pointerType2 &&
428+ ReferenceEquals ( pointerType2 . ElementType , myInterface1 ) ,
429+ "Unable to resolve return type getInstance2. Must be MyInterface2<MyInterface1*>*"
430+ ) ;
431+
432+ Assert . IsTrue ( myInterface3 . Functions [ 1 ] . ReturnType is CppPointerType pointerType3 &&
433+ pointerType3 . ElementType is CppObjCGenericType genericType2 &&
434+ ReferenceEquals ( genericType2 . BaseType , myInterface2NoGeneric ) &&
435+ genericType2 . ObjCProtocolRefs . Count == 1 &&
436+ ReferenceEquals ( genericType2 . ObjCProtocolRefs [ 0 ] , myProtocol ) ,
437+ "Unable to resolve return type getInstanceWithProtocol3. Must be MyInterface2NoGeneric<MyProtocol>*"
438+ ) ;
439+
440+ Assert . IsTrue ( myInterface3 . Functions [ 2 ] . ReturnType is CppPointerType pointerType4 &&
441+ pointerType4 . ElementType is CppObjCGenericType genericType3 &&
442+ genericType3 . BaseType is CppPrimitiveType primitiveType3 &&
443+ primitiveType3 . Kind == CppPrimitiveKind . ObjCObject &&
444+ genericType3 . ObjCProtocolRefs . Count == 1 &&
445+ ReferenceEquals ( genericType3 . ObjCProtocolRefs [ 0 ] , myProtocol ) ,
446+ "Unable to resolve return type getInstanceWithProtocol4. Must be id<MyProtocol>"
447+ ) ;
448+
449+ } , GetDefaultObjCOptions ( )
450+ ) ;
451+ }
452+
453+
361454 private static CppParserOptions GetDefaultObjCOptions ( )
362455 {
363456 return new CppParserOptions
0 commit comments