when trying to compile the following code, compiler complains that types do not match.
using [java]java.util::List as JList
abstract class Foo : JList
{
// Type mismatch in override of '[java]java.util::List.size' - '[java]::int' != 'sys::Int'
override Int size := 0
}
however, if the field is replaced with a method (Int size() { 0 }), everything is ok. it looks like the compiler does not infer types properly in that case. i've made a simple patch to compilerJava that seems to fix the problem:
diff -Nawur compilerJava.old/fan/JavaBridge.fan compilerJava/fan/JavaBridge.fan
--- compilerJava.old/fan/JavaBridge.fan 2010-05-13 09:42:40.000000000 +0700
+++ compilerJava/fan/JavaBridge.fan 2010-06-07 21:03:55.000000000 +0700
@@ -240,6 +240,10 @@
// route to method override checking
if (base is JavaMethod && def is MethodDef)
checkMethodOverride(t, base, def)
+
+ if (base is JavaMethod && def is FieldDef)
+ checkFieldOverride(t, base, def)
+
}
**
@@ -286,6 +290,14 @@
}
}
+ private Void checkFieldOverride(TypeDef t, JavaMethod base, FieldDef def)
+ {
+ if (isOverrideInferredType(base.returnType, def.fieldType))
+ {
+ base.returnType = def.fieldType
+ }
+ }
+
**
** When overriding a Java method check if the base type is
** is a Java primitive or array and the override definition is
brianTue 8 Jun 2010
Promoted to ticket #1113 and assigned to brian
brianThu 9 Sep 2010
Ticket cancelled
I spent some time this afternoon really digging into this issue (sorry it took so long). In Fantom we allow you to override a virtual method with a field (assuming the method has no parameters). In this case, the method in question uses a Java primitive type so we have to do special magic for coercion of int to sys::Int (which is really java.lang.Long).
But in the case of a field, this means we have to do something with the storage location and the setter too. We could change both to int, but this requires quite a bit of compiler magic. But if we leave the getter as int and the setter/storage as sys::Int then that has its own consequences.
Due to the complexity of this solution and all the boundary conditions its creates, I don't think we should support this feature. At least for now, we can always add it a later date without breaking compatibility. The simple workaround is to do it "Java-style" and override the method with a normal method and create a separate field.
swined Mon 7 Jun 2010
when trying to compile the following code, compiler complains that types do not match.
however, if the field is replaced with a method (Int size() { 0 }), everything is ok. it looks like the compiler does not infer types properly in that case. i've made a simple patch to compilerJava that seems to fix the problem:
brian Tue 8 Jun 2010
Promoted to ticket #1113 and assigned to brian
brian Thu 9 Sep 2010
Ticket cancelled
I spent some time this afternoon really digging into this issue (sorry it took so long). In Fantom we allow you to override a virtual method with a field (assuming the method has no parameters). In this case, the method in question uses a Java primitive type so we have to do special magic for coercion of
int
tosys::Int
(which is reallyjava.lang.Long
).But in the case of a field, this means we have to do something with the storage location and the setter too. We could change both to
int
, but this requires quite a bit of compiler magic. But if we leave the getter asint
and the setter/storage assys::Int
then that has its own consequences.Due to the complexity of this solution and all the boundary conditions its creates, I don't think we should support this feature. At least for now, we can always add it a later date without breaking compatibility. The simple workaround is to do it "Java-style" and override the method with a normal method and create a separate field.