8209865: Incorrect 'multiple elements' notes with Elements#getTypeElement and --release
Changing ct.sym to be module-path oriented, rather than class-path oriented. Reviewed-by: jjg
This commit is contained in:
parent
33c9c89bf0
commit
c1033edca8
@ -209,13 +209,15 @@ public class CreateSymbols {
|
|||||||
* {@code ctDescriptionFile}, using the file as a recipe to create the sigfiles.
|
* {@code ctDescriptionFile}, using the file as a recipe to create the sigfiles.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation, CtSymKind ctSymKind) throws IOException {
|
public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation) throws IOException {
|
||||||
LoadDescriptions data = load(ctDescriptionFileExtra != null ? Paths.get(ctDescriptionFileExtra)
|
LoadDescriptions data = load(ctDescriptionFileExtra != null ? Paths.get(ctDescriptionFileExtra)
|
||||||
: null,
|
: null,
|
||||||
Paths.get(ctDescriptionFile), null);
|
Paths.get(ctDescriptionFile), null);
|
||||||
|
|
||||||
splitHeaders(data.classes);
|
splitHeaders(data.classes);
|
||||||
|
|
||||||
|
Map<String, Map<Character, String>> package2Version2Module = new HashMap<>();
|
||||||
|
|
||||||
for (ModuleDescription md : data.modules.values()) {
|
for (ModuleDescription md : data.modules.values()) {
|
||||||
for (ModuleHeaderDescription mhd : md.header) {
|
for (ModuleHeaderDescription mhd : md.header) {
|
||||||
List<String> versionsList =
|
List<String> versionsList =
|
||||||
@ -224,26 +226,41 @@ public class CreateSymbols {
|
|||||||
md,
|
md,
|
||||||
mhd,
|
mhd,
|
||||||
versionsList);
|
versionsList);
|
||||||
|
mhd.exports.stream().forEach(pkg -> {
|
||||||
|
for (char v : mhd.versions.toCharArray()) {
|
||||||
|
package2Version2Module.computeIfAbsent(pkg, dummy -> new HashMap<>()).put(v, md.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ClassDescription classDescription : data.classes) {
|
for (ClassDescription classDescription : data.classes) {
|
||||||
|
Map<Character, String> version2Module = package2Version2Module.getOrDefault(classDescription.packge().replace('.', '/'), Collections.emptyMap());
|
||||||
for (ClassHeaderDescription header : classDescription.header) {
|
for (ClassHeaderDescription header : classDescription.header) {
|
||||||
switch (ctSymKind) {
|
Set<String> jointVersions = new HashSet<>();
|
||||||
case JOINED_VERSIONS:
|
jointVersions.add(header.versions);
|
||||||
Set<String> jointVersions = new HashSet<>();
|
limitJointVersion(jointVersions, classDescription.fields);
|
||||||
jointVersions.add(header.versions);
|
limitJointVersion(jointVersions, classDescription.methods);
|
||||||
limitJointVersion(jointVersions, classDescription.fields);
|
Map<String, StringBuilder> module2Versions = new HashMap<>();
|
||||||
limitJointVersion(jointVersions, classDescription.methods);
|
for (char v : header.versions.toCharArray()) {
|
||||||
writeClassesForVersions(ctSymLocation, classDescription, header, jointVersions);
|
String module = version2Module.get(v);
|
||||||
break;
|
if (module == null) {
|
||||||
case SEPARATE:
|
if (v >= '9') {
|
||||||
Set<String> versions = new HashSet<>();
|
throw new AssertionError("No module for " + classDescription.name +
|
||||||
for (char v : header.versions.toCharArray()) {
|
" and version " + v);
|
||||||
versions.add("" + v);
|
|
||||||
}
|
}
|
||||||
writeClassesForVersions(ctSymLocation, classDescription, header, versions);
|
module = version2Module.get('9');
|
||||||
break;
|
if (module == null) {
|
||||||
|
module = "java.base";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module2Versions.computeIfAbsent(module, dummy -> new StringBuilder()).append(v);
|
||||||
|
}
|
||||||
|
for (Entry<String, StringBuilder> e : module2Versions.entrySet()) {
|
||||||
|
Set<String> currentVersions = new HashSet<>(jointVersions);
|
||||||
|
limitJointVersion(currentVersions, e.getValue().toString());
|
||||||
|
currentVersions = currentVersions.stream().filter(vers -> !disjoint(vers, e.getValue().toString())).collect(Collectors.toSet());
|
||||||
|
writeClassesForVersions(ctSymLocation, classDescription, header, e.getKey(), currentVersions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -591,7 +608,7 @@ public class CreateSymbols {
|
|||||||
newHeader.innerClasses = header.innerClasses;
|
newHeader.innerClasses = header.innerClasses;
|
||||||
newHeader.runtimeAnnotations = header.runtimeAnnotations;
|
newHeader.runtimeAnnotations = header.runtimeAnnotations;
|
||||||
newHeader.signature = header.signature;
|
newHeader.signature = header.signature;
|
||||||
newHeader.versions = reduce(versions, header.versions);
|
newHeader.versions = reduce(header.versions, versions);
|
||||||
|
|
||||||
newHeaders.add(newHeader);
|
newHeaders.add(newHeader);
|
||||||
}
|
}
|
||||||
@ -603,26 +620,30 @@ public class CreateSymbols {
|
|||||||
|
|
||||||
void limitJointVersion(Set<String> jointVersions, List<? extends FeatureDescription> features) {
|
void limitJointVersion(Set<String> jointVersions, List<? extends FeatureDescription> features) {
|
||||||
for (FeatureDescription feature : features) {
|
for (FeatureDescription feature : features) {
|
||||||
for (String version : jointVersions) {
|
limitJointVersion(jointVersions, feature.versions);
|
||||||
if (!containsAll(feature.versions, version) &&
|
}
|
||||||
!disjoint(feature.versions, version)) {
|
}
|
||||||
StringBuilder featurePart = new StringBuilder();
|
|
||||||
StringBuilder otherPart = new StringBuilder();
|
void limitJointVersion(Set<String> jointVersions, String versions) {
|
||||||
for (char v : version.toCharArray()) {
|
for (String version : jointVersions) {
|
||||||
if (feature.versions.indexOf(v) != (-1)) {
|
if (!containsAll(versions, version) &&
|
||||||
featurePart.append(v);
|
!disjoint(versions, version)) {
|
||||||
} else {
|
StringBuilder featurePart = new StringBuilder();
|
||||||
otherPart.append(v);
|
StringBuilder otherPart = new StringBuilder();
|
||||||
}
|
for (char v : version.toCharArray()) {
|
||||||
|
if (versions.indexOf(v) != (-1)) {
|
||||||
|
featurePart.append(v);
|
||||||
|
} else {
|
||||||
|
otherPart.append(v);
|
||||||
}
|
}
|
||||||
jointVersions.remove(version);
|
|
||||||
if (featurePart.length() == 0 || otherPart.length() == 0) {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
jointVersions.add(featurePart.toString());
|
|
||||||
jointVersions.add(otherPart.toString());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
jointVersions.remove(version);
|
||||||
|
if (featurePart.length() == 0 || otherPart.length() == 0) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
jointVersions.add(featurePart.toString());
|
||||||
|
jointVersions.add(otherPart.toString());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -646,10 +667,11 @@ public class CreateSymbols {
|
|||||||
void writeClassesForVersions(String ctSymLocation,
|
void writeClassesForVersions(String ctSymLocation,
|
||||||
ClassDescription classDescription,
|
ClassDescription classDescription,
|
||||||
ClassHeaderDescription header,
|
ClassHeaderDescription header,
|
||||||
|
String module,
|
||||||
Iterable<String> versions)
|
Iterable<String> versions)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
for (String ver : versions) {
|
for (String ver : versions) {
|
||||||
writeClass(ctSymLocation, classDescription, header, ver);
|
writeClass(ctSymLocation, classDescription, header, module, ver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,11 +685,6 @@ public class CreateSymbols {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CtSymKind {
|
|
||||||
JOINED_VERSIONS,
|
|
||||||
SEPARATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="Class Writing">
|
//<editor-fold defaultstate="collapsed" desc="Class Writing">
|
||||||
void writeModule(String ctSymLocation,
|
void writeModule(String ctSymLocation,
|
||||||
ModuleDescription moduleDescription,
|
ModuleDescription moduleDescription,
|
||||||
@ -697,7 +714,7 @@ public class CreateSymbols {
|
|||||||
attributes);
|
attributes);
|
||||||
|
|
||||||
Path outputClassFile = Paths.get(ctSymLocation,
|
Path outputClassFile = Paths.get(ctSymLocation,
|
||||||
version + "-modules",
|
version,
|
||||||
moduleDescription.name,
|
moduleDescription.name,
|
||||||
"module-info" + EXTENSION);
|
"module-info" + EXTENSION);
|
||||||
|
|
||||||
@ -713,6 +730,7 @@ public class CreateSymbols {
|
|||||||
void writeClass(String ctSymLocation,
|
void writeClass(String ctSymLocation,
|
||||||
ClassDescription classDescription,
|
ClassDescription classDescription,
|
||||||
ClassHeaderDescription header,
|
ClassHeaderDescription header,
|
||||||
|
String module,
|
||||||
String version) throws IOException {
|
String version) throws IOException {
|
||||||
List<CPInfo> constantPool = new ArrayList<>();
|
List<CPInfo> constantPool = new ArrayList<>();
|
||||||
constantPool.add(null);
|
constantPool.add(null);
|
||||||
@ -765,7 +783,13 @@ public class CreateSymbols {
|
|||||||
methods.toArray(new Method[0]),
|
methods.toArray(new Method[0]),
|
||||||
attributes);
|
attributes);
|
||||||
|
|
||||||
Path outputClassFile = Paths.get(ctSymLocation, version, classDescription.name + EXTENSION);
|
Path outputClassFile = Paths.get(ctSymLocation, version);
|
||||||
|
|
||||||
|
if (module != null) {
|
||||||
|
outputClassFile = outputClassFile.resolve(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputClassFile = outputClassFile.resolve(classDescription.name + EXTENSION);
|
||||||
|
|
||||||
Files.createDirectories(outputClassFile.getParent());
|
Files.createDirectories(outputClassFile.getParent());
|
||||||
|
|
||||||
@ -3652,8 +3676,7 @@ public class CreateSymbols {
|
|||||||
|
|
||||||
new CreateSymbols().createSymbols(ctDescriptionFileExtra,
|
new CreateSymbols().createSymbols(ctDescriptionFileExtra,
|
||||||
ctDescriptionFile,
|
ctDescriptionFile,
|
||||||
ctSymLocation,
|
ctSymLocation);
|
||||||
CtSymKind.JOINED_VERSIONS);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
@ -61,6 +62,8 @@ import javax.tools.StandardJavaFileManager;
|
|||||||
import javax.tools.StandardLocation;
|
import javax.tools.StandardLocation;
|
||||||
|
|
||||||
import com.sun.source.util.Plugin;
|
import com.sun.source.util.Plugin;
|
||||||
|
import com.sun.tools.javac.code.Source;
|
||||||
|
import com.sun.tools.javac.code.Source.Feature;
|
||||||
import com.sun.tools.javac.file.CacheFSInfo;
|
import com.sun.tools.javac.file.CacheFSInfo;
|
||||||
import com.sun.tools.javac.file.JavacFileManager;
|
import com.sun.tools.javac.file.JavacFileManager;
|
||||||
import com.sun.tools.javac.jvm.Target;
|
import com.sun.tools.javac.jvm.Target;
|
||||||
@ -252,52 +255,64 @@ public class JDKPlatformProvider implements PlatformProvider {
|
|||||||
ctSym2FileSystem.put(file, fs = FileSystems.newFileSystem(file, null));
|
ctSym2FileSystem.put(file, fs = FileSystems.newFileSystem(file, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Path> paths = new ArrayList<>();
|
|
||||||
Path modules = fs.getPath(ctSymVersion + "-modules");
|
|
||||||
Path root = fs.getRootDirectories().iterator().next();
|
Path root = fs.getRootDirectories().iterator().next();
|
||||||
boolean pathsSet = false;
|
boolean hasModules =
|
||||||
|
Feature.MODULES.allowedInSource(Source.lookup(sourceVersion));
|
||||||
|
Path systemModules = root.resolve(ctSymVersion).resolve("system-modules");
|
||||||
Charset utf8 = Charset.forName("UTF-8");
|
Charset utf8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
try (DirectoryStream<Path> dir = Files.newDirectoryStream(root)) {
|
if (!hasModules) {
|
||||||
for (Path section : dir) {
|
List<Path> paths = new ArrayList<>();
|
||||||
if (section.getFileName().toString().contains(ctSymVersion) &&
|
|
||||||
!section.getFileName().toString().contains("-")) {
|
|
||||||
Path systemModules = section.resolve("system-modules");
|
|
||||||
|
|
||||||
if (Files.isRegularFile(systemModules)) {
|
try (DirectoryStream<Path> dir = Files.newDirectoryStream(root)) {
|
||||||
fm.handleOption("--system", Arrays.asList("none").iterator());
|
for (Path section : dir) {
|
||||||
|
if (section.getFileName().toString().contains(ctSymVersion) &&
|
||||||
Path jrtModules =
|
!section.getFileName().toString().contains("-")) {
|
||||||
FileSystems.getFileSystem(URI.create("jrt:/"))
|
try (DirectoryStream<Path> modules = Files.newDirectoryStream(section)) {
|
||||||
.getPath("modules");
|
for (Path module : modules) {
|
||||||
try (Stream<String> lines =
|
paths.add(module);
|
||||||
Files.lines(systemModules, utf8)) {
|
}
|
||||||
lines.map(line -> jrtModules.resolve(line))
|
|
||||||
.filter(mod -> Files.exists(mod))
|
|
||||||
.forEach(mod -> setModule(fm, mod));
|
|
||||||
}
|
}
|
||||||
pathsSet = true;
|
|
||||||
} else {
|
|
||||||
paths.add(section);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (Files.isDirectory(modules)) {
|
fm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, paths);
|
||||||
try (DirectoryStream<Path> dir = Files.newDirectoryStream(modules)) {
|
} else if (Files.isRegularFile(systemModules)) {
|
||||||
fm.handleOption("--system", Arrays.asList("none").iterator());
|
fm.handleOption("--system", Arrays.asList("none").iterator());
|
||||||
|
|
||||||
for (Path module : dir) {
|
Path jrtModules =
|
||||||
fm.setLocationForModule(StandardLocation.SYSTEM_MODULES,
|
FileSystems.getFileSystem(URI.create("jrt:/"))
|
||||||
module.getFileName().toString(),
|
.getPath("modules");
|
||||||
Stream.concat(paths.stream(),
|
try (Stream<String> lines =
|
||||||
Stream.of(module))
|
Files.lines(systemModules, utf8)) {
|
||||||
.collect(Collectors.toList()));
|
lines.map(line -> jrtModules.resolve(line))
|
||||||
|
.filter(mod -> Files.exists(mod))
|
||||||
|
.forEach(mod -> setModule(fm, mod));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Map<String, List<Path>> module2Paths = new HashMap<>();
|
||||||
|
|
||||||
|
try (DirectoryStream<Path> dir = Files.newDirectoryStream(root)) {
|
||||||
|
for (Path section : dir) {
|
||||||
|
if (section.getFileName().toString().contains(ctSymVersion) &&
|
||||||
|
!section.getFileName().toString().contains("-")) {
|
||||||
|
try (DirectoryStream<Path> modules = Files.newDirectoryStream(section)) {
|
||||||
|
for (Path module : modules) {
|
||||||
|
module2Paths.computeIfAbsent(module.getFileName().toString(), dummy -> new ArrayList<>()).add(module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!pathsSet) {
|
|
||||||
fm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, paths);
|
fm.handleOption("--system", Arrays.asList("none").iterator());
|
||||||
|
|
||||||
|
for (Entry<String, List<Path>> e : module2Paths.entrySet()) {
|
||||||
|
fm.setLocationForModule(StandardLocation.SYSTEM_MODULES,
|
||||||
|
e.getKey(),
|
||||||
|
e.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fm;
|
return fm;
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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 8209865
|
||||||
|
* @summary Verify that when reading from ct.sym, classes are only visible from modules from which
|
||||||
|
* they are exported.
|
||||||
|
* @modules jdk.compiler
|
||||||
|
* @build ReleaseModulesAndTypeElement
|
||||||
|
* @compile -processor ReleaseModulesAndTypeElement --release 11 ReleaseModulesAndTypeElement.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.processing.AbstractProcessor;
|
||||||
|
import javax.annotation.processing.RoundEnvironment;
|
||||||
|
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.lang.model.element.ModuleElement;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.lang.model.util.Elements;
|
||||||
|
|
||||||
|
@SupportedAnnotationTypes("*")
|
||||||
|
public class ReleaseModulesAndTypeElement extends AbstractProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> roots, RoundEnvironment roundEnv) {
|
||||||
|
Elements elements = processingEnv.getElementUtils();
|
||||||
|
if (elements.getTypeElement(JX_A_P_GENERATED) == null) {
|
||||||
|
throw new AssertionError("jx.a.p.Generated not found by unqualified search!");
|
||||||
|
}
|
||||||
|
ModuleElement javaBase = elements.getModuleElement("java.base");
|
||||||
|
if (elements.getTypeElement(javaBase, JX_A_P_GENERATED) != null) {
|
||||||
|
throw new AssertionError("jx.a.p.Generated found in java.base!");
|
||||||
|
}
|
||||||
|
ModuleElement javaCompiler = elements.getModuleElement("java.compiler");
|
||||||
|
if (elements.getTypeElement(javaCompiler, JX_A_P_GENERATED) == null) {
|
||||||
|
throw new AssertionError("jx.a.p.Generated not found in java.compiler!");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//where:
|
||||||
|
private static final String JX_A_P_GENERATED = "javax.annotation.processing.Generated";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latestSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user