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

Compilation order important to CompileStatic


    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Duplicate
    • Affects Version/s: 2.0.0
    • Fix Version/s: 2.0.1
    • Component/s: Static compilation
    • Labels:


      Discovered whilst I was debugging why STS was having a hard time compiling grails.

      Here is a cut down version of the issue:

      class PSI {
        Set<String> pluginNames = []


      import groovy.transform.*;
      class PBS {
        protected def foo(PSI compileInfo) {

      Compile them like this:
      > groovyc PSI.groovy PBS.groovy

      it works fine.

      Compile them like this:
      > groovyc PBS.groovy PSI.groovy

      org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
      PBS.groovy: 6: Access to PSI#pluginNames is forbidden @ line 6, column 5.
      1 error

      The 'forbidden' message is coming out because under the covers the PSI type does not implement GroovyObject at the time the static type checking is done. In the AsmClassGenerator.visitAttributeExpression() method, the code block:

        } else {
          adapter = getField;
          if (isGroovyObject(objectExpression)) adapter = getGroovyObjectField;
          if (usesSuper(expression)) adapter = getFieldOnSuper;

      The isGroovyObject(...) test fails (it is asking about PSI). The wrong adapter is used and then the code in AsmClassGenerator.visitAttributeOrProperty() makes the wrong choice:

       if (adapter == getProperty && !expression.isSpreadSafe() && propName != null) {
         controller.getCallSiteWriter().makeGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());
       } else if (adapter == getGroovyObjectProperty && !expression.isSpreadSafe() && propName != null) {      
         controller.getCallSiteWriter().makeGroovyObjectGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());

      As far as I can tell. The verifier adds GroovyObject but that runs in phase 9 whilst the static type checker is running in phase 7... before the verifier has done its work. So this is kind of behaving only if the relevant type has been all through the process before the question is asked about whether it is a groovyobject.

      Note, I have only been debugging under STS which does have a slightly different compilation sequence to regular groovy but hopefully that debug info from a above is somewhat useful.




            • Assignee:
              melix Cédric Champeau
              aclement Andy Clement
            • Votes:
              0 Vote for this issue
              2 Start watching this issue


              • Created: