[ 
https://issues.apache.org/jira/browse/GROOVY-8028?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15772428#comment-15772428
 ] 

Jochen Theodorou commented on GROOVY-8028:
------------------------------------------

{code:Java}
interface SomeInterface {
    String name
}
{code}
will define an interface with a final static field "name". delegate.name will 
in non-static mode always try to access a getter getName. Since SomeClass 
defines one, its getter is taken for invocation. This is because the runtime 
type is used here. In static compilation the compiler sees in "delegate.name" 
only that delegate is of the type SomeInterface, thus we can only access the 
field. SomeClass compiles, because it defines an instance field "name" and does 
not use the field defined by the interface. Of course that means the wrappers 
read the value for name from different fields. All in all there might be 
arguable behaviour, but I do not see a bug.

> @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)

Reply via email to