Jason Winnebeck created GROOVY-7597:
---
Summary: Static Compiler tries to cast delegate to target type of
property accessor
Key: GROOVY-7597
URL: https://issues.apache.org/jira/browse/GROOVY-7597
Project: Groovy
Issue Type: Bug
Components: Static compilation, Static Type Checker
Affects Versions: 2.4.4, 2.4.3
Reporter: Jason Winnebeck
Assignee: Cédric Champeau
I've been able to finally isolate a static compiler issue with accessing
properties on delegates that occur within our projects:
{code}
class Calculation {
boolean isValid() { true }
}
class Entity {
Calculation getCalculation(String name) { new Calculation() }
}
class Feature extends Entity {
}
void DoWithFeature(@DelegatesTo(Feature) Closure c) {
new Feature().with(c)
}
@groovy.transform.CompileStatic
void doIt() {
DoWithFeature() {
println getCalculation("whatever").valid
}
}
doIt()
{code}
The result is {{java.lang.ClassCastException: Feature cannot be cast to
Calculation}}
Workarounds:
* change the property access into a method access "valid" -> "isValid()"
* Remove CompileStatic annotation
As seen in the following bytecode, the static compiler tries to cast the
delegate to Calculation (which always fails), then tries to call
ScriptBytecodeAdapter.castToType to try to cast the "Calculation" back to an
Entity to properly call getCalculation("").isValid() on it.
{code}
// access flags 0x1
public doCall(Ljava/lang/Object;)Ljava/lang/Object;
L0
LINENUMBER 19 L0
ALOAD 0
CHECKCAST script1442861431462$_doIt_closure1
INVOKEVIRTUAL script1442861431462$_doIt_closure1.getThisObject
()Ljava/lang/Object;
LDC Lgroovy/lang/Script;.class
INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType
(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
CHECKCAST groovy/lang/Script
ALOAD 0
CHECKCAST script1442861431462$_doIt_closure1
INVOKEVIRTUAL script1442861431462$_doIt_closure1.getDelegate
()Ljava/lang/Object;
CHECKCAST Calculation
LDC LEntity;.class
INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType
(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
CHECKCAST Entity
LDC "whatever"
INVOKEVIRTUAL Entity.getCalculation (Ljava/lang/String;)LCalculation;
INVOKEVIRTUAL Calculation.isValid ()Z
INVOKESTATIC java/lang/Boolean.valueOf (Z)Ljava/lang/Boolean;
INVOKEVIRTUAL groovy/lang/Script.println (Ljava/lang/Object;)V
ACONST_NULL
ARETURN
L1
ACONST_NULL
ARETURN
LOCALVARIABLE this Lscript1442861431462$_doIt_closure1; L0 L1 0
LOCALVARIABLE it Ljava/lang/Object; L0 L1 1
MAXSTACK = 3
MAXLOCALS = 2
{code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)