IDE: Fire
Version: 8.3.93.1987
Target jdk1.8.0_74 (Android Studio 2.1.1)
Description:
The following code compiles for both Apple’s Swift and Elements Silver toolchain.
public subscript(z: UInt, x: UInt, y: UInt) -> QuadTreeNode? {
guard let tileID = try? TileID(x: x, y: y, level: z) else { return nil }
return self.node(forTileID: tileID)
}
However when .jar used from Android Studio Project the following runtime error is thrown:
java.lang.VerifyError: (class: geobingancore/android/QuadTree, method: getItem signature: (JJJ)Lgeobingancore/android/QuadTreeNode;) catch_type not a subclass of Throwable
This occurs in subscript(z: UInt, x: UInt, y: Uint) when you use try?, in disassembled java it look the following way. catch argument has Object type instead of Throwable.
public QuadTreeNode getItem(long z, long x, long y) {
Object tileID = null;
TileID tmp$1 = null;
try {
tmp$1 = new TileID(x, y, z);
} catch (Object var10) {
;
}
return tmp$1 == null?null:self.node(tmp$1);
}
This is kindoff really fundamental compiler toolchain issue when you use optional try?.
However the error resolved when you rewrite subscript(z: UInt, x: UInt, y: Uint) in more classical way:
public subscript(z: UInt, x: UInt, y: UInt) -> QuadTreeNode? {
do {
let tileID = try TileID(x: x, y: y, level: z)
return self.node(forTileID: tileID)
} catch {
return nil
}
}
The resulting Java disassembly will then look valid:
public QuadTreeNode getItem(long z, long x, long y) {
QuadTreeNode Result = null;
try {
TileID tileID = new TileID(x, y, z);
Result = self.node(tileID);
} catch (Throwable var10) {
Result = null;
}
return Result;
}