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

ClassNode#getSuperClass() returns incorrect data if super class has generics

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Not A Problem
    • Affects Version/s: 2.2.2
    • Fix Version/s: None
    • Component/s: ast builder
    • Labels:
      None
    • Environment:
      Mac OSX

      Description

      Consider the following class implementation:

      class Foo<T> {
      }

      class Baz {
      }

      class Boo extends Foo<Baz> {
      int sum(a, b)

      { a + b; }

      }

      if ClassNode for Boo calls getSuperClass() it would return JDT ClassNode via a redirect. The JDT ClassNode would not have any info on the Baz generic type, but rather have only info about the generic template T from the declaration of Foo class.

      This issue has been noticed while fixing Groovy Eclipse JIRA: http://jira.codehaus.org/browse/GRECLIPSE-1693
      Class Foo is resolved, Baz unresolved. This conditions leads to JDT ClassNode redirect which has no info about Baz, but rather has pure definition of the Foo.

      My fix was in org.codehaus.groovy.ast.ClassNode#getSuperClass()
      (Check if any generic types have actual types and if yes, don't perform redirect)

      public ClassNode getSuperClass() {
      if (!lazyInitDone && !isResolved())

      { throw new GroovyBugError("ClassNode#getSuperClass for "+getName()+" called before class resolving"); }

      //GRECLIPSE start
      if (hasInconsistentHierarchy())

      { return ClassHelper.OBJECT_TYPE; }

      //GRECLIPSE end
      ClassNode sn = redirect().getUnresolvedSuperClass();
      if (sn!=null && !hasDefinedGenericTypes(sn)) sn=sn.redirect();
      return sn;
      }

      private static boolean hasDefinedGenericTypes(ClassNode classNode) {
      if (classNode.isUsingGenerics() && classNode.getGenericsTypes() != null) {
      for (GenericsType gen : classNode.getGenericsTypes()) {
      if (gen.getType() != null && gen.getType().getName().charAt(0) != '?' && !gen.isPlaceholder())

      { return true; }

      }
      }
      return false;
      }

        Attachments

          Activity

            People

            • Assignee:
              guillaume Guillaume Sauthier
              Reporter:
              aboyko Alex Boyko
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: