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
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Jan 17 09:17:10 2017 +0530
+++ b/langtools/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/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Jan 17 09:17:10 2017 +0530
+++ b/langtools/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/langtools/test/tools/javac/diags/examples.not-yet.txt Tue Jan 17 09:17:10 2017 +0530
+++ b/langtools/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/langtools/test/tools/javac/modules/AnnotationProcessing.java Tue Jan 17 09:17:10 2017 +0530
+++ b/langtools/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;
}