changeset 3887:03f48cd283f5 jdk-9+153

8172262: packages missing from docs build Summary: Do not return packages without members from Elements.getPackageElement(String), to avoid ambiguities among such packages in multiple modules. Reviewed-by: jjg
author jlahoda
date Tue, 17 Jan 2017 07:41:04 +0100
parents 6c729485e202
children b670e95106f5 444b89786af3
files src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/diags/examples.not-yet.txt test/tools/javac/modules/AnnotationProcessing.java
diffstat 4 files changed, 71 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Tue Jan 17 09:17:10 2017 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Tue Jan 17 07:41:04 2017 +0100
@@ -25,9 +25,11 @@
 
 package com.sun.tools.javac.model;
 
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.lang.model.AnnotatedConstruct;
 import javax.lang.model.SourceVersion;
@@ -67,6 +69,7 @@
 import com.sun.tools.javac.comp.Modules;
 import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.comp.Resolve.RecoveryLoadClass;
+import com.sun.tools.javac.resources.CompilerProperties.Notes;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /**
@@ -87,6 +90,8 @@
     private final Enter enter;
     private final Resolve resolve;
     private final JavacTaskImpl javacTaskImpl;
+    private final Log log;
+    private final boolean allowModules;
 
     public static JavacElements instance(Context context) {
         JavacElements instance = context.get(JavacElements.class);
@@ -106,6 +111,9 @@
         resolve = Resolve.instance(context);
         JavacTask t = context.get(JavacTask.class);
         javacTaskImpl = t instanceof JavacTaskImpl ? (JavacTaskImpl) t : null;
+        log = Log.instance(context);
+        Source source = Source.instance(context);
+        allowModules = source.allowModules();
     }
 
     @Override @DefinedBy(Api.LANGUAGE_MODEL)
@@ -134,7 +142,7 @@
         ensureEntered("getPackageElement");
         if (name.length() == 0)
             return syms.unnamedModule.unnamedPackage;
-        return doGetElement(module, name, PackageSymbol.class);
+        return doGetElement(module, "getPackageElement", name, PackageSymbol.class);
     }
 
     @Override @DefinedBy(Api.LANGUAGE_MODEL)
@@ -151,22 +159,27 @@
 
     private ClassSymbol doGetTypeElement(ModuleElement module, CharSequence name) {
         ensureEntered("getTypeElement");
-        return doGetElement(module, name, ClassSymbol.class);
+        return doGetElement(module, "getTypeElement", name, ClassSymbol.class);
     }
 
-    private <S extends Symbol> S doGetElement(ModuleElement module, CharSequence name, Class<S> clazz) {
+    private <S extends Symbol> S doGetElement(ModuleElement module, String methodName,
+                                              CharSequence name, Class<S> clazz) {
         String strName = name.toString();
         if (!SourceVersion.isName(strName)) {
             return null;
         }
         if (module == null) {
-            return unboundNameToSymbol(strName, clazz);
+            return unboundNameToSymbol(methodName, strName, clazz);
         } else {
             return nameToSymbol((ModuleSymbol) module, strName, clazz);
         }
     }
 
-    private <S extends Symbol> S unboundNameToSymbol(String nameStr, Class<S> clazz) {
+    private final Set<String> alreadyWarnedDuplicates = new HashSet<>();
+
+    private <S extends Symbol> S unboundNameToSymbol(String methodName,
+                                                     String nameStr,
+                                                     Class<S> clazz) {
         if (modules.getDefaultModule() == syms.noModule) { //not a modular mode:
             return nameToSymbol(syms.noModule, nameStr, clazz);
         }
@@ -179,12 +192,25 @@
                 S sym = nameToSymbol(msym, nameStr, clazz);
 
                 if (sym != null) {
-                    found.add(sym);
+                    if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
+                        //do not add packages without members:
+                        found.add(sym);
+                    }
                 }
             }
 
             if (found.size() == 1) {
                 return found.iterator().next();
+            } else if (found.size() > 1) {
+                //more than one element found, produce a note:
+                if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
+                    String moduleNames = found.stream()
+                                              .map(s -> s.packge().modle)
+                                              .map(m -> m.toString())
+                                              .collect(Collectors.joining(", "));
+                    log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
+                }
+                return null;
             } else {
                 //not found, or more than one element found:
                 return null;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Jan 17 09:17:10 2017 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Jan 17 07:41:04 2017 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 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
@@ -1436,6 +1436,10 @@
 compiler.note.proc.messager=\
     {0}
 
+# 0: string, 1: string, 2: string
+compiler.note.multiple.elements=\
+    Multiple elements named '{1}' in modules '{2}' were found by javax.lang.model.util.Elements.{0}.
+
 #####
 
 # 0: number
--- a/test/tools/javac/diags/examples.not-yet.txt	Tue Jan 17 09:17:10 2017 +0530
+++ b/test/tools/javac/diags/examples.not-yet.txt	Tue Jan 17 07:41:04 2017 +0100
@@ -120,6 +120,7 @@
 compiler.misc.bad.const.pool.entry                      # constant pool entry has wrong type
 compiler.warn.access.to.member.from.serializable.lambda # in order to generate it we need to modify a restricted package
 compiler.warn.invalid.path                              # this warning is generated only in Windows systems
+compiler.note.multiple.elements                         # needs user code
 
 # The following module-related messages will have to stay on the not-yet list for various reasons:
 compiler.warn.locn.unknown.file.on.module.path                # Never issued ATM (short circuited with an if (false))
--- a/test/tools/javac/modules/AnnotationProcessing.java	Tue Jan 17 09:17:10 2017 +0530
+++ b/test/tools/javac/modules/AnnotationProcessing.java	Tue Jan 17 07:41:04 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8133884 8162711 8133896 8172158
+ * @bug 8133884 8162711 8133896 8172158 8172262
  * @summary Verify that annotation processing works.
  * @library /tools/lib
  * @modules
@@ -50,6 +50,7 @@
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.function.Function;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import javax.annotation.processing.AbstractProcessor;
@@ -1067,24 +1068,43 @@
                           "package impl1; public class Impl { }",
                           "package impl.conflict.module; class Impl { }",
                           "package impl.conflict.clazz; public class pkg { public static class I { } }",
-                          "package impl.conflict.src; public class Impl { }");
+                          "package impl.conflict.src; public class Impl { }",
+                          "package nested.pack.pack; public class Impl { }",
+                          "package unique.nested; public class Impl { }");
 
         tb.writeJavaFiles(m2,
                           "module m2x { }",
                           "package impl2; public class Impl { }",
                           "package impl.conflict.module; class Impl { }",
-                          "package impl.conflict; public class clazz { public static class pkg { } }");
+                          "package impl.conflict; public class clazz { public static class pkg { } }",
+                          "package nested.pack; public class Impl { }");
 
         //from source:
-        new JavacTask(tb)
+        String log = new JavacTask(tb)
             .options("--module-source-path", moduleSrc.toString(),
                      "--source-path", src.toString(),
                      "-processorpath", System.getProperty("test.class.path"),
-                     "-processor", UnboundLookup.class.getName())
+                     "-processor", UnboundLookup.class.getName(),
+                     "-XDrawDiagnostics")
             .outdir(classes)
             .files(findJavaFiles(moduleSrc))
             .run()
-            .writeAll();
+            .writeAll()
+            .getOutput(OutputKind.DIRECT);
+
+        String moduleImplConflictString =
+                "- compiler.note.multiple.elements: getTypeElement, impl.conflict.module.Impl, m2x, m1x";
+        String srcConflictString =
+                "- compiler.note.multiple.elements: getTypeElement, impl.conflict.src.Impl, m1x, unnamed module";
+
+        if (!log.contains(moduleImplConflictString) ||
+            !log.contains(srcConflictString)) {
+            throw new AssertionError("Expected output not found: " + log);
+        }
+
+        if (log.split(Pattern.quote(moduleImplConflictString)).length > 2) {
+            throw new AssertionError("Too many warnings in: " + log);
+        }
 
         new JavacTask(tb)
             .options("--source-path", src.toString())
@@ -1130,11 +1150,17 @@
             assertTypeElementExists("impl.conflict.clazz", "m2x");
             assertPackageElementExists("impl.conflict.clazz", "m1x");
             assertPackageElementExists("impl2", "m2x");
+            assertPackageElementExists("nested.pack.pack", "m1x");
+            assertPackageElementExists("nested.pack", "m2x");
+            assertTypeElementExists("unique.nested.Impl", "m1x");
             assertTypeElementNotFound("impl.conflict.module.Impl");
+            assertTypeElementNotFound("impl.conflict.module.Impl"); //check that the warning/note is produced only once
             assertPackageElementNotFound("impl.conflict.module");
             assertTypeElementNotFound("impl.conflict.src.Impl");
             assertPackageElementNotFound("impl.conflict.src");
             assertTypeElementNotFound("impl.conflict.clazz.pkg");
+            assertPackageElementNotFound("unique"); //do not return packages without members in module mode
+            assertTypeElementNotFound("nested"); //cannot distinguish between m1x and m2x
 
             return false;
         }