Few cents about my commits

iOS13 PostFix #4: Compilation failed on @Bridge annotate covariant return synthetic method


This post continues the series of fixes discovered during compilation of CocoaTouch library.

PostFix #4: @Bridge annotated covatiant return bridget methods

Other postfixes:

Issue was discovered while compiling NWTxtRecord:

java.lang.IllegalArgumentException: @Bridge annotated method <org.robovm.apple.network.NWTxtRecord: org.robovm.apple.foundation.NSObject copy()> must be native
	at org.robovm.compiler.BridgeMethodCompiler.validateBridgeMethod(BridgeMethodCompiler.java:87)
	at org.robovm.compiler.BridgeMethodCompiler.doCompile(BridgeMethodCompiler.java:233)

Root case and fix

In source code NWTxtRecord doesn’t contain NSObject copy() method but containts NWTxtRecord copy(). Hovewer once class file is decompiled following methods can be found there:

  public native org.robovm.apple.network.NWTxtRecord copy();
    descriptor: ()Lorg/robovm/apple/network/NWTxtRecord;
    flags: (0x0101) ACC_PUBLIC, ACC_NATIVE
    RuntimeVisibleAnnotations: org.robovm.rt.bro.annotation.Bridge(symbol="nw_txt_record_copy")

  public org.robovm.apple.foundation.NSObject copy();
    descriptor: ()Lorg/robovm/apple/foundation/NSObject;
    RuntimeVisibleAnnotations: org.robovm.rt.bro.annotation.Bridge(symbol="nw_txt_record_copy")
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokevirtual #13                 // Method copy:()Lorg/robovm/apple/network/NWTxtRecord;
         4: areturn

NSObject copy() is present in class file and was added there by javac to handle overriden method with covariant return type. As NWTxtRecord extends NSObject at some level and NSObject contains copy() method with return type that covariant to NWTxtRecord. More details in Oracle’s document.

RoboVM compiler finds @Bridge annotation on this synthetic method (as these being copied since JDK-6695379) and tries to handle it as a @Bridge to native founction and it fails as method doesn’t match the criteria (currently it is not native).

There are two way of fix:

  • simple, as @Bridge methods are just binding for native function the name of method might be changed to eliminate override with covariant return type case;
  • modify the compiler to handle these methods, skips them actually.

Second approach was implemented and delivered as PR422