Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8340694

Erroneous parameterized qualified type representation

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • None
    • tools
    • None

      This is related to https://bugs.openjdk.org/browse/JDK-8338678.

      After the changes for JDK-8338678 it is possible to access type arguments of most erroneous types, but the type arguments are still not available for type arguments on enclosing types of qualified types.

      In the example below, consider the type `B<C, D>.E<F>` where none of the referenced types exist. The ErrorType is `B.E<F>`, where the type arguments on B are not available in the model.

      I wondered if it would make sense to consider modeling B as an ErrorType that is the enclosing type of the type E, and associating type arguments with B. I don't have a motivating use-case for this, it just seemed like a possible extension to the improvements in JDK-8338678.

      ===
      class T extends M<N> {
        A a;
        B<C, D> b;
        B<C, D>.E<F> c;
      }
      ===

      ===
      import static javax.lang.model.util.ElementFilter.fieldsIn;

      import java.util.Set;
      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;
      import javax.lang.model.type.ErrorType;
      import javax.tools.Diagnostic;

      @SupportedAnnotationTypes("*")
      public class MissingParameterizedTypeProcessor extends AbstractProcessor {
        @Override
        public SourceVersion getSupportedSourceVersion() {
          return SourceVersion.latestSupported();
        }

        private boolean first = true;

        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
          if (!first) {
            return false;
          }
          first = false;
          for (Element root : roundEnv.getRootElements()) {
            ErrorType superClass = (ErrorType) ((TypeElement) root).getSuperclass();
            processingEnv
                .getMessager()
                .printMessage(
                    Diagnostic.Kind.ERROR,
                    String.format(
                        "%s supertype: %s, arguments: %s, enclosing: %s",
                        root, superClass, superClass.getTypeArguments(), superClass.getEnclosingType()));
            for (Element field : fieldsIn(root.getEnclosedElements())) {
              ErrorType type = (ErrorType) field.asType();
              processingEnv
                  .getMessager()
                  .printMessage(
                      Diagnostic.Kind.ERROR,
                      String.format(
                          "%s supertype: %s, arguments: %s, enclosing: %s",
                          field, type, type.getTypeArguments(), type.getEnclosingType()));
            }
          }
          return false;
        }
      }
      ===

      JDK 23:

      error: T supertype: M<N>, arguments: N, enclosing: none
      error: a supertype: A, arguments: , enclosing: none
      error: b supertype: <any>, arguments: , enclosing: none
      error: c supertype: <any>, arguments: , enclosing: none

      JDK 24:

      error: T supertype: M<N>, arguments: N, enclosing: none
      error: a supertype: A, arguments: , enclosing: none
      error: b supertype: B<C,D>, arguments: C,D, enclosing: none
      error: c supertype: B.E<F>, arguments: F, enclosing: none

            Unassigned Unassigned
            cushon Liam Miller-Cushon
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: