8172262: packages missing from docs build

Do not return packages without members from Elements.getPackageElement(String), to avoid ambiguities among such packages in multiple modules.

Reviewed-by: jjg
This commit is contained in:
Jan Lahoda 2017-01-17 07:41:04 +01:00
parent f1eb002e95
commit 53792b463e
4 changed files with 71 additions and 14 deletions
langtools
src/jdk.compiler/share/classes/com/sun/tools/javac
test/tools/javac

@ -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 static com.sun.tools.javac.code.TypeTag.CLASS;
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 @@ public class JavacElements implements Elements {
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 @@ public class JavacElements implements Elements {
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 @@ public class JavacElements implements Elements {
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 @@ public class JavacElements implements Elements {
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 @@ public class JavacElements implements Elements {
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;

@ -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.unchecked.plural.additional=\
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

@ -120,6 +120,7 @@ compiler.misc.bad.class.file # class file is malforme
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))

@ -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.Objects;
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 @@ public class AnnotationProcessing extends ModuleTestBase {
"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 @@ public class AnnotationProcessing extends ModuleTestBase {
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;
}