8163989: Clarify ModuleElement spec
authordarcy
Mon, 19 Jun 2017 15:06:01 -0700
changeset 45687 07463ccee73b
parent 45686 a423824381ae
child 45688 abb7c4afc7a8
8163989: Clarify ModuleElement spec Reviewed-by: abuckley, jjg
langtools/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java
langtools/src/java.compiler/share/classes/javax/lang/model/element/PackageElement.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
langtools/test/tools/javac/modules/EdgeCases.java
langtools/test/tools/javac/processing/model/element/TestModuleElementNames.java
langtools/test/tools/javac/processing/model/element/TestPackageElement.java
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java	Mon Jun 19 12:25:02 2017 -0700
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java	Mon Jun 19 15:06:01 2017 -0700
@@ -42,8 +42,16 @@
      * Returns the fully qualified name of this module.  For an
      * {@linkplain #isUnnamed() unnamed module}, an empty name is returned.
      *
+     * @apiNote If the module name consists of one identifier, then
+     * this method returns that identifier, which is deemed to be
+     * module's fully qualified name despite not being in qualified
+     * form.  If the module name consists of more than one identifier,
+     * then this method returns the entire name.
+     *
      * @return the fully qualified name of this module, or an
      * empty name if this is an unnamed module
+     *
+     * @jls 6.2 Names and Identifiers
      */
     @Override
     Name getQualifiedName();
@@ -52,8 +60,16 @@
      * Returns the simple name of this module.  For an {@linkplain
      * #isUnnamed() unnamed module}, an empty name is returned.
      *
+     * @apiNote If the module name consists of one identifier, then
+     * this method returns that identifier.  If the module name
+     * consists of more than one identifier, then this method returns
+     * the rightmost such identifier, which is deemed to be the
+     * module's simple name.
+     *
      * @return the simple name of this module or an empty name if
      * this is an unnamed module
+     *
+     * @jls 6.2 Names and Identifiers
      */
     @Override
     Name getSimpleName();
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/PackageElement.java	Mon Jun 19 12:25:02 2017 -0700
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/PackageElement.java	Mon Jun 19 15:06:01 2017 -0700
@@ -44,6 +44,13 @@
      * This is also known as the package's <i>canonical</i> name.
      * For an {@linkplain #isUnnamed() unnamed package}, an empty name is returned.
      *
+     * @apiNote The fully qualified name of a named package that is
+     * not a subpackage of a named package is its simple name. The
+     * fully qualified name of a named package that is a subpackage of
+     * another named package consists of the fully qualified name of
+     * the containing package, followed by "{@code .}", followed by the simple
+     * (member) name of the subpackage.
+     *
      * @return the fully qualified name of this package, or an
      * empty name if this is an unnamed package
      * @jls 6.7 Fully Qualified Names and Canonical Names
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Jun 19 12:25:02 2017 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Jun 19 15:06:01 2017 -0700
@@ -950,6 +950,17 @@
         }
 
         @Override @DefinedBy(Api.LANGUAGE_MODEL)
+        public Name getSimpleName() {
+            Name fullName = getQualifiedName();
+            int lastPeriod = fullName.lastIndexOf((byte)'.');
+            if (lastPeriod == -1) {
+                return fullName;
+            } else {
+                return fullName.subName(lastPeriod + 1, fullName.length());
+            }
+        }
+
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public boolean isOpen() {
             return flags.contains(ModuleFlags.OPEN);
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Jun 19 12:25:02 2017 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Jun 19 15:06:01 2017 -0700
@@ -838,7 +838,7 @@
 
         for(TypeElement a  : annotationsPresent) {
             ModuleElement mod = elementUtils.getModuleOf(a);
-            String moduleSpec = allowModules && mod != null ? mod.getSimpleName() + "/" : "";
+            String moduleSpec = allowModules && mod != null ? mod.getQualifiedName() + "/" : "";
             unmatchedAnnotations.put(moduleSpec + a.getQualifiedName().toString(),
                                      a);
         }
--- a/langtools/test/tools/javac/modules/EdgeCases.java	Mon Jun 19 12:25:02 2017 -0700
+++ b/langtools/test/tools/javac/modules/EdgeCases.java	Mon Jun 19 15:06:01 2017 -0700
@@ -595,12 +595,12 @@
 
                 System.out.println("from directives:");
                 for (RequiresDirective rd : ElementFilter.requiresIn(testE.getDirectives())) {
-                    System.out.println(rd.getDependency().getSimpleName());
+                    System.out.println(rd.getDependency().getQualifiedName());
                 }
 
                 System.out.println("from requires:");
                 for (RequiresDirective rd : ((ModuleSymbol) testE).requires) {
-                    System.out.println(rd.getDependency().getSimpleName());
+                    System.out.println(rd.getDependency().getQualifiedName());
                 }
             }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/element/TestModuleElementNames.java	Mon Jun 19 15:06:01 2017 -0700
@@ -0,0 +1,68 @@
+/*
+ * 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 8163989
+ * @summary Test basic workings of naming methods on ModuleElement
+ * @library /tools/javac/lib
+ * @modules java.compiler
+ *          jdk.compiler
+ * @build   JavacTestingAbstractProcessor TestModuleElementNames
+ * @compile -processor TestModuleElementNames -proc:only TestModuleElementNames.java
+ */
+
+import java.util.Set;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+
+/**
+ * Test basic workings of names of ModuleElement.
+ */
+public class TestModuleElementNames extends JavacTestingAbstractProcessor {
+    public boolean process(Set<? extends TypeElement> annotations,
+                           RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver()) {
+            checkNames(eltUtils.getModuleElement(""),          "",          "",          true);
+            checkNames(eltUtils.getModuleElement("java.base"), "base",      "java.base", false);
+        }
+        return true;
+    }
+
+    private void checkNames(ModuleElement mod, String expectedSimple, String expectedQual, boolean expectedUnnamed) {
+        boolean unnamed = mod.isUnnamed();
+        String simpleName    = mod.getSimpleName().toString();
+        String qualifiedName = mod.getQualifiedName().toString();
+
+        if (unnamed != expectedUnnamed) {
+            throw new RuntimeException("Unnamed mismatch on " + qualifiedName);
+        }
+
+        if (!simpleName.equals(expectedSimple) ||
+            !qualifiedName.equals(expectedQual)) {
+            throw new RuntimeException("Unexpected name,\tqualitifed ``" + qualifiedName +
+                                       "''\tsimmple ``" + simpleName + "''");
+        }
+    }
+}
--- a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java	Mon Jun 19 12:25:02 2017 -0700
+++ b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java	Mon Jun 19 15:06:01 2017 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6449798 6399404 8173776
+ * @bug 6449798 6399404 8173776 8163989
  * @summary Test basic workings of PackageElement
  * @author  Joseph D. Darcy
  * @library /tools/javac/lib
@@ -54,8 +54,7 @@
         if (!roundEnv.processingOver()) {
             PackageElement unnamedPkg = eltUtils.getPackageElement("");
 
-            if (!unnamedPkg.getQualifiedName().contentEquals(""))
-                throw new RuntimeException("The unnamed package is named!");
+            testNames(unnamedPkg, "", "");
 
             // The next line tests an implementation detail upon which
             // some diagnostics depend.
@@ -70,11 +69,23 @@
             if (javaLang.isUnnamed())
                 throw new RuntimeException("Package java.lang is unnamed!");
 
+            testNames(javaLang, "java.lang", "lang");
+
             testEnclosingElement(javaLang);
         }
         return true;
     }
 
+    void testNames(PackageElement pkg, String expectedQualified, String expectedSimple) {
+        String tmp = pkg.getQualifiedName().toString();
+        if (!tmp.equals(expectedQualified))
+            throw new RuntimeException("Unexpected qualifed name ``" + tmp + "''.");
+
+        tmp = pkg.getSimpleName().toString();
+        if (!tmp.equals(expectedSimple))
+            throw new RuntimeException("Unexpected simple name ``" + tmp + "''.");
+    }
+
     void testEnclosingElement(PackageElement javaLang) {
         SourceVersion version = processingEnv.getSourceVersion();
         Element enclosing = javaLang.getEnclosingElement();