Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-7687

Bug with @CompileStatic and nested closures

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.4.5
    • Fix Version/s: 2.5.6, 3.0.0-beta-1
    • Component/s: Compiler
    • Labels:
      None

      Description

      I've encountered a strange bug in conjunction with closures, delegates and @CompileStatic. The following code works as expected:

      import groovy.transform.CompileStatic
      
      @CompileStatic
      class SimpleTest {
      
          static class Foo {
              List<Bar> bars = Arrays.asList(new Bar())
          }
      
          static class Bar {
              String message
              public String toString() {return message}
          }
      
      
          void execute(Foo foo) {
              interactions(foo, {
                  bars.each ( { bar -> bar.message = "hello world"})
              })
          }
      
          void interactions(Foo foo, @DelegatesTo(Foo) Closure closure) {
              closure.delegate = foo
              closure.resolveStrategy = Closure.DELEGATE_FIRST
              closure()
          }
      
          static void main(String... args) {
              SimpleTest test = new SimpleTest()
              Foo foo = new Foo()
              test.execute(foo)
              println foo.bars
          }
      }
      

      But when the bars member is prefixed with a public modifier the following compilation error is thrown

      Exception in thread "main" java.lang.ClassCastException: SimpleTest$_execute_closure1 cannot be cast to SimpleTest$Foo
      	at SimpleTest$_execute_closure1.doCall(SimpleTest.groovy:18)
      	at SimpleTest$_execute_closure1.call(SimpleTest.groovy)
      	at SimpleTest.interactions(SimpleTest.groovy:25)
      	at SimpleTest.execute(SimpleTest.groovy:17)
      	at SimpleTest.main(SimpleTest.groovy:31)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:497)
      	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
      

      Here the code causing the error:

      import groovy.transform.CompileStatic
      
      @CompileStatic
      class SimpleTest {
      
          static class Foo {
              public List<Bar> bars = Arrays.asList(new Bar())
          }
      
          static class Bar {
              String message
              public String toString() {return message}
          }
      
      
          void execute(Foo foo) {
              interactions(foo, {
                  bars.each ( { bar -> bar.message = "hello world"})
              })
          }
      
          void interactions(Foo foo, @DelegatesTo(Foo) Closure closure) {
              closure.delegate = foo
              closure.resolveStrategy = Closure.DELEGATE_FIRST
              closure()
          }
      
          static void main(String... args) {
              SimpleTest test = new SimpleTest()
              Foo foo = new Foo()
              test.execute(foo)
              println foo.bars
          }
      }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                paulk Paul King
                Reporter:
                m.ewert Marc Ewert
              • Votes:
                1 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: