8175335: Improve handling of module types in javax.lang.model.util.Types
authordarcy
Wed, 22 Feb 2017 12:01:15 -0800
changeset 44014 56d15b6333fc
parent 44013 81d8706c9a3e
child 44016 7ceaef603725
8175335: Improve handling of module types in javax.lang.model.util.Types Reviewed-by: jjg, abuckley
langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeMirror.java
langtools/src/java.compiler/share/classes/javax/lang/model/util/Types.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java
langtools/test/tools/javac/processing/model/util/types/TestPseudoTypeHandling.java
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeMirror.java	Tue Feb 21 06:02:37 2017 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeMirror.java	Wed Feb 22 12:01:15 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,9 +34,9 @@
  * Represents a type in the Java programming language.
  * Types include primitive types, declared types (class and interface types),
  * array types, type variables, and the null type.
- * Also represented are wildcard type arguments,
- * the signature and return types of executables,
- * and pseudo-types corresponding to packages and to the keyword {@code void}.
+ * Also represented are wildcard type arguments, the signature and
+ * return types of executables, and pseudo-types corresponding to
+ * packages, modules, and the keyword {@code void}.
  *
  * <p> Types should be compared using the utility methods in {@link
  * Types}.  There is no guarantee that any particular type will always
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Types.java	Tue Feb 21 06:02:37 2017 -0800
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Types.java	Wed Feb 22 12:01:15 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@
      * @param t2  the second type
      * @return {@code true} if and only if the first type is a subtype
      *          of the second
-     * @throws IllegalArgumentException if given an executable or package type
+     * @throws IllegalArgumentException if given a type for an executable, package, or module
      * @jls 4.10 Subtyping
      */
     boolean isSubtype(TypeMirror t1, TypeMirror t2);
@@ -103,7 +103,7 @@
      * @param t2  the second type
      * @return {@code true} if and only if the first type is assignable
      *          to the second
-     * @throws IllegalArgumentException if given an executable or package type
+     * @throws IllegalArgumentException if given a type for an executable, package, or module
      * @jls 5.2 Assignment Conversion
      */
     boolean isAssignable(TypeMirror t1, TypeMirror t2);
@@ -114,7 +114,7 @@
      * @param t1  the first type
      * @param t2  the second type
      * @return {@code true} if and only if the first type contains the second
-     * @throws IllegalArgumentException if given an executable or package type
+     * @throws IllegalArgumentException if given a type for an executable, package, or module
      * @jls 4.5.1.1 Type Argument Containment and Equivalence
      */
     boolean contains(TypeMirror t1, TypeMirror t2);
@@ -139,7 +139,7 @@
      *
      * @param t  the type being examined
      * @return the direct supertypes, or an empty list if none
-     * @throws IllegalArgumentException if given an executable or package type
+     * @throws IllegalArgumentException if given a type for an executable, package, or module
      * @jls 4.10 Subtyping
      */
     List<? extends TypeMirror> directSupertypes(TypeMirror t);
@@ -149,7 +149,7 @@
      *
      * @param t  the type to be erased
      * @return the erasure of the given type
-     * @throws IllegalArgumentException if given a package type
+     * @throws IllegalArgumentException if given a type for a package or module
      * @jls 4.6 Type Erasure
      */
     TypeMirror erasure(TypeMirror t);
@@ -181,7 +181,7 @@
      *
      * @param t  the type to be converted
      * @return the result of applying capture conversion
-     * @throws IllegalArgumentException if given an executable or package type
+     * @throws IllegalArgumentException if given a type for an executable, package, or module
      * @jls 5.1.10 Capture Conversion
      */
     TypeMirror capture(TypeMirror t);
@@ -206,9 +206,14 @@
      * Returns a pseudo-type used where no actual type is appropriate.
      * The kind of type to return may be either
      * {@link TypeKind#VOID VOID} or {@link TypeKind#NONE NONE}.
-     * For packages, use
-     * {@link Elements#getPackageElement(CharSequence)}{@code .asType()}
-     * instead.
+     *
+     * <p>To get the pseudo-type corresponding to a package or module,
+     * call {@code asType()} on the element modeling the {@linkplain
+     * PackageElement package} or {@linkplain ModuleElement
+     * module}. Names can be converted to elements for packages or
+     * modules using {@link Elements#getPackageElement(CharSequence)}
+     * or {@link Elements#getModuleElement(CharSequence)},
+     * respectively.
      *
      * @param kind  the kind of type to return
      * @return a pseudo-type of kind {@code VOID} or {@code NONE}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java	Tue Feb 21 06:02:37 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java	Wed Feb 22 12:01:15 2017 -0800
@@ -93,22 +93,22 @@
 
     @DefinedBy(Api.LANGUAGE_MODEL)
     public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
-        validateTypeNotIn(t1, EXEC_OR_PKG);
-        validateTypeNotIn(t2, EXEC_OR_PKG);
+        validateTypeNotIn(t1, EXEC_OR_PKG_OR_MOD);
+        validateTypeNotIn(t2, EXEC_OR_PKG_OR_MOD);
         return types.isSubtype((Type) t1, (Type) t2);
     }
 
     @DefinedBy(Api.LANGUAGE_MODEL)
     public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
-        validateTypeNotIn(t1, EXEC_OR_PKG);
-        validateTypeNotIn(t2, EXEC_OR_PKG);
+        validateTypeNotIn(t1, EXEC_OR_PKG_OR_MOD);
+        validateTypeNotIn(t2, EXEC_OR_PKG_OR_MOD);
         return types.isAssignable((Type) t1, (Type) t2);
     }
 
     @DefinedBy(Api.LANGUAGE_MODEL)
     public boolean contains(TypeMirror t1, TypeMirror t2) {
-        validateTypeNotIn(t1, EXEC_OR_PKG);
-        validateTypeNotIn(t2, EXEC_OR_PKG);
+        validateTypeNotIn(t1, EXEC_OR_PKG_OR_MOD);
+        validateTypeNotIn(t2, EXEC_OR_PKG_OR_MOD);
         return types.containsType((Type) t1, (Type) t2);
     }
 
@@ -119,7 +119,7 @@
 
     @DefinedBy(Api.LANGUAGE_MODEL)
     public List<Type> directSupertypes(TypeMirror t) {
-        validateTypeNotIn(t, EXEC_OR_PKG);
+        validateTypeNotIn(t, EXEC_OR_PKG_OR_MOD);
         Type ty = (Type)t;
         return types.directSupertypes(ty).stream()
                 .map(Type::stripMetadataIfNeeded)
@@ -128,7 +128,8 @@
 
     @DefinedBy(Api.LANGUAGE_MODEL)
     public TypeMirror erasure(TypeMirror t) {
-        if (t.getKind() == TypeKind.PACKAGE)
+        TypeKind kind = t.getKind();
+        if (kind == TypeKind.PACKAGE || kind == TypeKind.MODULE)
             throw new IllegalArgumentException(t.toString());
         return types.erasure((Type)t).stripMetadataIfNeeded();
     }
@@ -150,7 +151,7 @@
 
     @DefinedBy(Api.LANGUAGE_MODEL)
     public TypeMirror capture(TypeMirror t) {
-        validateTypeNotIn(t, EXEC_OR_PKG);
+        validateTypeNotIn(t, EXEC_OR_PKG_OR_MOD);
         return types.capture((Type)t).stripMetadataIfNeeded();
     }
 
@@ -192,6 +193,7 @@
         case EXECUTABLE:
         case WILDCARD:  // heh!
         case PACKAGE:
+        case MODULE:
             throw new IllegalArgumentException(componentType.toString());
         }
         return new Type.ArrayType((Type) componentType, syms.arrayClass);
@@ -299,8 +301,8 @@
     }
 
 
-    private static final Set<TypeKind> EXEC_OR_PKG =
-            EnumSet.of(TypeKind.EXECUTABLE, TypeKind.PACKAGE);
+    private static final Set<TypeKind> EXEC_OR_PKG_OR_MOD =
+        EnumSet.of(TypeKind.EXECUTABLE, TypeKind.PACKAGE, TypeKind.MODULE);
 
     /**
      * Throws an IllegalArgumentException if a type's kind is one of a set.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/types/TestPseudoTypeHandling.java	Wed Feb 22 12:01:15 2017 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8175335
+ * @summary Test Elements.getPackageOf
+ * @author  Joseph D. Darcy
+ * @library /tools/javac/lib
+ * @modules jdk.compiler
+ * @build   JavacTestingAbstractProcessor TestPseudoTypeHandling
+ * @compile -processor TestPseudoTypeHandling -proc:only TestPseudoTypeHandling.java
+ */
+
+import java.util.*;
+import java.util.function.*;
+import static java.util.Objects.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+/**
+ * Test basic handling of module type.
+ */
+public class TestPseudoTypeHandling extends JavacTestingAbstractProcessor {
+    public boolean process(Set<? extends TypeElement> annotations,
+                           RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver()) {
+            TypeMirror objectType  = requireNonNull(eltUtils.getTypeElement("java.lang.Object")).asType();
+
+            List<TypeMirror> typeMirrorsToTest =
+                List.of(requireNonNull(eltUtils.getModuleElement("java.base")).asType(),
+                        requireNonNull(eltUtils.getPackageElement("java.lang")).asType());
+
+            for (TypeMirror type : typeMirrorsToTest) {
+                expectException(t -> typeUtils.isSubtype(t, objectType), type);
+                expectException(t -> typeUtils.isSubtype(objectType, t), type);
+
+                expectException(t -> typeUtils.isAssignable(t, objectType), type);
+                expectException(t -> typeUtils.isAssignable(objectType, t), type);
+
+                expectException(t -> typeUtils.contains(t, objectType), type);
+                expectException(t -> typeUtils.contains(objectType, t), type);
+
+                expectException(t -> typeUtils.capture(t), type);
+                expectException(t -> typeUtils.erasure(t), type);
+
+                expectException(t -> typeUtils.getArrayType(t), type);
+
+                expectException(t -> typeUtils.directSupertypes(t), type);
+            }
+        }
+        return true;
+    }
+
+    void expectException(Consumer<TypeMirror> argument, TypeMirror type) {
+        try {
+            argument.accept(type);
+            throw new RuntimeException("Should not reach " + type.toString());
+        } catch (IllegalArgumentException e) {
+            ; // Expected
+        }
+    }
+}