groovy
  1. groovy
  2. GROOVY-3578

Ordering of files passed to compiler affects whether some (invalid) generics errors get reported

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.6.5, 1.7-beta-2
    • Component/s: Compiler
    • Labels:
      None
    • Environment:
      Windows 7
    • Number of attachments :
      0

      Description

      I have two files:

      — A.groovy

      package p;
      
      public class A<T> {
      }
      

      — B.groovy

      package p;
      
      class B extends A<String> {
      }
      

      Depending on the order in which they are passed to groovyc, I may get an error:

      > groovyc A.groovy B.groovy

      works fine.

      > groovyc B.groovy A.groovy

      org.codehaus.groovy.control.MultipleCompilationErrorsException: startup
      failed, B.groovy: 3: The type String is not a valid substitute for the
      bounded parameter <T>
      @ line 3, column 17.
      class B extends A<String> {
      ^
      1 error

      This happens because the generics checking is done as part of the resolution phase. From CompilationUnit:

      private final SourceUnitOperation resolve = new SourceUnitOperation() {
              public void call(SourceUnit source) throws CompilationFailedException {
                  List classes = source.ast.getClasses();
                  for (Iterator it = classes.iterator(); it.hasNext();) {
                      ClassNode node = (ClassNode) it.next();
      
                      VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
                      scopeVisitor.visitClass(node);
      
                      resolveVisitor.startResolving(node, source);
      
                      GenericsVisitor genericsVisitor = new GenericsVisitor(source);
                      genericsVisitor.visitClass(node);
                  }
      
              }
          };
      

      if the generics check is performed before the types involved (like A) are resolved, you get this problem. The solution is to break that into two phases: resolution and then generics checking (take the last two lines from the resolution phase and move them into a new phase, done after resolution):

          /**
           * Check generics usage
           */
          private final SourceUnitOperation checkGenerics = new SourceUnitOperation() {
              public void call(SourceUnit source) throws CompilationFailedException {
                  List classes = source.ast.getClasses();
                  for (Iterator it = classes.iterator(); it.hasNext();) {
                      ClassNode node = (ClassNode) it.next();
      
                      GenericsVisitor genericsVisitor = new GenericsVisitor(source);
                      genericsVisitor.visitClass(node);
                  }
      
              }
          };
      

      then the order doesn't matter.

        Activity

        Hide
        Peter Niederwieser added a comment -

        formatting

        Show
        Peter Niederwieser added a comment - formatting
        Hide
        blackdrag blackdrag added a comment -

        Because of a different issue we decided to move the GenericsVisitor into the same phase as Verifier, the visitor does only checks anyway (which fits what Verifier does). With that move (that Roshan did, thx) this issue is resolved too

        Show
        blackdrag blackdrag added a comment - Because of a different issue we decided to move the GenericsVisitor into the same phase as Verifier, the visitor does only checks anyway (which fits what Verifier does). With that move (that Roshan did, thx) this issue is resolved too
        Hide
        Roshan Dawrani added a comment -

        The change was done against GROOVY-3762, in case it makes sense to link the issues,

        Show
        Roshan Dawrani added a comment - The change was done against GROOVY-3762 , in case it makes sense to link the issues,

          People

          • Assignee:
            blackdrag blackdrag
            Reporter:
            Andy Clement
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: