Chris Erickson created GROOVY-8028:
--------------------------------------
Summary: @CompileStatic causes behavioral change in how interfaces
work
Key: GROOVY-8028
URL: https://issues.apache.org/jira/browse/GROOVY-8028
Project: Groovy
Issue Type: Bug
Affects Versions: 2.4.4
Environment: Windows / Grails 2.5.4
Reporter: Chris Erickson
Given an interface:
{code}
interface SomeInterface {
String name
}
{code}
and a class:
{code}
class SomeClass implements SomeInterface {
String name
}
{code}
and a wrapper class, for which we have a statically compiled and non-statically
compiled version:
{code}
class WrapperClass {
SomeInterface delegate
String getName() { delegate.name }
}
@CompileStatic
class StaticCompileWrapperClass {
SomeInterface delegate
String getName() { delegate.name }
}
{code}
The behavior of the two classes is different, with no compiler warnings or
errors, as demonstrated by this script:
{code}
def wrapped = new WrapperClass(delegate: new SomeClass(name: "Name"))
assert wrapped.name == "Name" // ok
assert wrapped.getName() == "Name" // ok
def wrapped2 = new StaticCompileWrapperClass(delegate: new SomeClass(name:
"Name"))
assert wrapped2.name == "Name" // fail
assert wrapped2.getName() == "Name" // fail
{code}
It was pointed out when I reported this to grails (I thought it was a
@GrailsCompileStatic issue but it turns out I had defined it differently in my
interface) that the interface definition is incorrect (I'd assumed you could
define a property on an interface, which would imply the getters/setters) and
that leads to the issue.
However, I think that the functional behavior of a class should not change
based on a @CompileStatic annotation. Minimally, if it does change, there
should be compiler warnings or errors. The fix may be that the compiler should
fail saying that "SomeClass" doesn't implement the interface, or that when it
isn't compiled static it also returns null. I could be convinced either way,
the inconsistency is my complaint.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)