Hi all,
I was recently looking in some better code paths for the static compiler
and noticed something we should talk about with regards to extension
methods
Let us assume we have a class A with a method foo(), and class B extends
A, which overrides A.foo. If we then compile
def bar(A x) {
x.foo()
}
since foo is defined on A and inherited to B and B provides a new
implementation x.foo() the compiler will still emit a call to A.foo -
but since this is a invokevirtual and x is an instance of B, B.foo will
be executed in the end. So far so good, just the same as in Java.
Not imagine foo is not defined in A or B. Now image we have a foo(A) and
foo(B) as extension method. The compiler will now emit invokestatic call
to foo(A), because x has the type A. Which means foo(B) will not be
selected even if x is actually an instance of B.
If we consider that correct behavior then I have a small problem.
x as Y
is in the static compiler currently compiled using SBC#castToType, which
may or may not do a call DGM.asType(x,Y). It depends on a few things
that should not matter here atm. What matters is that this call is done
dynamic. Which means if we have a asType method on Object and one on X
and x is a X, then the X-variant is taken, even if the only type
information on x available says x is Object. This simulates a
invokevirtual (more or less). But would we transform "x as Y" to
x.asType(Y)
then the rules I mentioned above apply. And since we see only Object for
X as I stated before, we would select DGM.asType(Object,Class) instead
of a more fitting method for the runtime type.
This gives the following options in my eyes:
[] do nothing and accept the dynamic call in the static compiler as well
as the diverging behavior of extension methods (how does that work with
native image?)
[] leave extension method as they are, but migrate asType if we can,
this is a breaking change
[] try to fix category methods and migrate asType, this is a breaking change
[] have a more static compilation friendly solution for asType, that
preserves functionality, but do not change extension method behavior.
This may also be a breaking change
And it is not only asType, asBoolean is in the same class. If we dig
deeper we may find even more cases. I do not favor a specific solution
for the static compiler.
bye Jochen