This commit is contained in:
Lana Steuck 2015-06-11 20:19:56 -07:00
commit e012aadd0c
92 changed files with 3104 additions and 2016 deletions

View File

@ -2175,11 +2175,19 @@ public class Attr extends JCTree.Visitor {
if (isDiamond
&& ((tree.constructorType != null && inferenceContext.free(tree.constructorType))
|| (tree.clazz.type != null && inferenceContext.free(tree.clazz.type)))) {
final ResultInfo resultInfoForClassDefinition = this.resultInfo;
inferenceContext.addFreeTypeListener(List.of(tree.constructorType, tree.clazz.type),
instantiatedContext -> {
tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
clazz.type = instantiatedContext.asInstType(clazz.type);
visitAnonymousClassDefinition(tree, clazz, clazz.type, cdef, localEnv, argtypes, typeargtypes, pkind);
ResultInfo prevResult = this.resultInfo;
try {
this.resultInfo = resultInfoForClassDefinition;
visitAnonymousClassDefinition(tree, clazz, clazz.type, cdef,
localEnv, argtypes, typeargtypes, pkind);
} finally {
this.resultInfo = prevResult;
}
});
} else {
if (isDiamond && clazztype.hasTag(CLASS)) {

View File

@ -478,22 +478,6 @@ public class Operators {
}
}
/**
* Class representing bitwise operator helpers that operate on all primitive types (either boxed or unboxed).
* Operator lookup is performed after applying binary numeric promotion of the input types.
*/
class BinaryBitwiseOperator extends BinaryNumericOperator {
BinaryBitwiseOperator(Tag tag) {
super(tag);
}
@Override
public boolean test(Type arg1, Type arg2) {
return unaryPromotion(arg1).isPrimitive() && unaryPromotion(arg2).isPrimitive();
}
}
/**
* Class representing bitwise operator helpers that operate on boolean types (either boxed or unboxed).
* Operator lookup is performed assuming both input types are boolean types.
@ -727,16 +711,19 @@ public class Operators {
.addBinaryOperator(FLOAT, FLOAT, FLOAT, fmod)
.addBinaryOperator(LONG, LONG, LONG, lmod)
.addBinaryOperator(INT, INT, INT, imod),
new BinaryBitwiseOperator(Tag.BITAND)
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, iand)
new BinaryBooleanOperator(Tag.BITAND)
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, iand),
new BinaryNumericOperator(Tag.BITAND)
.addBinaryOperator(LONG, LONG, LONG, land)
.addBinaryOperator(INT, INT, INT, iand),
new BinaryBitwiseOperator(Tag.BITOR)
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ior)
new BinaryBooleanOperator(Tag.BITOR)
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ior),
new BinaryNumericOperator(Tag.BITOR)
.addBinaryOperator(LONG, LONG, LONG, lor)
.addBinaryOperator(INT, INT, INT, ior),
new BinaryBitwiseOperator(Tag.BITXOR)
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ixor)
new BinaryBooleanOperator(Tag.BITXOR)
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ixor),
new BinaryNumericOperator(Tag.BITXOR)
.addBinaryOperator(LONG, LONG, LONG, lxor)
.addBinaryOperator(INT, INT, INT, ixor),
new BinaryShiftOperator(Tag.SL)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -26,12 +26,13 @@
package com.sun.tools.sjavac;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.sjavac.pubapi.PubApi;
/**
* The build state class captures the source code and generated artifacts
@ -77,7 +78,7 @@ public class BuildState {
*/
Module findModuleFromPackageName(String pkg) {
int cp = pkg.indexOf(':');
Assert.check(cp != -1);
Assert.check(cp != -1, "Could not find package name");
String mod = pkg.substring(0, cp);
return lookupModule(mod);
}
@ -154,21 +155,28 @@ public class BuildState {
*/
public void calculateDependents() {
dependents = new HashMap<>();
for (String s : packages.keySet()) {
Package p = packages.get(s);
for (String d : p.dependencies()) {
Set<String> ss = dependents.get(d);
if (ss == null) {
ss = new HashSet<>();
dependents.put(d, ss);
}
// Collect all dependencies of the classes in this package
Set<String> deps = p.typeDependencies() // maps fqName -> set of dependencies
.values()
.stream()
.reduce(Collections.emptySet(), Util::union);
// Now reverse the direction
for (String dep : deps) {
// Add the dependent information to the global dependent map.
ss.add(s);
Package dp = packages.get(d);
String depPkgStr = ":" + dep.substring(0, dep.lastIndexOf('.'));
dependents.merge(depPkgStr, Collections.singleton(s), Util::union);
// Also add the dependent information to the package specific map.
// Normally, you do not compile java.lang et al. Therefore
// there are several packages that p depends upon that you
// do not have in your state database. This is perfectly fine.
Package dp = packages.get(depPkgStr);
if (dp != null) {
// But this package did exist in the state database.
dp.addDependent(p.name());
@ -270,11 +278,21 @@ public class BuildState {
public void copyPackagesExcept(BuildState prev, Set<String> recompiled, Set<String> removed) {
for (String pkg : prev.packages().keySet()) {
// Do not copy recompiled or removed packages.
if (recompiled.contains(pkg) || removed.contains(pkg)) continue;
if (recompiled.contains(pkg) || removed.contains(pkg))
continue;
Module mnew = findModuleFromPackageName(pkg);
Package pprev = prev.packages().get(pkg);
// Even though we haven't recompiled this package, we may have
// information about its public API: It may be a classpath dependency
if (packages.containsKey(pkg)) {
pprev.setPubapi(PubApi.mergeTypes(pprev.getPubApi(),
packages.get(pkg).getPubApi()));
}
mnew.addPackage(pprev);
// Do not forget to update the flattened data.
// Do not forget to update the flattened data. (See JDK-8071904)
packages.put(pkg, pprev);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, 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
@ -25,17 +25,25 @@
package com.sun.tools.sjavac;
import java.io.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/**
@ -63,8 +71,10 @@ public class CleanProperties implements Transformer {
Map<String,Set<String>> oldPackageDependencies,
URI destRoot,
Map<String,Set<URI>> packageArtifacts,
Map<String,Set<String>> packageDependencies,
Map<String,String> packagePublicApis,
Map<String, Map<String, Set<String>>> packageDependencies,
Map<String, Map<String, Set<String>>> packageCpDependencies,
Map<String, PubApi> packagePublicApis,
Map<String, PubApi> dependencyPublicApis,
int debugLevel,
boolean incremental,
int numCores,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -30,10 +30,12 @@ import java.io.PrintStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.Sjavac;
import com.sun.tools.sjavac.server.SysInfo;
@ -73,21 +75,25 @@ public class CompileJavaPackages implements Transformer {
Map<String,Set<String>> oldPackageDependents,
URI destRoot,
final Map<String,Set<URI>> packageArtifacts,
final Map<String,Set<String>> packageDependencies,
final Map<String,String> packagePubapis,
final Map<String,Map<String, Set<String>>> packageDependencies,
final Map<String,Map<String, Set<String>>> packageCpDependencies,
final Map<String, PubApi> packagePubapis,
final Map<String, PubApi> dependencyPubapis,
int debugLevel,
boolean incremental,
int numCores,
final PrintStream out,
final PrintStream err)
{
final PrintStream err) {
Log.debug("Performing CompileJavaPackages transform...");
boolean rc = true;
boolean concurrentCompiles = true;
// Fetch the id.
final String id = Util.extractStringOption("id", sjavac.serverSettings());
// Only keep portfile and sjavac settings..
String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings());
//String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings());
// Get maximum heap size from the server!
SysInfo sysinfo = sjavac.getSysInfo();
@ -210,20 +216,44 @@ public class CompileJavaPackages implements Transformer {
final CompileChunk cc = compileChunks[i];
// Pass the num_cores and the id (appended with the chunk number) to the server.
final String cleanedServerSettings = psServerSettings+",poolsize="+numCores+",id="+id+"-"+i;
Object lock = new Object();
requests[i] = new Thread() {
@Override
public void run() {
rn[ii] = sjavac.compile("n/a",
id + "-" + ii,
args.prepJavacArgs(),
Collections.<File>emptyList(),
cc.srcs,
visibleSources);
packageArtifacts.putAll(rn[ii].packageArtifacts);
packageDependencies.putAll(rn[ii].packageDependencies);
packagePubapis.putAll(rn[ii].packagePubapis);
id + "-" + ii,
args.prepJavacArgs(),
Collections.<File>emptyList(),
cc.srcs,
visibleSources);
// In the code below we have to keep in mind that two
// different compilation results may include results for
// the same package.
synchronized (lock) {
for (String pkg : rn[ii].packageArtifacts.keySet()) {
Set<URI> pkgArtifacts = rn[ii].packageArtifacts.get(pkg);
packageArtifacts.merge(pkg, pkgArtifacts, Util::union);
}
for (String pkg : rn[ii].packageDependencies.keySet()) {
packageDependencies.putIfAbsent(pkg, new HashMap<>());
packageDependencies.get(pkg).putAll(rn[ii].packageDependencies.get(pkg));
}
for (String pkg : rn[ii].packageCpDependencies.keySet()) {
packageCpDependencies.putIfAbsent(pkg, new HashMap<>());
packageCpDependencies.get(pkg).putAll(rn[ii].packageCpDependencies.get(pkg));
}
for (String pkg : rn[ii].packagePubapis.keySet()) {
packagePubapis.merge(pkg, rn[ii].packagePubapis.get(pkg), PubApi::mergeTypes);
}
for (String pkg : rn[ii].dependencyPubapis.keySet()) {
dependencyPubapis.merge(pkg, rn[ii].dependencyPubapis.get(pkg), PubApi::mergeTypes);
}
}
}
};
@ -278,7 +308,6 @@ public class CompileJavaPackages implements Transformer {
return rc;
}
/**
* Split up the sources into compile chunks. If old package dependents information
* is available, sort the order of the chunks into the most dependent first!
@ -294,9 +323,9 @@ public class CompileJavaPackages implements Transformer {
* @return
*/
CompileChunk[] createCompileChunks(Map<String,Set<URI>> pkgSrcs,
Map<String,Set<String>> oldPackageDependents,
int numCompiles,
int sourcesPerCompile) {
Map<String,Set<String>> oldPackageDependents,
int numCompiles,
int sourcesPerCompile) {
CompileChunk[] compileChunks = new CompileChunk[numCompiles];
for (int i=0; i<compileChunks.length; ++i) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -25,19 +25,27 @@
package com.sun.tools.sjavac;
import java.io.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.net.URI;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/**
@ -70,8 +78,10 @@ public class CompileProperties implements Transformer {
Map<String,Set<String>> oldPackageDependents,
URI destRoot,
Map<String,Set<URI>> packageArtifacts,
Map<String,Set<String>> packageDependencies,
Map<String,String> packagePublicApis,
Map<String,Map<String, Set<String>>> packageDependencies,
Map<String,Map<String, Set<String>>> packageCpDependencies,
Map<String, PubApi> packagePublicApis,
Map<String, PubApi> dependencyPublicApis,
int debugLevel,
boolean incremental,
int numCores,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -25,13 +25,20 @@
package com.sun.tools.sjavac;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URI;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/**
@ -58,8 +65,10 @@ public class CopyFile implements Transformer {
Map<String,Set<String>> oldPackageDependents,
URI destRoot,
Map<String,Set<URI>> packageArtifacts,
Map<String,Set<String>> packageDependencies,
Map<String,String> packagePubapis,
Map<String,Map<String, Set<String>>> packageDependencies,
Map<String,Map<String, Set<String>>> packageCpDependencies,
Map<String, PubApi> packagePubapis,
Map<String, PubApi> dependencyPubapis,
int debugLevel,
boolean incremental,
int numCores,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -25,11 +25,17 @@
package com.sun.tools.sjavac;
import java.io.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.nio.file.NoSuchFileException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
@ -37,8 +43,10 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/**
@ -268,24 +276,25 @@ public class JavacState {
* Save the javac_state file.
*/
public void save() throws IOException {
if (!needsSaving) return;
if (!needsSaving)
return;
try (FileWriter out = new FileWriter(javacState)) {
StringBuilder b = new StringBuilder();
long millisNow = System.currentTimeMillis();
Date d = new Date(millisNow);
SimpleDateFormat df =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
b.append("# javac_state ver 0.3 generated "+millisNow+" "+df.format(d)+"\n");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
b.append("# javac_state ver 0.4 generated "+millisNow+" "+df.format(d)+"\n");
b.append("# This format might change at any time. Please do not depend on it.\n");
b.append("# R arguments\n");
b.append("# M module\n");
b.append("# P package\n");
b.append("# S C source_tobe_compiled timestamp\n");
b.append("# S L link_only_source timestamp\n");
b.append("# G C generated_source timestamp\n");
b.append("# A artifact timestamp\n");
b.append("# D dependency\n");
b.append("# D S dependant -> source dependency\n");
b.append("# D C dependant -> classpath dependency\n");
b.append("# I pubapi\n");
b.append("# R arguments\n");
b.append("R ").append(theArgs).append("\n");
// Copy over the javac_state for the packages that did not need recompilation.
@ -312,6 +321,8 @@ public class JavacState {
boolean newCommandLine = false;
boolean syntaxError = false;
Log.debug("Loading javac state file: " + db.javacState);
try (BufferedReader in = new BufferedReader(new FileReader(db.javacState))) {
for (;;) {
String l = in.readLine();
@ -327,11 +338,14 @@ public class JavacState {
} else
if (c == 'D') {
if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
lastPackage.loadDependency(l);
char depType = l.charAt(2);
if (depType != 'S' && depType != 'C')
throw new RuntimeException("Bad dependency string: " + l);
lastPackage.parseAndAddDependency(l.substring(4), depType == 'C');
} else
if (c == 'I') {
if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
lastPackage.loadPubapi(l);
lastPackage.getPubApi().appendItem(l.substring(2)); // Strip "I "
} else
if (c == 'A') {
if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
@ -356,7 +370,7 @@ public class JavacState {
int sp = l.indexOf(" ", 18);
if (sp != -1) {
String ver = l.substring(18,sp);
if (!ver.equals("0.3")) {
if (!ver.equals("0.4")) {
break;
}
foundCorrectVerNr = true;
@ -488,11 +502,92 @@ public class JavacState {
* Propagate recompilation through the dependency chains.
* Avoid re-tainting packages that have already been compiled.
*/
public void taintPackagesDependingOnChangedPackages(Set<String> pkgs, Set<String> recentlyCompiled) {
public void taintPackagesDependingOnChangedPackages(Set<String> pkgsWithChangedPubApi, Set<String> recentlyCompiled) {
// For each to-be-recompiled-candidates...
for (Package pkg : new HashSet<>(prev.packages().values())) {
// Find out what it depends upon...
Set<String> deps = pkg.typeDependencies()
.values()
.stream()
.flatMap(s -> s.stream())
.collect(Collectors.toSet());
for (String dep : deps) {
String depPkg = ":" + dep.substring(0, dep.lastIndexOf('.'));
if (depPkg.equals(pkg.name()))
continue;
// Checking if that dependency has changed
if (pkgsWithChangedPubApi.contains(depPkg) && !recentlyCompiled.contains(pkg.name())) {
taintPackage(pkg.name(), "its depending on " + depPkg);
}
}
}
}
/**
* Compare the javac_state recorded public apis of packages on the classpath
* with the actual public apis on the classpath.
*/
public void taintPackagesDependingOnChangedClasspathPackages() {
// 1. Collect fully qualified names of all interesting classpath dependencies
Set<String> fqDependencies = new HashSet<>();
for (Package pkg : prev.packages().values()) {
for (String dep : pkg.dependencies()) {
if (pkgs.contains(dep) && !recentlyCompiled.contains(pkg.name())) {
taintPackage(pkg.name(), " its depending on "+dep);
// Check if this package was compiled. If it's presence is recorded
// because it was on the class path and we needed to save it's
// public api, it's not a candidate for tainting.
if (pkg.sources().isEmpty())
continue;
pkg.typeClasspathDependencies().values().forEach(fqDependencies::addAll);
}
// 2. Extract the public APIs from the on disk .class files
// (Reason for doing step 1 in a separate phase is to avoid extracting
// public APIs of the same class twice.)
PubApiExtractor pubApiExtractor = new PubApiExtractor(options);
Map<String, PubApi> onDiskPubApi = new HashMap<>();
for (String cpDep : fqDependencies) {
onDiskPubApi.put(cpDep, pubApiExtractor.getPubApi(cpDep));
}
// 3. Compare them with the public APIs as of last compilation (loaded from javac_state)
nextPkg:
for (Package pkg : prev.packages().values()) {
// Check if this package was compiled. If it's presence is recorded
// because it was on the class path and we needed to save it's
// public api, it's not a candidate for tainting.
if (pkg.sources().isEmpty())
continue;
Set<String> cpDepsOfThisPkg = new HashSet<>();
for (Set<String> cpDeps : pkg.typeClasspathDependencies().values())
cpDepsOfThisPkg.addAll(cpDeps);
for (String fqDep : cpDepsOfThisPkg) {
String depPkg = ":" + fqDep.substring(0, fqDep.lastIndexOf('.'));
PubApi prevPkgApi = prev.packages().get(depPkg).getPubApi();
// This PubApi directly lists the members of the class,
// i.e. [ MEMBER1, MEMBER2, ... ]
PubApi prevDepApi = prevPkgApi.types.get(fqDep).pubApi;
// In order to dive *into* the class, we need to add
// .types.get(fqDep).pubApi below.
PubApi currentDepApi = onDiskPubApi.get(fqDep).types.get(fqDep).pubApi;
if (!currentDepApi.isBackwardCompatibleWith(prevDepApi)) {
List<String> apiDiff = currentDepApi.diff(prevDepApi);
taintPackage(pkg.name(), "depends on classpath "
+ "package which has an updated package api: "
+ String.join("\n", apiDiff));
//Log.debug("========================================");
//Log.debug("------ PREV API ------------------------");
//prevDepApi.asListOfStrings().forEach(Log::debug);
//Log.debug("------ CURRENT API ---------------------");
//currentDepApi.asListOfStrings().forEach(Log::debug);
//Log.debug("========================================");
continue nextPkg;
}
}
}
@ -660,7 +755,6 @@ public class JavacState {
Map<String,Transformer> suffixRules = new HashMap<>();
suffixRules.put(".java", compileJavaPackages);
compileJavaPackages.setExtra(args);
rcValue[0] = perform(sjavac, binDir, suffixRules);
recentlyCompiled.addAll(taintedPackages());
clearTaintedPackages();
@ -668,6 +762,11 @@ public class JavacState {
taintPackagesDependingOnChangedPackages(packagesWithChangedPublicApis, recentlyCompiled);
packagesWithChangedPublicApis = new HashSet<>();
return again && rcValue[0];
// TODO: Figure out why 'again' checks packagesWithChangedPublicAPis.
// (It shouldn't matter if packages had changed pub apis as long as no
// one depends on them. Wouldn't it make more sense to let 'again'
// depend on taintedPackages?)
}
/**
@ -699,68 +798,101 @@ public class JavacState {
Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<>();
for (Source src : now.sources().values()) {
Transformer t = suffixRules.get(src.suffix());
if (t != null) {
if (t != null) {
if (taintedPackages.contains(src.pkg().name()) && !src.isLinkedOnly()) {
addFileToTransform(groupedSources, t, src);
}
}
}
// Go through the transforms and transform them.
for (Map.Entry<Transformer,Map<String,Set<URI>>> e : groupedSources.entrySet()) {
for (Map.Entry<Transformer, Map<String, Set<URI>>> e : groupedSources.entrySet()) {
Transformer t = e.getKey();
Map<String,Set<URI>> srcs = e.getValue();
// These maps need to be synchronized since multiple threads will be writing results into them.
Map<String,Set<URI>> packageArtifacts =
Collections.synchronizedMap(new HashMap<String,Set<URI>>());
Map<String,Set<String>> packageDependencies =
Collections.synchronizedMap(new HashMap<String,Set<String>>());
Map<String,String> packagePublicApis =
Collections.synchronizedMap(new HashMap<String, String>());
Map<String, Set<URI>> srcs = e.getValue();
// These maps need to be synchronized since multiple threads will be
// writing results into them.
Map<String, Set<URI>> packageArtifacts = Collections.synchronizedMap(new HashMap<>());
Map<String, Map<String, Set<String>>> packageDependencies = Collections.synchronizedMap(new HashMap<>());
Map<String, Map<String, Set<String>>> packageCpDependencies = Collections.synchronizedMap(new HashMap<>());
Map<String, PubApi> packagePublicApis = Collections.synchronizedMap(new HashMap<>());
Map<String, PubApi> dependencyPublicApis = Collections.synchronizedMap(new HashMap<>());
boolean r = t.transform(sjavac,
srcs,
visibleSrcs,
visibleClasses,
prev.dependents(),
outputDir.toURI(),
packageArtifacts,
packageDependencies,
packagePublicApis,
0,
isIncremental(),
numCores,
out,
err);
if (!r) rc = false;
boolean r = t.transform(sjavac,
srcs,
visibleSrcs,
visibleClasses,
prev.dependents(),
outputDir.toURI(),
packageArtifacts,
packageDependencies,
packageCpDependencies,
packagePublicApis,
dependencyPublicApis,
0,
isIncremental(),
numCores,
out,
err);
if (!r)
rc = false;
for (String p : srcs.keySet()) {
recompiledPackages.add(p);
}
// The transform is done! Extract all the artifacts and store the info into the Package objects.
for (Map.Entry<String,Set<URI>> a : packageArtifacts.entrySet()) {
for (Map.Entry<String, Set<URI>> a : packageArtifacts.entrySet()) {
Module mnow = now.findModuleFromPackageName(a.getKey());
mnow.addArtifacts(a.getKey(), a.getValue());
}
// Extract all the dependencies and store the info into the Package objects.
for (Map.Entry<String,Set<String>> a : packageDependencies.entrySet()) {
Set<String> deps = a.getValue();
for (Map.Entry<String, Map<String, Set<String>>> a : packageDependencies.entrySet()) {
Map<String, Set<String>> deps = a.getValue();
Module mnow = now.findModuleFromPackageName(a.getKey());
mnow.setDependencies(a.getKey(), deps);
mnow.setDependencies(a.getKey(), deps, false);
}
// Extract all the pubapis and store the info into the Package objects.
for (Map.Entry<String,String> a : packagePublicApis.entrySet()) {
Module mprev = prev.findModuleFromPackageName(a.getKey());
List<String> pubapi = Package.pubapiToList(a.getValue());
for (Map.Entry<String, Map<String, Set<String>>> a : packageCpDependencies.entrySet()) {
Map<String, Set<String>> deps = a.getValue();
Module mnow = now.findModuleFromPackageName(a.getKey());
mnow.setPubapi(a.getKey(), pubapi);
if (mprev.hasPubapiChanged(a.getKey(), pubapi)) {
mnow.setDependencies(a.getKey(), deps, true);
}
// This map contains the public api of the types that this
// compilation depended upon. This means that it may not contain
// full packages. In other words, we shouldn't remove knowledge of
// public apis but merge these with what we already have.
for (Map.Entry<String, PubApi> a : dependencyPublicApis.entrySet()) {
String pkg = a.getKey();
PubApi packagePartialPubApi = a.getValue();
Package pkgNow = now.findModuleFromPackageName(pkg).lookupPackage(pkg);
PubApi currentPubApi = pkgNow.getPubApi();
PubApi newPubApi = PubApi.mergeTypes(currentPubApi, packagePartialPubApi);
pkgNow.setPubapi(newPubApi);
// See JDK-8071904
if (now.packages().containsKey(pkg))
now.packages().get(pkg).setPubapi(newPubApi);
else
now.packages().put(pkg, pkgNow);
}
// The packagePublicApis cover entire packages (since sjavac compiles
// stuff on package level). This means that if a type is missing
// in the public api of a given package, it means that it has been
// removed. In other words, we should *set* the pubapi to whatever
// this map contains, and not merge it with what we already have.
for (Map.Entry<String, PubApi> a : packagePublicApis.entrySet()) {
String pkg = a.getKey();
PubApi newPubApi = a.getValue();
Module mprev = prev.findModuleFromPackageName(pkg);
Module mnow = now.findModuleFromPackageName(pkg);
mnow.setPubapi(pkg, newPubApi);
if (mprev.hasPubapiChanged(pkg, newPubApi)) {
// Aha! The pubapi of this package has changed!
// It can also be a new compile from scratch.
if (mprev.lookupPackage(a.getKey()).existsInJavacState()) {
if (mprev.lookupPackage(pkg).existsInJavacState()) {
// This is an incremental compile! The pubapi
// did change. Trigger recompilation of dependents.
packagesWithChangedPublicApis.add(a.getKey());
Log.info("The pubapi of "+Util.justPackageName(a.getKey())+" has changed!");
packagesWithChangedPublicApis.add(pkg);
Log.info("The API of " + Util.justPackageName(pkg) + " has changed!");
}
}
}
@ -791,17 +923,21 @@ public class JavacState {
}
/**
* Compare the calculate source list, with an explicit list, usually supplied from the makefile.
* Used to detect bugs where the makefile and sjavac have different opinions on which files
* should be compiled.
* Compare the calculate source list, with an explicit list, usually
* supplied from the makefile. Used to detect bugs where the makefile and
* sjavac have different opinions on which files should be compiled.
*/
public void compareWithMakefileList(File makefileSourceList) throws ProblemException {
// If we are building on win32 using for example cygwin the paths in the makefile source list
public void compareWithMakefileList(File makefileSourceList)
throws ProblemException {
// If we are building on win32 using for example cygwin the paths in the
// makefile source list
// might be /cygdrive/c/.... which does not match c:\....
// We need to adjust our calculated sources to be identical, if necessary.
// We need to adjust our calculated sources to be identical, if
// necessary.
boolean mightNeedRewriting = File.pathSeparatorChar == ';';
if (makefileSourceList == null) return;
if (makefileSourceList == null)
return;
Set<String> calculatedSources = new HashSet<>();
Set<String> listedSources = new HashSet<>();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -28,10 +28,11 @@ package com.sun.tools.sjavac;
import java.io.File;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.pubapi.PubApi;
/**
* The module is the root of a set of packages/sources/artifacts.
* At the moment there is only one module in use, the empty/no-name/default module.
@ -86,8 +87,7 @@ public class Module implements Comparable<Module> {
return new Module(name, "");
}
public static void saveModules(Map<String,Module> ms, StringBuilder b)
{
public static void saveModules(Map<String,Module> ms, StringBuilder b) {
for (Module m : ms.values()) {
m.save(b);
}
@ -98,6 +98,7 @@ public class Module implements Comparable<Module> {
}
public Package lookupPackage(String pkg) {
// See JDK-8071904
Package p = packages.get(pkg);
if (p == null) {
p = new Package(this, pkg);
@ -124,18 +125,17 @@ public class Module implements Comparable<Module> {
}
}
public void setDependencies(String pkg, Set<String> deps) {
Package p = lookupPackage(pkg);
p.setDependencies(deps);
public void setDependencies(String pkg, Map<String, Set<String>> deps, boolean cp) {
lookupPackage(pkg).setDependencies(deps, cp);
}
public void setPubapi(String pkg, List<String> ps) {
public void setPubapi(String pkg, PubApi ps) {
Package p = lookupPackage(pkg);
p.setPubapi(ps);
}
public boolean hasPubapiChanged(String pkg, List<String> ps) {
public boolean hasPubapiChanged(String pkg, PubApi newPubApi) {
Package p = lookupPackage(pkg);
return p.hasPubapiChanged(ps);
return p.hasPubApiChanged(newPubApi);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -31,11 +31,16 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.sjavac.pubapi.PubApi;
/**
* The Package class maintains meta information about a package.
@ -71,12 +76,16 @@ public class Package implements Comparable<Package> {
// The directory path to the package. If the package belongs to a module,
// then that module's file system name is part of the path.
private String dirname;
// This package depends on these packages.
private Set<String> dependencies = new HashSet<>();
// This package has the following dependents, that depend on this package.
private Set<String> dependents = new HashSet<>();
// Fully qualified name of class in this package -> fully qualified name of dependency
private Map<String, Set<String>> dependencies = new TreeMap<>();
// Fully qualified name of class in this package -> fully qualified name of dependency on class path
private Map<String, Set<String>> cpDependencies = new TreeMap<>();
// This is the public api of this package.
private List<String> pubapi = new ArrayList<>();
private PubApi pubApi = new PubApi();
// Map from source file name to Source info object.
private Map<String,Source> sources = new HashMap<>();
// This package generated these artifacts.
@ -85,7 +94,6 @@ public class Package implements Comparable<Package> {
public Package(Module m, String n) {
int c = n.indexOf(":");
Assert.check(c != -1);
String mn = n.substring(0,c);
Assert.check(m.name().equals(m.name()));
name = n;
dirname = n.replace('.', File.separatorChar);
@ -100,9 +108,11 @@ public class Package implements Comparable<Package> {
public String dirname() { return dirname; }
public Map<String,Source> sources() { return sources; }
public Map<String,File> artifacts() { return artifacts; }
public List<String> pubapi() { return pubapi; }
public PubApi getPubApi() { return pubApi; }
public Map<String,Set<String>> typeDependencies() { return dependencies; }
public Map<String,Set<String>> typeClasspathDependencies() { return cpDependencies; }
public Set<String> dependencies() { return dependencies; }
public Set<String> dependents() { return dependents; }
@Override
@ -124,70 +134,48 @@ public class Package implements Comparable<Package> {
sources.put(s.file().getPath(), s);
}
public void addDependency(String d) {
dependencies.add(d);
private static Pattern DEP_PATTERN = Pattern.compile("(.*) -> (.*)");
public void parseAndAddDependency(String d, boolean cp) {
Matcher m = DEP_PATTERN.matcher(d);
if (!m.matches())
throw new IllegalArgumentException("Bad dependency string: " + d);
addDependency(m.group(1), m.group(2), cp);
}
public void addDependency(String fullyQualifiedFrom,
String fullyQualifiedTo,
boolean cp) {
Map<String, Set<String>> map = cp ? cpDependencies : dependencies;
if (!map.containsKey(fullyQualifiedFrom))
map.put(fullyQualifiedFrom, new HashSet<>());
map.get(fullyQualifiedFrom).add(fullyQualifiedTo);
}
public void addDependent(String d) {
dependents.add(d);
}
public void addPubapi(String p) {
pubapi.add(p);
}
/**
* Check if we have knowledge in the javac state that
* describe the results of compiling this package before.
*/
public boolean existsInJavacState() {
return artifacts.size() > 0 || pubapi.size() > 0;
return artifacts.size() > 0 || !pubApi.isEmpty();
}
public static List<String> pubapiToList(String ps)
{
String[] lines = ps.split("\n");
List<String> r = new ArrayList<>();
for (String l : lines) {
r.add(l);
}
return r;
public boolean hasPubApiChanged(PubApi newPubApi) {
return !newPubApi.isBackwardCompatibleWith(pubApi);
}
public boolean hasPubapiChanged(List<String> ps) {
Iterator<String> i = ps.iterator();
Iterator<String> j = pubapi.iterator();
int line = 0;
while (i.hasNext() && j.hasNext()) {
String is = i.next();
String js = j.next();
if (!is.equals(js)) {
Log.debug("Change in pubapi for package "+name+" line "+line);
Log.debug("Old: "+js);
Log.debug("New: "+is);
return true;
}
line++;
}
if ((i.hasNext() && !j.hasNext() ) ||
(!i.hasNext() && j.hasNext())) {
Log.debug("Change in pubapi for package "+name);
if (i.hasNext()) {
Log.debug("New has more lines!");
} else {
Log.debug("Old has more lines!");
}
return true;
}
return false;
public void setPubapi(PubApi newPubApi) {
pubApi = newPubApi;
}
public void setPubapi(List<String> ps) {
pubapi = ps;
}
public void setDependencies(Set<String> ds) {
dependencies = ds;
public void setDependencies(Map<String, Set<String>> ds, boolean cp) {
(cp ? cpDependencies : dependencies).clear();
for (String fullyQualifiedFrom : ds.keySet())
for (String fullyQualifiedTo : ds.get(fullyQualifiedFrom))
addDependency(fullyQualifiedFrom, fullyQualifiedTo, cp);
}
public void save(StringBuilder b) {
@ -203,31 +191,28 @@ public class Package implements Comparable<Package> {
return new Package(module, name);
}
public void loadDependency(String l) {
String n = l.substring(2);
addDependency(n);
}
public void loadPubapi(String l) {
String pi = l.substring(2);
addPubapi(pi);
}
public void saveDependencies(StringBuilder b) {
List<String> sorted_dependencies = new ArrayList<>();
for (String key : dependencies) {
sorted_dependencies.add(key);
// Dependencies where *to* is among sources
for (String fullyQualifiedFrom : dependencies.keySet()) {
for (String fullyQualifiedTo : dependencies.get(fullyQualifiedFrom)) {
b.append(String.format("D S %s -> %s%n", fullyQualifiedFrom, fullyQualifiedTo));
}
}
Collections.sort(sorted_dependencies);
for (String a : sorted_dependencies) {
b.append("D "+a+"\n");
// Dependencies where *to* is on class path
for (String fullyQualifiedFrom : cpDependencies.keySet()) {
for (String fullyQualifiedTo : cpDependencies.get(fullyQualifiedFrom)) {
b.append(String.format("D C %s -> %s%n", fullyQualifiedFrom, fullyQualifiedTo));
}
}
}
public void savePubapi(StringBuilder b) {
for (String l : pubapi) {
b.append("I "+l+"\n");
}
pubApi.asListOfStrings()
.stream()
.flatMap(l -> Stream.of("I ", l, "\n"))
.forEach(b::append);
}
public static void savePackages(Map<String,Package> packages, StringBuilder b) {

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2012-2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac;
import java.io.PrintWriter;
import java.util.Arrays;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import com.sun.tools.sjavac.comp.PubapiVisitor;
import com.sun.tools.sjavac.comp.SmartFileManager;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
public class PubApiExtractor {
// Setup a compiler context for finding classes in the classpath
// and to execute annotation processors.
Context context;
CompilationTask task;
/**
* Setup a compilation context, used for reading public apis of classes on the classpath
* as well as annotation processors.
*/
public PubApiExtractor(Options options) {
JavacTool compiler = com.sun.tools.javac.api.JavacTool.create();
SmartFileManager fileManager = new SmartFileManager(compiler.getStandardFileManager(null, null, null));
context = new com.sun.tools.javac.util.Context();
String[] args = options.prepJavacArgs();
task = compiler.getTask(new PrintWriter(System.err),
fileManager,
null,
Arrays.asList(args),
null,
null,
context);
// Trigger a creation of the JavaCompiler, necessary to get a sourceCompleter for ClassFinder.
// The sourceCompleter is used for build situations where a classpath class references other classes
// that happens to be on the sourcepath.
JavaCompiler.instance(context);
// context.put(JavaFileManager.class, fileManager);
}
public PubApi getPubApi(String fullyQualifiedClassName) {
ClassFinder cr = ClassFinder.instance(context);
Names ns = Names.instance(context);
Name n = ns.fromString(fullyQualifiedClassName);
ClassSymbol cs = cr.loadClass(n);
PubapiVisitor v = new PubapiVisitor();
v.visit(cs);
return v.getCollectedPubApi();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -373,8 +373,6 @@ public class Source implements Comparable<Source> {
return currentModule;
}
private static boolean gurka = false;
static private void scanDirectory(File dir, int rootPrefix, File root,
Set<String> suffixes,
List<String> excludes, List<String> includes,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -27,10 +27,11 @@ package com.sun.tools.sjavac;
import java.io.PrintStream;
import java.net.URI;
import java.util.Set;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.server.Sjavac;
/**
@ -89,8 +90,10 @@ public interface Transformer {
Map<String,Set<String>> oldPackageDependencies,
URI destRoot,
Map<String,Set<URI>> packageArtifacts,
Map<String,Set<String>> packageDependencies,
Map<String,String> packagePublicApis,
Map<String, Map<String, Set<String>>> packageDependencies, // Package name -> Fully Qualified Type [from] -> Set of fully qualified type [to]
Map<String, Map<String, Set<String>>> packageCpDependencies, // Package name -> Fully Qualified Type [from] -> Set of fully qualified type [to]
Map<String, PubApi> packagePublicApis,
Map<String, PubApi> dependencyApis,
int debugLevel,
boolean incremental,
int numCores,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -30,9 +30,13 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Utilities.
@ -106,6 +110,20 @@ public class Util {
return v;
}
/**
* Extract the package name from a fully qualified class name.
*
* Example: Given "pkg.subpkg.A" this method returns ":pkg.subpkg".
* Given "C" this method returns ":".
*
* @returns package name of the given class name
*/
public static String pkgNameOfClassName(String fqClassName) {
int i = fqClassName.lastIndexOf('.');
String pkg = i == -1 ? "" : fqClassName.substring(0, i);
return ":" + pkg;
}
/**
* Clean out unwanted sub options supplied inside a primary option.
* For example to only had portfile remaining from:
@ -183,6 +201,13 @@ public class Util {
return union;
}
public static <E> Set<E> subtract(Set<? extends E> orig,
Set<? extends E> toSubtract) {
Set<E> difference = new HashSet<>(orig);
difference.removeAll(toSubtract);
return difference;
}
public static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
@ -193,4 +218,16 @@ public class Util {
public static File pathToFile(Path path) {
return path == null ? null : path.toFile();
}
public static <E> Set<E> intersection(Collection<? extends E> c1,
Collection<? extends E> c2) {
Set<E> intersection = new HashSet<E>(c1);
intersection.retainAll(c2);
return intersection;
}
public static <I, T> Map<I, T> indexBy(Collection<? extends T> c,
Function<? super T, ? extends I> indexFunction) {
return c.stream().collect(Collectors.<T, I, T>toMap(indexFunction, o -> o));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -93,6 +93,11 @@ public class ClientMain {
if (hdrdir != null && !createIfMissing(hdrdir))
return -1;
Log.debug("==========================================================");
Log.debug("Launching sjavac client with the following parameters:");
Log.debug(" " + options.getStateArgsString());
Log.debug("==========================================================");
// Load the prev build state database.
JavacState javac_state = JavacState.load(options, out, err);
@ -167,6 +172,9 @@ public class ClientMain {
javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
javac_state.setVisibleSources(sources_to_link_to);
int round = 0;
printRound(round);
// If there is any change in the source files, taint packages
// and mark the database in need of saving.
javac_state.checkSourceStatus(false);
@ -188,6 +196,10 @@ public class ClientMain {
// Go through all sources and taint all packages that miss artifacts.
javac_state.taintPackagesThatMissArtifacts();
// Check recorded classpath public apis. Taint packages that depend on
// classpath classes whose public apis have changed.
javac_state.taintPackagesDependingOnChangedClasspathPackages();
// Now clean out all known artifacts belonging to tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
// Copy files, for example property files, images files, xml files etc etc.
@ -231,11 +243,22 @@ public class ClientMain {
}
do {
if (round > 0)
printRound(round);
// Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
again = javac_state.performJavaCompilations(sjavac, options, recently_compiled, rc);
if (!rc[0]) break;
if (!rc[0]) {
Log.debug("Compilation failed.");
break;
}
if (!again) {
Log.debug("Nothing left to do.");
}
round++;
} while (again);
Log.debug("No need to do another round.");
// Only update the state if the compile went well.
if (rc[0]) {
javac_state.save();
@ -323,4 +346,10 @@ public class ClientMain {
}
}
private static void printRound(int round) {
Log.debug("****************************************");
Log.debug("* Round " + round + " *");
Log.debug("****************************************");
}
}

View File

@ -1,181 +0,0 @@
/*
* Copyright (c) 1999, 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp;
import javax.lang.model.element.Element;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Name;
/** Utility class containing dependency information between packages
* and the pubapi for a package.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Dependencies {
protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>();
// The log to be used for error reporting.
protected Log log;
// Map from package name to packages that the package depends upon.
protected Map<Name,Set<Name>> deps;
// This is the set of all packages that are supplied
// through the java files at the command line.
protected Set<Name> explicitPackages;
// Map from a package name to its public api.
// Will the Name encode the module in the future?
// If not, this will have to change to map from Module+Name to public api.
protected Map<Name,StringBuffer> publicApiPerClass;
public static Dependencies instance(Context context) {
Dependencies instance = context.get(dependenciesKey);
if (instance == null)
instance = new Dependencies(context);
return instance;
}
private Dependencies(Context context) {
context.put(dependenciesKey, this);
log = Log.instance(context);
deps = new HashMap<>();
explicitPackages = new HashSet<>();
publicApiPerClass = new HashMap<>();
}
/**
* Fetch the set of dependencies that are relevant to the compile
* that has just been performed. I.e. we are only interested in
* dependencies for classes that were explicitly compiled.
* @return
*/
public Map<String,Set<String>> getDependencies() {
Map<String,Set<String>> new_deps = new HashMap<>();
if (explicitPackages == null) return new_deps;
for (Name pkg : explicitPackages) {
Set<Name> set = deps.get(pkg);
if (set != null) {
Set<String> new_set = new_deps.get(pkg.toString());
if (new_set == null) {
new_set = new HashSet<>();
// Modules beware....
new_deps.put(":"+pkg.toString(), new_set);
}
for (Name d : set) {
new_set.add(":"+d.toString());
}
}
}
return new_deps;
}
static class CompareNames implements Comparator<Name> {
public int compare(Name a, Name b) {
return a.toString().compareTo(b.toString());
}
}
/**
* Convert the map from class names to their pubapi to a map
* from package names to their pubapi (which is the sorted concatenation
* of all the class pubapis)
*/
public Map<String,String> getPubapis() {
Map<String,String> publicApiPerPackage = new HashMap<>();
if (publicApiPerClass == null) return publicApiPerPackage;
Name[] keys = publicApiPerClass.keySet().toArray(new Name[0]);
Arrays.sort(keys, new CompareNames());
StringBuffer newPublicApi = new StringBuffer();
int i=0;
String prevPkg = "";
for (Name k : keys) {
String cn = k.toString();
String pn = "";
int dp = cn.lastIndexOf('.');
if (dp != -1) {
pn = cn.substring(0,dp);
}
if (!pn.equals(prevPkg)) {
if (!prevPkg.equals("")) {
// Add default module name ":"
publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
}
newPublicApi = new StringBuffer();
prevPkg = pn;
}
newPublicApi.append(publicApiPerClass.get(k));
i++;
}
if (!prevPkg.equals(""))
publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
return publicApiPerPackage;
}
/**
* Visit the api of a class and construct a pubapi string and
* store it into the pubapi_perclass map.
*/
public void visitPubapi(Element e) {
Name n = ((ClassSymbol)e).fullname;
Name p = ((ClassSymbol)e).packge().fullname;
StringBuffer sb = publicApiPerClass.get(n);
Assert.check(sb == null);
sb = new StringBuffer();
PubapiVisitor v = new PubapiVisitor(sb);
v.visit(e);
if (sb.length()>0) {
publicApiPerClass.put(n, sb);
}
explicitPackages.add(p);
}
/**
* Collect a dependency. curr_pkg is marked as depending on dep_pkg.
*/
public void collect(Name currPkg, Name depPkg) {
if (!currPkg.equals(depPkg)) {
Set<Name> theset = deps.get(currPkg);
if (theset==null) {
theset = new HashSet<>();
deps.put(currPkg, theset);
}
theset.add(depPkg);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -22,9 +22,33 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package pkg14;
public class Cls14 {
public int[] getCls15() {
return null;
package com.sun.tools.sjavac.comp;
import javax.tools.FileObject;
import javax.tools.ForwardingFileObject;
import javax.tools.JavaFileManager.Location;
import com.sun.tools.javac.api.ClientCodeWrapper.Trusted;
@Trusted
public class FileObjectWithLocation<F extends FileObject> extends ForwardingFileObject<F> {
private final Location loc;
public FileObjectWithLocation(F delegate, Location loc) {
super(delegate);
this.loc = loc;
}
public Location getLocation() {
return loc;
}
public FileObject getDelegate() {
return fileObject;
}
public String toString() {
return "FileObjectWithLocation[" + fileObject + "]";
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp;
import javax.tools.ForwardingJavaFileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.api.ClientCodeWrapper.Trusted;
@Trusted
public class JavaFileObjectWithLocation<F extends JavaFileObject> extends ForwardingJavaFileObject<F> {
private final Location loc;
public JavaFileObjectWithLocation(F delegate, Location loc) {
super(delegate);
this.loc = loc;
}
public Location getLocation() {
return loc;
}
public F getDelegate() {
return fileObject;
}
public String toString() {
return "JavaFileObjectWithLocation[loc: " + loc + ", " + fileObject + "]";
}
@Override
public int hashCode() {
return loc.hashCode() ^ fileObject.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof JavaFileObjectWithLocation))
return false;
JavaFileObjectWithLocation<?> other = (JavaFileObjectWithLocation<?>) obj;
return loc.equals(other.loc) && fileObject.equals(other.fileObject);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -41,6 +41,7 @@ import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Name;
import com.sun.tools.sjavac.Log;
public class PathAndPackageVerifier implements TaskListener {
@ -50,30 +51,37 @@ public class PathAndPackageVerifier implements TaskListener {
@Override
@DefinedBy(Api.COMPILER_TREE)
public void started(TaskEvent e) {
public void finished(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.ANALYZE) {
CompilationUnitTree cu = e.getCompilationUnit();
if (cu == null)
return;
JavaFileObject jfo = cu.getSourceFile();
if (jfo == null)
return; // No source file -> package doesn't matter
JCTree pkg = (JCTree) cu.getPackageName();
if (pkg == null)
return; // Default package. See JDK-8048144.
Path dir = Paths.get(jfo.toUri()).normalize().getParent();
if (!checkPathAndPackage(dir, pkg))
misplacedCompilationUnits.add(cu);
}
if (e.getKind() == TaskEvent.Kind.COMPILATION) {
for (CompilationUnitTree cu : misplacedCompilationUnits) {
Log.error("Misplaced compilation unit.");
Log.error(" Directory: " + Paths.get(cu.getSourceFile().toUri()).getParent());
Log.error(" Package: " + cu.getPackageName());
}
}
}
@Override
@DefinedBy(Api.COMPILER_TREE)
public void finished(TaskEvent e) {
if (e.getKind() != TaskEvent.Kind.ANALYZE)
return;
CompilationUnitTree cu = e.getCompilationUnit();
if (cu == null)
return;
JavaFileObject jfo = cu.getSourceFile();
if (jfo == null)
return; // No source file -> package doesn't matter
JCTree pkg = (JCTree) cu.getPackageName();
if (pkg == null)
return; // Default package. See JDK-8048144.
Path dir = Paths.get(jfo.toUri()).normalize().getParent();
if (!checkPathAndPackage(dir, pkg))
misplacedCompilationUnits.add(cu);
public boolean errorsDiscovered() {
return misplacedCompilationUnits.size() > 0;
}
/* Returns true if dir matches pkgName.
@ -94,10 +102,6 @@ public class PathAndPackageVerifier implements TaskListener {
return !pkgIter.hasNext(); /*&& !pathIter.hasNext() See JDK-8059598 */
}
public Set<CompilationUnitTree> getMisplacedCompilationUnits() {
return misplacedCompilationUnits;
}
/* Iterates over the names of the parents of the given path:
* Example: dir1/dir2/dir3 results in dir3 -> dir2 -> dir1
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -29,12 +29,9 @@ import java.net.URI;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.server.CompilationResult;
@ -58,28 +55,13 @@ public class PooledSjavac implements Sjavac {
public PooledSjavac(Sjavac delegate, int poolsize) {
Objects.requireNonNull(delegate);
this.delegate = delegate;
pool = Executors.newFixedThreadPool(poolsize, new ThreadFactory() {
AtomicInteger count = new AtomicInteger();
@Override
public Thread newThread(Runnable runnable) {
String cls = PooledSjavac.class.getSimpleName();
int num = count.incrementAndGet();
Thread t = new Thread(runnable, cls + "-" + num);
t.setDaemon(true);
return t;
}
});
pool = Executors.newFixedThreadPool(poolsize);
}
@Override
public SysInfo getSysInfo() {
try {
return pool.submit(new Callable<SysInfo>() {
@Override
public SysInfo call() throws Exception {
return delegate.getSysInfo();
}
}).get();
return pool.submit(() -> delegate.getSysInfo()).get();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error during getSysInfo", e);
@ -94,16 +76,13 @@ public class PooledSjavac implements Sjavac {
final Set<URI> sourcesToCompile,
final Set<URI> visibleSources) {
try {
return pool.submit(new Callable<CompilationResult>() {
@Override
public CompilationResult call() throws Exception {
return delegate.compile(protocolId,
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
}
return pool.submit(() -> {
return delegate.compile(protocolId,
invocationId,
args,
explicitSources,
sourcesToCompile,
visibleSources);
}).get();
} catch (Exception e) {
e.printStackTrace();
@ -113,6 +92,7 @@ public class PooledSjavac implements Sjavac {
@Override
public void shutdown() {
Log.debug("Shutting down PooledSjavac");
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
@ -122,8 +102,6 @@ public class PooledSjavac implements Sjavac {
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
Log.error("ThreadPool did not terminate");
}
// Grace period for thread termination
Thread.sleep(1000);
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 1999, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.lang.model.element.Element;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
import com.sun.tools.sjavac.pubapi.PubApi;
/**
* Utility class containing public API information.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class PubAPIs {
protected static final Context.Key<PubAPIs> pubApisKey = new Context.Key<>();
// The log to be used for error reporting.
protected Log log;
// Map from a class name to its public api.
// Will the Name encode the module in the future?
// If not, this will have to change to map from Module+Name to public api.
protected Map<ClassSymbol, PubApi> publicApiPerClass = new HashMap<>();
public static PubAPIs instance(Context context) {
PubAPIs instance = context.get(pubApisKey);
if (instance == null)
instance = new PubAPIs(context);
return instance;
}
private PubAPIs(Context context) {
context.put(pubApisKey, this);
log = Log.instance(context);
}
/**
* Convert the map from class names to their pubapi to a map
* from package names to their pubapi.
*/
public Map<String, PubApi> getPubapis(Collection<JavaFileObject> explicitJFOs, boolean explicits) {
// Maps ":java.lang" to a package level pub api (with only types on top level)
Map<String, PubApi> result = new HashMap<>();
for (ClassSymbol cs : publicApiPerClass.keySet()) {
boolean amongExplicits = explicitJFOs.contains(cs.sourcefile);
if (explicits != amongExplicits)
continue;
String pkg = ":" + cs.packge().fullname;
PubApi currentPubApi = result.getOrDefault(pkg, new PubApi());
result.put(pkg, PubApi.mergeTypes(currentPubApi, publicApiPerClass.get(cs)));
}
return result;
}
/**
* Visit the api of a class and construct a pubapi and
* store it into the pubapi_perclass map.
*/
@SuppressWarnings("deprecation")
public void visitPubapi(Element e) {
// Skip anonymous classes for now
if (e == null)
return;
PubapiVisitor v = new PubapiVisitor();
v.visit(e);
publicApiPerClass.put((ClassSymbol) e, v.getCollectedPubApi());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, 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
@ -25,17 +25,28 @@
package com.sun.tools.sjavac.comp;
import java.util.Iterator;
import static javax.lang.model.element.Modifier.PRIVATE;
import java.util.List;
import javax.lang.model.element.Modifier;
import java.util.stream.Collectors;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementScanner9;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.pubapi.PubApiTypeParam;
import com.sun.tools.sjavac.pubapi.PubMethod;
import com.sun.tools.sjavac.pubapi.PubType;
import com.sun.tools.sjavac.pubapi.PubVar;
import com.sun.tools.sjavac.pubapi.TypeDesc;
/** Utility class that constructs a textual representation
* of the public api of a class.
@ -47,40 +58,67 @@ import com.sun.tools.javac.util.DefinedBy.Api;
*/
public class PubapiVisitor extends ElementScanner9<Void, Void> {
StringBuffer sb;
// Important that it is 1! Part of protocol over wire, silly yes.
// Fix please.
int indent = 1;
private PubApi collectedApi = new PubApi();
public PubapiVisitor(StringBuffer sb) {
this.sb = sb;
}
String depth(int l) {
return " ".substring(0, l);
private boolean isNonPrivate(Element e) {
return !e.getModifiers().contains(PRIVATE);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Void visitType(TypeElement e, Void p) {
if (e.getModifiers().contains(Modifier.PUBLIC)
|| e.getModifiers().contains(Modifier.PROTECTED))
{
sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n");
indent += 2;
Void v = super.visitType(e, p);
indent -= 2;
return v;
if (isNonPrivate(e)) {
PubApi prevApi = collectedApi;
collectedApi = new PubApi();
super.visitType(e, p);
if (!isAnonymous(e)) {
String name = ((ClassSymbol) e).flatname.toString();
PubType t = new PubType(e.getModifiers(),
name,
//e.getQualifiedName().toString(),
collectedApi);
prevApi.types.put(t.fqName, t);
}
collectedApi = prevApi;
}
return null;
}
private boolean isAnonymous(TypeElement e) {
return e.getQualifiedName().length() == 0;
}
private static String encodeChar(int c) {
return String.format("\\u%04x", c);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Void visitVariable(VariableElement e, Void p) {
if (e.getModifiers().contains(Modifier.PUBLIC)
|| e.getModifiers().contains(Modifier.PROTECTED)) {
sb.append(depth(indent)).append("VAR ")
.append(makeVariableString(e)).append("\n");
if (isNonPrivate(e)) {
Object constVal = e.getConstantValue();
String constValStr = null;
// TODO: This doesn't seem to be entirely accurate. What if I change
// from, say, 0 to 0L? (And the field is public final static so that
// it could get inlined.)
if (constVal != null) {
if (e.asType().toString().equals("char")) {
// What type is 'value'? Is it already a char?
char c = constVal.toString().charAt(0);
constValStr = "'" + encodeChar(c) + "'";
} else {
constValStr = constVal.toString()
.chars()
.mapToObj(PubapiVisitor::encodeChar)
.collect(Collectors.joining("", "\"", "\""));
}
}
PubVar v = new PubVar(e.getModifiers(),
TypeDesc.fromType(e.asType()),
e.toString(),
constValStr);
collectedApi.variables.put(v.identifier, v);
}
// Safe to not recurse here, because the only thing
// to visit here is the constructor of a variable declaration.
// If it happens to contain an anonymous inner class (which it might)
@ -91,70 +129,38 @@ public class PubapiVisitor extends ElementScanner9<Void, Void> {
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Void visitExecutable(ExecutableElement e, Void p) {
if (e.getModifiers().contains(Modifier.PUBLIC)
|| e.getModifiers().contains(Modifier.PROTECTED)) {
sb.append(depth(indent)).append("METHOD ")
.append(makeMethodString(e)).append("\n");
if (isNonPrivate(e)) {
PubMethod m = new PubMethod(e.getModifiers(),
getTypeParameters(e.getTypeParameters()),
TypeDesc.fromType(e.getReturnType()),
e.getSimpleName().toString(),
getTypeDescs(getParamTypes(e)),
getTypeDescs(e.getThrownTypes()));
collectedApi.methods.put(m.asSignatureString(), m);
}
return null;
}
/**
* Creates a String representation of a method element with everything
* necessary to track all public aspects of it in an API.
* @param e Element to create String for.
* @return String representation of element.
*/
protected String makeMethodString(ExecutableElement e) {
StringBuilder result = new StringBuilder();
for (Modifier modifier : e.getModifiers()) {
result.append(modifier.toString());
result.append(" ");
}
result.append(e.getReturnType().toString());
result.append(" ");
result.append(e.toString());
List<? extends TypeMirror> thrownTypes = e.getThrownTypes();
if (!thrownTypes.isEmpty()) {
result.append(" throws ");
for (Iterator<? extends TypeMirror> iterator = thrownTypes
.iterator(); iterator.hasNext();) {
TypeMirror typeMirror = iterator.next();
result.append(typeMirror.toString());
if (iterator.hasNext()) {
result.append(", ");
}
}
}
return result.toString();
private List<PubApiTypeParam> getTypeParameters(List<? extends TypeParameterElement> elements) {
return elements.stream()
.map(e -> new PubApiTypeParam(e.getSimpleName().toString(), getTypeDescs(e.getBounds())))
.collect(Collectors.toList());
}
/**
* Creates a String representation of a variable element with everything
* necessary to track all public aspects of it in an API.
* @param e Element to create String for.
* @return String representation of element.
*/
protected String makeVariableString(VariableElement e) {
StringBuilder result = new StringBuilder();
for (Modifier modifier : e.getModifiers()) {
result.append(modifier.toString());
result.append(" ");
}
result.append(e.asType().toString());
result.append(" ");
result.append(e.toString());
Object value = e.getConstantValue();
if (value != null) {
result.append(" = ");
if (e.asType().toString().equals("char")) {
int v = (int)value.toString().charAt(0);
result.append("'\\u"+Integer.toString(v,16)+"'");
} else {
result.append(value.toString());
}
}
return result.toString();
private List<TypeMirror> getParamTypes(ExecutableElement e) {
return e.getParameters()
.stream()
.map(VariableElement::asType)
.collect(Collectors.toList());
}
private List<TypeDesc> getTypeDescs(List<? extends TypeMirror> list) {
return list.stream()
.map(TypeDesc::fromType)
.collect(Collectors.toList());
}
public PubApi getCollectedPubApi() {
return collectedApi;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -29,24 +29,25 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Dependencies;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Options;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.comp.dependencies.DependencyCollector;
import com.sun.tools.sjavac.comp.dependencies.NewDependencyCollector;
import com.sun.tools.sjavac.comp.dependencies.PublicApiCollector;
import com.sun.tools.sjavac.server.CompilationResult;
import com.sun.tools.sjavac.server.Sjavac;
@ -76,86 +77,79 @@ public class SjavacImpl implements Sjavac {
List<File> explicitSources,
Set<URI> sourcesToCompile,
Set<URI> visibleSources) {
JavacTool compiler = JavacTool.create();
try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {
SmartFileManager smartFileManager = new SmartFileManager(fileManager);
JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler();
try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
SmartFileManager sfm = new SmartFileManager(fm);
Context context = new Context();
// Now setup the actual compilation....
Dependencies.GraphDependencies.preRegister(context);
// Now setup the actual compilation
CompilationResult compilationResult = new CompilationResult(0);
// First deal with explicit source files on cmdline and in at file.
ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(explicitSources)) {
compilationUnits.append(i);
// First deal with explicit source files on cmdline and in at file
ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>();
for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(explicitSources)) {
explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH));
}
// Now deal with sources supplied as source_to_compile.
// Now deal with sources supplied as source_to_compile
ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
for (URI u : sourcesToCompile) {
for (URI u : sourcesToCompile)
sourcesToCompileFiles.append(new File(u));
}
for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
compilationUnits.append(i);
}
// Create a new logger.
for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(sourcesToCompileFiles))
explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH));
// Create a new logger
StringWriter stdoutLog = new StringWriter();
StringWriter stderrLog = new StringWriter();
PrintWriter stdout = new PrintWriter(stdoutLog);
PrintWriter stderr = new PrintWriter(stderrLog);
com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
DependencyCollector depsCollector = new DependencyCollector();
PublicApiCollector pubApiCollector = new PublicApiCollector();
PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs);
PathAndPackageVerifier papVerifier = new PathAndPackageVerifier();
NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs);
try {
if (compilationUnits.size() > 0) {
smartFileManager.setVisibleSources(visibleSources);
smartFileManager.cleanArtifacts();
smartFileManager.setLog(stdout);
if (explicitJFOs.size() > 0) {
sfm.setVisibleSources(visibleSources);
sfm.cleanArtifacts();
sfm.setLog(stdout);
// Do the compilation!
JavacTaskImpl task =
(JavacTaskImpl) compiler.getTask(stderr,
smartFileManager,
sfm,
null,
Arrays.asList(args),
null,
compilationUnits,
explicitJFOs,
context);
smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
sfm.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
task.addTaskListener(depsCollector);
task.addTaskListener(pubApiCollector);
task.addTaskListener(papVerifier);
logJavacInvocation(args);
rc = task.doCall();
smartFileManager.flush();
Log.debug("javac returned with code " + rc);
sfm.flush();
}
} catch (Exception e) {
Log.error(Util.getStackTrace(e));
stderrLog.append(Util.getStackTrace(e));
rc = com.sun.tools.javac.main.Main.Result.ERROR;
}
compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
compilationResult.packageArtifacts = sfm.getPackageArtifacts();
Dependencies deps = Dependencies.instance(context);
for (PackageSymbol from : depsCollector.getSourcePackages()) {
for (PackageSymbol to : depsCollector.getDependenciesForPkg(from))
deps.collect(from.fullname, to.fullname);
}
for (ClassSymbol cs : pubApiCollector.getClassSymbols())
deps.visitPubapi(cs);
if (papVerifier.getMisplacedCompilationUnits().size() > 0) {
for (CompilationUnitTree cu : papVerifier.getMisplacedCompilationUnits()) {
System.err.println("Misplaced compilation unit.");
System.err.println(" Directory: " + Paths.get(cu.getSourceFile().toUri()).getParent());
System.err.println(" Package: " + cu.getPackageName());
}
if (papVerifier.errorsDiscovered())
rc = com.sun.tools.javac.main.Main.Result.ERROR;
}
compilationResult.packageDependencies = deps.getDependencies();
compilationResult.packagePubapis = deps.getPubapis();
compilationResult.packageDependencies = depsCollector.getDependencies(false);
compilationResult.packageCpDependencies = depsCollector.getDependencies(true);
compilationResult.packagePubapis = pubApiCollector.getPubApis(true); // pubApis.getPubapis(explicitJFOs, true);
compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false); // pubApis.getPubapis(explicitJFOs, false);
compilationResult.stdout = stdoutLog.toString();
compilationResult.stderr = stderrLog.toString();
compilationResult.returnCode = rc.exitCode;
@ -172,10 +166,22 @@ public class SjavacImpl implements Sjavac {
// ... maybe we should wait for any current request to finish?
}
@Override
public String serverSettings() {
return "";
}
private void logJavacInvocation(String[] args) {
Log.debug("Invoking javac with args");
Iterator<String> argIter = Arrays.asList(args).iterator();
while (argIter.hasNext()) {
String arg = argIter.next();
String line = " " + arg;
if (arg.matches("\\-(d|cp|classpath|sourcepath|source|target)")
&& argIter.hasNext()) {
line += " " + argIter.next();
}
Log.debug(line);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -91,6 +91,12 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
((JavacFileManager) fileManager).setSymbolFileEnabled(b);
}
@DefinedBy(Api.COMPILER)
public String inferBinaryName(Location location, JavaFileObject file) {
return super.inferBinaryName(location, locUnwrap(file));
}
public Map<String,Set<URI>> getPackageArtifacts() {
return packageArtifacts;
}
@ -100,10 +106,11 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
String packageName,
Set<Kind> kinds,
boolean recurse) throws IOException {
// TODO: Do this lazily by returning an iterable with a filtering Iterator
// Acquire the list of files.
Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
if (visibleSources.isEmpty()) {
return files;
return locWrapMany(files, location);
}
// Now filter!
ListBuffer<JavaFileObject> filteredFiles = new ListBuffer<>();
@ -116,12 +123,8 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
filteredFiles.add(f);
}
}
return filteredFiles;
}
@Override @DefinedBy(Api.COMPILER)
public boolean hasLocation(Location location) {
return super.hasLocation(location);
return locWrapMany(filteredFiles, location);
}
@Override @DefinedBy(Api.COMPILER)
@ -129,6 +132,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
String className,
Kind kind) throws IOException {
JavaFileObject file = super.getJavaFileForInput(location, className, kind);
file = locWrap(file, location);
if (file == null || visibleSources.isEmpty()) {
return file;
}
@ -145,6 +149,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
Kind kind,
FileObject sibling) throws IOException {
JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
file = locWrap(file, location);
if (file == null) return file;
int dp = className.lastIndexOf('.');
String pkg_name = "";
@ -162,6 +167,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
String packageName,
String relativeName) throws IOException {
FileObject file = super.getFileForInput(location, packageName, relativeName);
file = locWrap(file, location);
if (file == null || visibleSources.isEmpty()) {
return file;
}
@ -177,11 +183,12 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
String packageName,
String relativeName,
FileObject sibling) throws IOException {
FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
FileObject superFile = super.getFileForOutput(location, packageName, relativeName, sibling);
FileObject file = locWrap(superFile, location);
if (file == null) return file;
if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
file instanceof JavaFileObject) {
file = new SmartFileObject((JavaFileObject)file, stdout);
if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) && superFile instanceof JavaFileObject) {
file = new SmartFileObject((JavaFileObject) file, stdout);
packageName = ":" + packageNameFromFileName(relativeName);
}
if (packageName.equals("")) {
@ -191,7 +198,7 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
return file;
}
private String packageNameFromFileName(String fn) {
private static String packageNameFromFileName(String fn) {
StringBuilder sb = new StringBuilder();
int p = fn.indexOf('_'), pp = 0;
while (p != -1) {
@ -204,16 +211,6 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
return sb.toString();
}
@Override @DefinedBy(Api.COMPILER)
public void flush() throws IOException {
super.flush();
}
@Override @DefinedBy(Api.COMPILER)
public void close() throws IOException {
super.close();
}
void addArtifact(String pkgName, URI art) {
Set<URI> s = packageArtifacts.get(pkgName);
if (s == null) {
@ -222,4 +219,50 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
}
s.add(art);
}
public static JavaFileObject locWrap(JavaFileObject jfo, Location loc) {
// From sjavac's perspective platform classes are not interesting and
// there is no need to track the location for these file objects.
// Also, there exists some jfo instanceof checks which breaks if
// the jfos for platform classes are wrapped.
if (loc == StandardLocation.PLATFORM_CLASS_PATH)
return jfo;
return jfo == null ? null : new JavaFileObjectWithLocation<>(jfo, loc);
}
private static FileObject locWrap(FileObject fo, Location loc) {
if (fo instanceof JavaFileObject)
return locWrap((JavaFileObject) fo, loc);
return fo == null ? null : new FileObjectWithLocation<>(fo, loc);
}
@DefinedBy(Api.COMPILER)
@Override
public boolean isSameFile(FileObject a, FileObject b) {
return super.isSameFile(locUnwrap(a), locUnwrap(b));
}
private static ListBuffer<JavaFileObject> locWrapMany(Iterable<JavaFileObject> jfos,
Location loc) {
ListBuffer<JavaFileObject> locWrapped = new ListBuffer<>();
for (JavaFileObject f : jfos)
locWrapped.add(locWrap(f, loc));
return locWrapped;
}
private static FileObject locUnwrap(FileObject fo) {
if (fo instanceof FileObjectWithLocation<?>)
return ((FileObjectWithLocation<?>) fo).getDelegate();
if (fo instanceof JavaFileObjectWithLocation<?>)
return ((JavaFileObjectWithLocation<?>) fo).getDelegate();
return fo;
}
private static JavaFileObject locUnwrap(JavaFileObject fo) {
if (fo instanceof JavaFileObjectWithLocation<?>)
return ((JavaFileObjectWithLocation<?>) fo).getDelegate();
return fo;
}
}

View File

@ -1,33 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp.dependencies;
import java.util.Set;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
interface Dependency {
Set<PackageSymbol> getPackages();
}

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp.dependencies;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.sjavac.Util;
public class DependencyCollector implements TaskListener {
Map<PackageSymbol, Set<PackageSymbol>> collectedDependencies = new HashMap<>();
@Override
@DefinedBy(Api.COMPILER_TREE)
public void started(TaskEvent e) {
}
@Override
@DefinedBy(Api.COMPILER_TREE)
public void finished(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.ANALYZE) {
JCCompilationUnit cu = (JCCompilationUnit) e.getCompilationUnit();
PackageSymbol thisPkg = cu.packge;
if (thisPkg == null) {
// Compilation unit in default package. See JDK-8048144.
return;
}
DependencyScanner ds = new DependencyScanner();
cu.accept(ds);
Set<PackageSymbol> pkgDeps = ds.getResult()
.stream()
.flatMap(dep -> dep.getPackages().stream())
.collect(Collectors.toSet());
collectedDependencies.merge(thisPkg, pkgDeps, Util::union);
}
}
public Set<PackageSymbol> getSourcePackages() {
return collectedDependencies.keySet();
}
public Set<PackageSymbol> getDependenciesForPkg(PackageSymbol ps) {
return collectedDependencies.get(ps);
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp.dependencies;
import java.util.HashSet;
import java.util.Set;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.TreeScanner;
class DependencyScanner extends TreeScanner {
public final Set<Dependency> dependencies = new HashSet<>();
private boolean isValidDependency(Type t) {
if (t == null || t.isPrimitiveOrVoid() || t.isErroneous())
return false;
TypeTag tag = t.getTag();
return tag != TypeTag.PACKAGE
&& tag != TypeTag.METHOD
&& tag != TypeTag.ARRAY
&& tag != TypeTag.TYPEVAR;
}
@Override
public void visitIdent(JCIdent tree) {
if (isValidDependency(tree.type))
dependencies.add(new TypeAndSupertypesDependency(tree.type.tsym));
super.visitIdent(tree);
}
@Override
public void visitSelect(JCFieldAccess tree) {
if (tree.getIdentifier().contentEquals("*")) {
Symbol sym = tree.selected instanceof JCIdent ? ((JCIdent) tree.selected).sym
: ((JCFieldAccess) tree.selected).sym;
if (sym instanceof ClassSymbol) {
ClassSymbol clsSym = (ClassSymbol) sym;
dependencies.add(new TypeAndSupertypesDependency(clsSym.type.tsym));
} else {
dependencies.add(new PackageDependency((PackageSymbol) sym));
}
} else if (tree.type != null && tree.type.hasTag(TypeTag.METHOD)) { // Method call? Depend on the result (even though we never access it elsewhere)
Type retType = tree.type.getReturnType();
if (isValidDependency(retType))
dependencies.add(new TypeAndSupertypesDependency(retType.tsym));
} else if (isValidDependency(tree.type)) {
dependencies.add(new TypeAndSupertypesDependency(tree.type.tsym));
}
super.visitSelect(tree);
}
public Set<Dependency> getResult() {
return dependencies;
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp.dependencies;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Dependencies.GraphDependencies;
import com.sun.tools.javac.util.Dependencies.GraphDependencies.CompletionNode;
import com.sun.tools.javac.util.GraphUtils.Node;
import com.sun.tools.sjavac.Util;
import com.sun.tools.sjavac.comp.JavaFileObjectWithLocation;
import com.sun.tools.sjavac.comp.PubAPIs;
public class NewDependencyCollector implements TaskListener {
private final Context context;
private final Collection<JavaFileObject> explicitJFOs;
private Map<String, Map<String, Set<String>>> deps;
private Map<String, Map<String, Set<String>>> cpDeps;
public NewDependencyCollector(Context context,
Collection<JavaFileObject> explicitJFOs) {
this.context = context;
this.explicitJFOs = explicitJFOs;
}
@Override
@DefinedBy(Api.COMPILER_TREE)
public void finished(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.COMPILATION) {
collectPubApisOfDependencies(context, explicitJFOs);
deps = getDependencies(context, explicitJFOs, false);
cpDeps = getDependencies(context, explicitJFOs, true);
}
}
public Map<String, Map<String, Set<String>>> getDependencies(boolean cp) {
return cp ? cpDeps : deps;
}
private Set<CompletionNode> getDependencyNodes(Context context,
Collection<JavaFileObject> explicitJFOs,
boolean explicits) {
GraphDependencies deps = (GraphDependencies) GraphDependencies.instance(context);
return deps.getNodes()
.stream()
.filter(n -> n instanceof CompletionNode)
.map(n -> (CompletionNode) n)
.filter(n -> n.getClassSymbol().fullname != null)
.filter(n -> explicits == explicitJFOs.contains(n.getClassSymbol().classfile))
.collect(Collectors.toSet());
}
private void collectPubApisOfDependencies(Context context,
Collection<JavaFileObject> explicitJFOs) {
PubAPIs pubApis = PubAPIs.instance(context);
for (CompletionNode cDepNode : getDependencyNodes(context, explicitJFOs, false)) {
ClassSymbol cs = cDepNode.getClassSymbol().outermostClass();
Location loc = getLocationOf(cs);
// We're completely ignorant of PLATFORM_CLASS_PATH classes
if (loc == StandardLocation.CLASS_PATH || loc == StandardLocation.SOURCE_PATH)
pubApis.visitPubapi(cs);
}
}
private Location getLocationOf(ClassSymbol cs) {
JavaFileObject jfo = cs.outermostClass().classfile;
if (jfo instanceof JavaFileObjectWithLocation) {
return ((JavaFileObjectWithLocation<?>) jfo).getLocation();
}
// jfo is most likely on PLATFORM_CLASS_PATH.
// See notes in SmartFileManager::locWrap
return null;
}
// :Package -> fully qualified class name [from] -> set of fully qualified class names [to]
private Map<String, Map<String, Set<String>>> getDependencies(Context context,
Collection<JavaFileObject> explicitJFOs,
boolean cp) {
Map<String, Map<String, Set<String>>> result = new HashMap<>();
for (CompletionNode cnode : getDependencyNodes(context, explicitJFOs, true)) {
String fqDep = cnode.getClassSymbol().outermostClass().flatname.toString();
String depPkg = Util.pkgNameOfClassName(fqDep);
Map<String, Set<String>> depsForThisClass = result.get(depPkg);
if (depsForThisClass == null)
result.put(depPkg, depsForThisClass = new HashMap<>());
for (Node<?,?> depNode : cnode.getDependenciesByKind(GraphDependencies.Node.DependencyKind.REQUIRES)) {
boolean isCompletionNode = depNode instanceof CompletionNode;
if (isCompletionNode) {
CompletionNode cDepNode = (CompletionNode) depNode;
if (cDepNode == cnode)
continue;
if (cDepNode.getClassSymbol().fullname == null) // Anonymous class
continue;
Location depLoc = getLocationOf(cDepNode.getClassSymbol());
boolean relevant = (cp && depLoc == StandardLocation.CLASS_PATH)
|| (!cp && depLoc == StandardLocation.SOURCE_PATH);
if (!relevant)
continue;
Set<String> fqDeps = depsForThisClass.get(fqDep);
if (fqDeps == null)
depsForThisClass.put(fqDep, fqDeps = new HashSet<>());
fqDeps.add(cDepNode.getClassSymbol().outermostClass().flatname.toString());
}
}
}
return result;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -22,40 +22,91 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.comp.dependencies;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.tools.JavaFileObject;
import com.sun.source.tree.Tree;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.comp.PubAPIs;
import com.sun.tools.sjavac.pubapi.PubApi;
public class PublicApiCollector implements TaskListener {
final Set<ClassSymbol> classSymbols = new HashSet<>();
private Context context;
private final Set<ClassSymbol> classSymbols = new HashSet<>();
private final Collection<JavaFileObject> explicitJFOs;
@Override
@DefinedBy(Api.COMPILER_TREE)
public void started(TaskEvent e) {
// Result collected upon compilation task finished
private Map<String, PubApi> explicitPubApis;
private Map<String, PubApi> nonExplicitPubApis;
public PublicApiCollector(Context context,
Collection<JavaFileObject> explicitJFOs) {
this.context = context;
this.explicitJFOs = explicitJFOs;
}
@Override
@DefinedBy(Api.COMPILER_TREE)
public void finished(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.ANALYZE) {
for (Tree t : e.getCompilationUnit().getTypeDecls()) {
if (t instanceof JCClassDecl) // Can also be a JCSkip
classSymbols.add(((JCClassDecl) t).sym);
}
switch (e.getKind()) {
case ANALYZE:
collectClassSymbols((JCCompilationUnit) e.getCompilationUnit());
break;
case COMPILATION:
Log.debug("Compilation finished");
Log.debug("Extracting pub APIs for the following symbols:");
for (ClassSymbol cs : classSymbols)
Log.debug(" " + cs.fullname);
extractPubApis();
// Save result for later retrieval. (Important that we do this
// before we return from this method, because we may not access
// symbols after compilation is finished.)
PubAPIs pa = PubAPIs.instance(context);
explicitPubApis = pa.getPubapis(explicitJFOs, true);
nonExplicitPubApis = pa.getPubapis(explicitJFOs, false);
Log.debug("done");
break;
}
}
public Set<ClassSymbol> getClassSymbols() {
return classSymbols;
private void collectClassSymbols(JCCompilationUnit cu) {
for (Tree t : cu.getTypeDecls()) {
if (t instanceof JCClassDecl) // Can also be a JCSkip
classSymbols.add(((JCClassDecl) t).sym);
}
}
private void extractPubApis() {
// To handle incremental builds (subsequent sjavac invocations) we need
// to keep track of the public API of what we depend upon.
//
// During the recompilation loop (within a single sjavac invocation) we
// need to keep track of public API of what we're compiling to decide if
// any dependants needs to be tainted.
PubAPIs pubApis = PubAPIs.instance(context);
classSymbols.forEach(pubApis::visitPubapi);
}
public Map<String, PubApi> getPubApis(boolean explicit) {
return explicit ? explicitPubApis : nonExplicitPubApis;
}
}

View File

@ -1,75 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.comp.dependencies;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Type;
import static com.sun.tools.javac.code.Kinds.Kind.*;
public class TypeAndSupertypesDependency implements Dependency {
protected TypeSymbol type;
public TypeAndSupertypesDependency(TypeSymbol type) {
this.type = Objects.requireNonNull(type);
}
private Set<TypeSymbol> allSupertypes(TypeSymbol t) {
if (t == null)
return Collections.emptySet();
Set<TypeSymbol> result = new HashSet<>();
result.add(t);
if (t instanceof ClassSymbol) {
ClassSymbol cs = (ClassSymbol) t;
result.addAll(allSupertypes(cs.getSuperclass().tsym));
for (Type it : cs.getInterfaces())
result.addAll(allSupertypes(it.tsym));
}
return result;
}
@Override
public Set<PackageSymbol> getPackages() {
if (type.kind == ERR)
return Collections.emptySet();
if (type instanceof ClassSymbol) {
return allSupertypes(type).stream()
.map(TypeSymbol::packge)
.collect(Collectors.toSet());
}
throw new AssertionError("Could not get package name for " + type);
}
}

View File

@ -316,9 +316,19 @@ public class Options {
args.add(concatenateSourceLocations(classSearchPaths));
}
// Enable dependency generation
args.add("-XDcompletionDeps=source,class");
// This can't be anything but 'none'. Enforced by sjavac main method.
args.add("-implicit:" + implicitPolicy);
// If this option is not used, Object for instance is erroneously
// picked up from PLATFORM_CLASS_PATH instead of CLASS_PATH.
//
// Discussing this further led to the decision of letting bootclasspath
// be a dummy (empty) directory when building the JDK.
//args.add("-XXuserPathsFirst");
// Append javac-options (i.e. pass through options not recognized by
// sjavac to javac.)
args.addAll(javacArgs);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -22,20 +22,33 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.sjavac.comp.dependencies;
package com.sun.tools.sjavac.pubapi;
import java.util.Collections;
import java.util.Set;
import java.io.Serializable;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import javax.lang.model.type.TypeKind;
public class PackageDependency implements Dependency {
PackageSymbol ps;
public PackageDependency(PackageSymbol ps) {
this.ps = ps;
public class ArrayTypeDesc extends TypeDesc implements Serializable {
private static final long serialVersionUID = -1177329549163314996L;
TypeDesc compTypeDesc;
public ArrayTypeDesc(TypeDesc compTypeDesc) {
super(TypeKind.ARRAY);
this.compTypeDesc = compTypeDesc;
}
@Override
public Set<PackageSymbol> getPackages() {
return Collections.singleton(ps);
public boolean equals(Object obj) {
if (!super.equals(obj))
return false;
return compTypeDesc.equals(((ArrayTypeDesc) obj).compTypeDesc);
}
@Override
public int hashCode() {
return super.hashCode() ^ compTypeDesc.hashCode();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -22,9 +22,28 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package pkg13;
public class Cls13 {
public pkg14.Cls14 getCls14() {
return null;
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import javax.lang.model.type.TypeKind;
import com.sun.tools.javac.util.StringUtils;
public class PrimitiveTypeDesc extends TypeDesc implements Serializable {
private static final long serialVersionUID = 6051065543149129106L;
public PrimitiveTypeDesc(TypeKind typeKind) {
super(typeKind);
if (!typeKind.isPrimitive() && typeKind != TypeKind.VOID)
throw new IllegalArgumentException("Only primitives or void accepted");
}
// This class has no fields, so the inherited hashCode and equals should do fine.
@Override
public String toString() {
return StringUtils.toLowerCase(typeKind.toString());
}
}

View File

@ -0,0 +1,434 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.pubapi;
import static com.sun.tools.sjavac.Util.union;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.StringUtils;
public class PubApi implements Serializable {
private static final long serialVersionUID = 5926627347801986850L;
// Used to have Set here. Problem is that the objects are mutated during
// javac_state loading, causing them to change hash codes. We could probably
// change back to Set once javac_state loading is cleaned up.
public final Map<String, PubType> types = new HashMap<>();
public final Map<String, PubVar> variables = new HashMap<>();
public final Map<String, PubMethod> methods = new HashMap<>();
public PubApi() {
}
public PubApi(Collection<PubType> types,
Collection<PubVar> variables,
Collection<PubMethod> methods) {
types.forEach(this::addPubType);
variables.forEach(this::addPubVar);
methods.forEach(this::addPubMethod);
}
// Currently this is implemented as equality. This is far from optimal. It
// should preferably make sure that all previous methods are still available
// and no abstract methods are added. It should also be aware of inheritance
// of course.
public boolean isBackwardCompatibleWith(PubApi older) {
return equals(older);
}
private static String typeLine(PubType type) {
if (type.fqName.isEmpty())
throw new RuntimeException("empty class name " + type);
return String.format("TYPE %s%s", asString(type.modifiers), type.fqName);
}
private static String varLine(PubVar var) {
return String.format("VAR %s%s %s%s",
asString(var.modifiers),
TypeDesc.encodeAsString(var.type),
var.identifier,
var.getConstValue().map(v -> " = " + v).orElse(""));
}
private static String methodLine(PubMethod method) {
return String.format("METHOD %s%s%s %s(%s)%s",
asString(method.modifiers),
method.typeParams.isEmpty() ? "" : ("<" + method.typeParams.stream().map(PubApiTypeParam::asString).collect(Collectors.joining(",")) + "> "),
TypeDesc.encodeAsString(method.returnType),
method.identifier,
commaSeparated(method.paramTypes),
method.throwDecls.isEmpty()
? ""
: " throws " + commaSeparated(method.throwDecls));
}
public List<String> asListOfStrings() {
List<String> lines = new ArrayList<>();
// Types
types.values()
.stream()
.sorted(Comparator.comparing(PubApi::typeLine))
.forEach(type -> {
lines.add(typeLine(type));
for (String subline : type.pubApi.asListOfStrings())
lines.add(" " + subline);
});
// Variables
variables.values()
.stream()
.map(PubApi::varLine)
.sorted()
.forEach(lines::add);
// Methods
methods.values()
.stream()
.map(PubApi::methodLine)
.sorted()
.forEach(lines::add);
return lines;
}
@Override
public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
PubApi other = (PubApi) obj;
return types.equals(other.types)
&& variables.equals(other.variables)
&& methods.equals(other.methods);
}
@Override
public int hashCode() {
return types.keySet().hashCode()
^ variables.keySet().hashCode()
^ methods.keySet().hashCode();
}
private static String commaSeparated(List<TypeDesc> typeDescs) {
return typeDescs.stream()
.map(TypeDesc::encodeAsString)
.collect(Collectors.joining(","));
}
// Create space separated list of modifiers (with a trailing space)
private static String asString(Set<Modifier> modifiers) {
return modifiers.stream()
.map(mod -> mod + " ")
.sorted()
.collect(Collectors.joining());
}
// Used to combine class PubApis to package level PubApis
public static PubApi mergeTypes(PubApi api1, PubApi api2) {
Assert.check(api1.methods.isEmpty(), "Can only merge types.");
Assert.check(api2.methods.isEmpty(), "Can only merge types.");
Assert.check(api1.variables.isEmpty(), "Can only merge types.");
Assert.check(api2.variables.isEmpty(), "Can only merge types.");
PubApi merged = new PubApi();
merged.types.putAll(api1.types);
merged.types.putAll(api2.types);
return merged;
}
// Used for line-by-line parsing
private PubType lastInsertedType = null;
private final static String MODIFIERS = Stream.of(Modifier.values())
.map(Modifier::name)
.map(StringUtils::toLowerCase)
.collect(Collectors.joining("|", "(", ")"));
private final static Pattern MOD_PATTERN = Pattern.compile("(" + MODIFIERS + " )*");
private final static Pattern METHOD_PATTERN = Pattern.compile("(?<ret>.+?) (?<name>\\S+)\\((?<params>.*)\\)( throws (?<throws>.*))?");
private final static Pattern VAR_PATTERN = Pattern.compile("VAR (?<modifiers>("+MODIFIERS+" )*)(?<type>.+?) (?<id>\\S+)( = (?<val>.*))?");
private final static Pattern TYPE_PATTERN = Pattern.compile("TYPE (?<modifiers>("+MODIFIERS+" )*)(?<fullyQualified>\\S+)");
public void appendItem(String l) {
try {
if (l.startsWith(" ")) {
lastInsertedType.pubApi.appendItem(l.substring(2));
return;
}
if (l.startsWith("METHOD")) {
l = l.substring("METHOD ".length());
Set<Modifier> modifiers = new HashSet<>();
Matcher modMatcher = MOD_PATTERN.matcher(l);
if (modMatcher.find()) {
String modifiersStr = modMatcher.group();
modifiers.addAll(parseModifiers(modifiersStr));
l = l.substring(modifiersStr.length());
}
List<PubApiTypeParam> typeParams = new ArrayList<>();
if (l.startsWith("<")) {
int closingPos = findClosingTag(l, 0);
String str = l.substring(1, closingPos);
l = l.substring(closingPos+1);
typeParams.addAll(parseTypeParams(splitOnTopLevelCommas(str)));
}
Matcher mm = METHOD_PATTERN.matcher(l);
if (!mm.matches())
throw new AssertionError("Could not parse return type, identifier, parameter types or throws declaration of method: " + l);
List<String> params = splitOnTopLevelCommas(mm.group("params"));
String th = Optional.ofNullable(mm.group("throws")).orElse("");
List<String> throwz = splitOnTopLevelCommas(th);
PubMethod m = new PubMethod(modifiers,
typeParams,
TypeDesc.decodeString(mm.group("ret")),
mm.group("name"),
parseTypeDescs(params),
parseTypeDescs(throwz));
addPubMethod(m);
return;
}
Matcher vm = VAR_PATTERN.matcher(l);
if (vm.matches()) {
addPubVar(new PubVar(parseModifiers(vm.group("modifiers")),
TypeDesc.decodeString(vm.group("type")),
vm.group("id"),
vm.group("val")));
return;
}
Matcher tm = TYPE_PATTERN.matcher(l);
if (tm.matches()) {
addPubType(new PubType(parseModifiers(tm.group("modifiers")),
tm.group("fullyQualified"),
new PubApi()));
return;
}
throw new AssertionError("No matching line pattern.");
} catch (Throwable e) {
throw new AssertionError("Could not parse API line: " + l, e);
}
}
public void addPubType(PubType t) {
types.put(t.fqName, t);
lastInsertedType = t;
}
public void addPubVar(PubVar v) {
variables.put(v.identifier, v);
}
public void addPubMethod(PubMethod m) {
methods.put(m.asSignatureString(), m);
}
private static List<TypeDesc> parseTypeDescs(List<String> strs) {
return strs.stream()
.map(TypeDesc::decodeString)
.collect(Collectors.toList());
}
private static List<PubApiTypeParam> parseTypeParams(List<String> strs) {
return strs.stream().map(PubApi::parseTypeParam).collect(Collectors.toList());
}
// Parse a type parameter string. Example input:
// identifier
// identifier extends Type (& Type)*
private static PubApiTypeParam parseTypeParam(String typeParamString) {
int extPos = typeParamString.indexOf(" extends ");
if (extPos == -1)
return new PubApiTypeParam(typeParamString, Collections.emptyList());
String identifier = typeParamString.substring(0, extPos);
String rest = typeParamString.substring(extPos + " extends ".length());
List<TypeDesc> bounds = parseTypeDescs(splitOnTopLevelChars(rest, '&'));
return new PubApiTypeParam(identifier, bounds);
}
public Set<Modifier> parseModifiers(String modifiers) {
if (modifiers == null)
return Collections.emptySet();
return Stream.of(modifiers.split(" "))
.map(String::trim)
.map(StringUtils::toUpperCase)
.filter(s -> !s.isEmpty())
.map(Modifier::valueOf)
.collect(Collectors.toSet());
}
// Find closing tag of the opening tag at the given 'pos'.
private static int findClosingTag(String l, int pos) {
while (true) {
pos = pos + 1;
if (l.charAt(pos) == '>')
return pos;
if (l.charAt(pos) == '<')
pos = findClosingTag(l, pos);
}
}
public List<String> splitOnTopLevelCommas(String s) {
return splitOnTopLevelChars(s, ',');
}
public static List<String> splitOnTopLevelChars(String s, char split) {
if (s.isEmpty())
return Collections.emptyList();
List<String> result = new ArrayList<>();
StringBuilder buf = new StringBuilder();
int depth = 0;
for (char c : s.toCharArray()) {
if (c == split && depth == 0) {
result.add(buf.toString().trim());
buf = new StringBuilder();
} else {
if (c == '<') depth++;
if (c == '>') depth--;
buf.append(c);
}
}
result.add(buf.toString().trim());
return result;
}
public boolean isEmpty() {
return types.isEmpty() && variables.isEmpty() && methods.isEmpty();
}
// Used for descriptive debug messages when figuring out what triggers
// recompilation.
public List<String> diff(PubApi prevApi) {
return diff("", prevApi);
}
private List<String> diff(String scopePrefix, PubApi prevApi) {
List<String> diffs = new ArrayList<>();
for (String typeKey : union(types.keySet(), prevApi.types.keySet())) {
PubType type = types.get(typeKey);
PubType prevType = prevApi.types.get(typeKey);
if (prevType == null) {
diffs.add("Type " + scopePrefix + typeKey + " was added");
} else if (type == null) {
diffs.add("Type " + scopePrefix + typeKey + " was removed");
} else {
// Check modifiers
if (!type.modifiers.equals(prevType.modifiers)) {
diffs.add("Modifiers for type " + scopePrefix + typeKey
+ " changed from " + prevType.modifiers + " to "
+ type.modifiers);
}
// Recursively check types pub API
diffs.addAll(type.pubApi.diff(prevType.pubApi));
}
}
for (String varKey : union(variables.keySet(), prevApi.variables.keySet())) {
PubVar var = variables.get(varKey);
PubVar prevVar = prevApi.variables.get(varKey);
if (prevVar == null) {
diffs.add("Variable " + scopePrefix + varKey + " was added");
} else if (var == null) {
diffs.add("Variable " + scopePrefix + varKey + " was removed");
} else {
if (!var.modifiers.equals(prevVar.modifiers)) {
diffs.add("Modifiers for var " + scopePrefix + varKey
+ " changed from " + prevVar.modifiers + " to "
+ var.modifiers);
}
if (!var.type.equals(prevVar.type)) {
diffs.add("Type of " + scopePrefix + varKey
+ " changed from " + prevVar.type + " to "
+ var.type);
}
if (!var.getConstValue().equals(prevVar.getConstValue())) {
diffs.add("Const value of " + scopePrefix + varKey
+ " changed from " + prevVar.getConstValue().orElse("<none>")
+ " to " + var.getConstValue().orElse("<none>"));
}
}
}
for (String methodKey : union(methods.keySet(), prevApi.methods.keySet())) {
PubMethod method = methods.get(methodKey);
PubMethod prevMethod = prevApi.methods.get(methodKey);
if (prevMethod == null) {
diffs.add("Method " + scopePrefix + methodKey + " was added");
} else if (method == null) {
diffs.add("Method " + scopePrefix + methodKey + " was removed");
} else {
if (!method.modifiers.equals(prevMethod.modifiers)) {
diffs.add("Modifiers for method " + scopePrefix + methodKey
+ " changed from " + prevMethod.modifiers + " to "
+ method.modifiers);
}
if (!method.typeParams.equals(prevMethod.typeParams)) {
diffs.add("Type parameters for method " + scopePrefix
+ methodKey + " changed from " + prevMethod.typeParams
+ " to " + method.typeParams);
}
if (!method.throwDecls.equals(prevMethod.throwDecls)) {
diffs.add("Throw decl for method " + scopePrefix + methodKey
+ " changed from " + prevMethod.throwDecls + " to "
+ " to " + method.throwDecls);
}
}
}
return diffs;
}
public String toString() {
return String.format("%s[types: %s, variables: %s, methods: %s]",
getClass().getSimpleName(),
types.values(),
variables.values(),
methods.values());
}
}

View File

@ -0,0 +1,49 @@
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
public class PubApiTypeParam implements Serializable {
private static final long serialVersionUID = 8899204612014329162L;
private final String identifier;
private final List<TypeDesc> bounds;
public PubApiTypeParam(String identifier, List<TypeDesc> bounds) {
this.identifier = identifier;
this.bounds = bounds;
}
@Override
public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
PubApiTypeParam other = (PubApiTypeParam) obj;
return identifier.equals(other.identifier)
&& bounds.equals(other.bounds);
}
@Override
public int hashCode() {
return identifier.hashCode() ^ bounds.hashCode();
}
public String asString() {
if (bounds.isEmpty())
return identifier;
String boundsStr = bounds.stream()
.map(TypeDesc::encodeAsString)
.collect(Collectors.joining(" & "));
return identifier + " extends " + boundsStr;
}
@Override
public String toString() {
return String.format("%s[id: %s, bounds: %s]",
getClass().getSimpleName(),
identifier,
bounds);
}
}

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.element.Modifier;
public class PubMethod implements Serializable {
private static final long serialVersionUID = -7813050194553446243L;
Set<Modifier> modifiers;
List<PubApiTypeParam> typeParams;
TypeDesc returnType;
String identifier;
List<TypeDesc> paramTypes;
List<TypeDesc> throwDecls;
public PubMethod(Set<Modifier> modifiers,
List<PubApiTypeParam> typeParams,
TypeDesc returnType,
String identifier,
List<TypeDesc> paramTypes,
List<TypeDesc> throwDecls) {
this.modifiers = modifiers;
this.typeParams = typeParams;
this.returnType = returnType;
this.identifier = identifier;
this.paramTypes = paramTypes;
this.throwDecls = throwDecls;
}
// We need to include return type and type parameters to be sure to have
// different values for different methods. (A method can be overloaded with
// the only difference being the upper bound of the return type.)
public String asSignatureString() {
StringBuilder sb = new StringBuilder();
// <A extends String, Serializable, B extends List>
if (typeParams.size() > 0) {
sb.append(typeParams.stream()
.map(PubApiTypeParam::asString)
.collect(Collectors.joining(",", "<", "> ")));
}
sb.append(TypeDesc.encodeAsString(returnType));
sb.append(" ");
sb.append(identifier);
sb.append("(");
sb.append(paramTypes.stream()
.map(TypeDesc::encodeAsString)
.collect(Collectors.joining(",")));
sb.append(")");
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
PubMethod other = (PubMethod) obj;
return modifiers.equals(other.modifiers)
&& typeParams.equals(other.typeParams)
&& returnType.equals(other.returnType)
&& identifier.equals(other.identifier)
&& paramTypes.equals(other.paramTypes)
&& throwDecls.equals(other.throwDecls);
}
@Override
public int hashCode() {
return modifiers.hashCode()
^ typeParams.hashCode()
^ returnType.hashCode()
^ identifier.hashCode()
^ paramTypes.hashCode()
^ throwDecls.hashCode();
}
public String toString() {
return String.format("%s[modifiers: %s, typeParams: %s, retType: %s, identifier: %s, params: %s, throws: %s]",
getClass().getSimpleName(),
modifiers,
typeParams,
returnType,
identifier,
paramTypes,
throwDecls);
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import java.util.Set;
import javax.lang.model.element.Modifier;
public class PubType implements Serializable {
private static final long serialVersionUID = -7423416049253889793L;
public final Set<Modifier> modifiers;
public final String fqName;
public final PubApi pubApi;
public PubType(Set<Modifier> modifiers,
String fqName,
PubApi pubApi) {
this.modifiers = modifiers;
this.fqName = fqName;
this.pubApi = pubApi;
}
public String getFqName() {
return fqName.toString();
}
@Override
public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
PubType other = (PubType) obj;
return modifiers.equals(other.modifiers)
&& fqName.equals(other.fqName)
&& pubApi.equals(other.pubApi);
}
@Override
public int hashCode() {
return modifiers.hashCode() ^ fqName.hashCode() ^ pubApi.hashCode();
}
@Override
public String toString() {
return String.format("%s[modifiers: %s, fqName: %s, pubApi: %s]",
getClass().getSimpleName(),
modifiers,
fqName,
pubApi);
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import java.util.Optional;
import java.util.Set;
import javax.lang.model.element.Modifier;
public class PubVar implements Serializable {
private static final long serialVersionUID = 5806536061153374575L;
public final Set<Modifier> modifiers;
public final TypeDesc type;
public final String identifier;
private final String constValue;
public PubVar(Set<Modifier> modifiers,
TypeDesc type,
String identifier,
String constValue) {
this.modifiers = modifiers;
this.type = type;
this.identifier = identifier;
this.constValue = constValue;
}
public String getIdentifier() {
return identifier;
}
@Override
public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
PubVar other = (PubVar) obj;
return modifiers.equals(other.modifiers)
&& type.equals(other.type)
&& identifier.equals(other.identifier)
&& getConstValue().equals(other.getConstValue());
}
@Override
public int hashCode() {
return modifiers.hashCode()
^ type.hashCode()
^ identifier.hashCode()
^ getConstValue().hashCode();
}
public String toString() {
return String.format("%s[modifiers: %s, type: %s, identifier: %s, constValue: %s]",
getClass().getSimpleName(),
modifiers,
type,
identifier,
constValue);
}
public Optional<String> getConstValue() {
return Optional.ofNullable(constValue);
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import javax.lang.model.type.TypeKind;
public class ReferenceTypeDesc extends TypeDesc implements Serializable {
private static final long serialVersionUID = 3357616754544796372L;
// Example: "java.util.Vector<java.lang.String>"
String javaType;
public ReferenceTypeDesc(String javaType) {
super(TypeKind.DECLARED);
this.javaType = javaType;
}
@Override
public boolean equals(Object obj) {
if (!super.equals(obj))
return false;
return javaType.equals(((ReferenceTypeDesc) obj).javaType);
}
@Override
public int hashCode() {
return super.hashCode() ^ javaType.hashCode();
}
@Override
public String toString() {
return String.format("%s[type: %s]", getClass().getSimpleName(), javaType);
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ErrorType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.SimpleTypeVisitor9;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.StringUtils;
public abstract class TypeDesc implements Serializable {
private static final long serialVersionUID = -8201634143915519172L;
TypeKind typeKind;
public TypeDesc(TypeKind typeKind) {
this.typeKind = typeKind;
}
public static TypeDesc decodeString(String s) {
s = s.trim();
if (s.endsWith("[]")) {
String componentPart = s.substring(0, s.length()-2);
return new ArrayTypeDesc(decodeString(componentPart));
}
if (s.startsWith("#"))
return new TypeVarTypeDesc(s.substring(1));
if (s.matches("boolean|byte|char|double|float|int|long|short|void")) {
TypeKind tk = TypeKind.valueOf(StringUtils.toUpperCase(s));
return new PrimitiveTypeDesc(tk);
}
return new ReferenceTypeDesc(s);
}
public static String encodeAsString(TypeDesc td) {
if (td.typeKind.isPrimitive() || td.typeKind == TypeKind.VOID)
return StringUtils.toLowerCase(td.typeKind.toString());
if (td.typeKind == TypeKind.ARRAY)
return encodeAsString(((ArrayTypeDesc) td).compTypeDesc) + "[]";
if (td.typeKind == TypeKind.TYPEVAR)
return "#" + ((TypeVarTypeDesc) td).identifier;
if (td.typeKind == TypeKind.DECLARED)
return ((ReferenceTypeDesc) td).javaType.toString();
throw new AssertionError("Unhandled type: " + td.typeKind);
}
public static TypeDesc fromType(TypeMirror type) {
TypeVisitor<TypeDesc, Void> v = new SimpleTypeVisitor9<TypeDesc, Void>() {
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeDesc visitArray(ArrayType t, Void p) {
return new ArrayTypeDesc(t.getComponentType().accept(this, p));
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeDesc visitDeclared(DeclaredType t, Void p) {
return new ReferenceTypeDesc(((ClassType) t).tsym.flatName().toString());
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeDesc visitNoType(NoType t, Void p) {
return new PrimitiveTypeDesc(TypeKind.VOID);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeDesc visitTypeVariable(TypeVariable t, Void p) {
return new TypeVarTypeDesc(t.toString());
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeDesc visitPrimitive(PrimitiveType t, Void p) {
return new PrimitiveTypeDesc(t.getKind());
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeDesc visitError(ErrorType t, Void p) {
return new ReferenceTypeDesc("<error type>");
}
};
TypeDesc td = v.visit(type);
if (td == null)
throw new AssertionError("Unhandled type mirror: " + type + " (" + type.getClass() + ")");
return td;
}
@Override
public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
return typeKind.equals(((TypeDesc) obj).typeKind);
}
@Override
public int hashCode() {
return typeKind.hashCode();
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.tools.sjavac.pubapi;
import java.io.Serializable;
import javax.lang.model.type.TypeKind;
public class TypeVarTypeDesc extends TypeDesc implements Serializable {
private static final long serialVersionUID = 3357616754544796373L;
String identifier; // Example: "T"
public TypeVarTypeDesc(String identifier) {
super(TypeKind.TYPEVAR);
this.identifier = identifier;
}
@Override
public boolean equals(Object obj) {
if (!super.equals(obj))
return false;
return identifier.equals(((TypeVarTypeDesc) obj).identifier);
}
@Override
public int hashCode() {
return super.hashCode() ^ identifier.hashCode();
}
@Override
public String toString() {
return String.format("%s[identifier: %s]",
getClass().getSimpleName(),
identifier);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -31,6 +31,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.sun.tools.sjavac.pubapi.PubApi;
/**
*
* <p><b>This is NOT part of any supported API.
@ -47,8 +49,10 @@ public class CompilationResult implements Serializable {
public int returnCode;
public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
public Map<String, Set<String>> packageDependencies = new HashMap<>();
public Map<String, String> packagePubapis = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageDependencies = new HashMap<>();
public Map<String, Map<String, Set<String>>> packageCpDependencies = new HashMap<>();
public Map<String, PubApi> packagePubapis = new HashMap<>();
public Map<String, PubApi> dependencyPubapis = new HashMap<>();
public String stdout = "";
public String stderr = "";

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -27,6 +27,8 @@ package com.sun.tools.sjavac.server;
import java.io.IOException;
import com.sun.tools.sjavac.Log;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@ -36,6 +38,8 @@ import java.io.IOException;
public class ServerMain {
public static int run(String[] args) {
Log.initializeLog(System.out, System.err);
// Any options other than --startserver?
if (args.length > 1) {
System.err.println("When spawning a background server, only a single --startserver argument is allowed.");

View File

@ -1,12 +1,10 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* 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
@ -22,9 +20,34 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package pkg10;
public class Cls10 {
public pkg13.Cls13 getCls13() {
return null;
/*
* @test
* @bug 8081521
* @summary Ensure that anonymous class construction using <> can be nested within another
* @compile NestedDiamondAllocationTest.java
* @run main NestedDiamondAllocationTest
*
*/
public class NestedDiamondAllocationTest {
static class Clazz2 {
static class A {
};
public A a;
}
static class FooNest<Q> {
FooNest(Q q, Foo<Q> foo) {
}
}
static class Foo<T> {
}
static Clazz2 clazz = new Clazz2();
public static void main(String [] args) {
FooNest fooNest = new FooNest<>(clazz.a, new Foo<>() {
});
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2015, 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 8082311
* @summary Verify that bitwise operators don't allow to mix numeric and boolean operands.
* @library ../lib
*/
import com.sun.tools.javac.util.StringUtils;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
public class BitWiseOperators extends JavacTestingAbstractThreadedTest {
public static void main(String... args) {
new BitWiseOperators().run();
}
void run() {
for (TYPE type1 : TYPE.values()) {
for (OPERATION op : OPERATION.values()) {
for (TYPE type2 : TYPE.values()) {
runTest(type1, op, type2);
}
}
}
}
void runTest(TYPE type1, OPERATION op, TYPE type2) {
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
List<JavaSource> files = Arrays.asList(new JavaSource(type1, op, type2));
comp.getTask(null, null, dc, null, null, files).call();
if (dc.getDiagnostics().isEmpty() ^ TYPE.compatible(type1, type2)) {
throw new AssertionError("Unexpected behavior. Type1: " + type1 +
"; type2: " + type2 +
"; diagnostics: " + dc.getDiagnostics());
}
}
enum TYPE {
BYTE,
CHAR,
SHORT,
INT,
LONG,
BOOLEAN;
public static boolean compatible(TYPE op1, TYPE op2) {
return !(op1 == BOOLEAN ^ op2 == BOOLEAN);
}
}
enum OPERATION {
BITAND("&"),
BITOR("|"),
BITXOR("^");
String op;
private OPERATION(String op) {
this.op = op;
}
}
class JavaSource extends SimpleJavaFileObject {
String template = "class Test {\n" +
" public Object test(#TYPE1 var1, #TYPE2 var2) {\n" +
" return var1 #OP var2;\n" +
" }\n" +
"}";
String source;
public JavaSource(TYPE type1, OPERATION op, TYPE type2) {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
source = template.replaceAll("#TYPE1", StringUtils.toLowerCase(type1.name()))
.replaceAll("#OP", StringUtils.toLowerCase(op.op))
.replaceAll("#TYPE2", StringUtils.toLowerCase(type2.name()));
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
}
}

View File

@ -0,0 +1,214 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8054717
* @summary Make sure extraction of non-private APIs work as expected.
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.sjavac
* @build Wrapper ToolBox
* @run main Wrapper ApiExtraction
*/
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PROTECTED;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.lang.model.type.TypeKind;
import com.sun.tools.sjavac.PubApiExtractor;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.pubapi.PrimitiveTypeDesc;
import com.sun.tools.sjavac.pubapi.PubApi;
import com.sun.tools.sjavac.pubapi.PubMethod;
import com.sun.tools.sjavac.pubapi.PubType;
import com.sun.tools.sjavac.pubapi.PubVar;
import com.sun.tools.sjavac.pubapi.ReferenceTypeDesc;
public class ApiExtraction {
public static void main(String[] args) throws IOException {
String testSrc = String.join("\n",
"import java.util.*;",
"public final class TestClass extends Thread {",
// Fields with various combination of modifiers
" private String s1 = \"str 1\";",
" public String s2 = \"str 2\";",
" protected final String s3 = \"str 3\";",
" static String s4 = \"str 4\";",
// Methods with various combinations of types and modifiers
" protected void m1() {}",
" public static Map<Integer, List<String>> m2() {",
" return null;",
" }",
" final void m3(Set<Map<Integer, Map<String, String>>> s) {}",
// Some inner classes
" static class DummyInner1 implements Runnable {",
" protected int field;",
" public void run() {}",
" }",
" final class DummyInner2 { }",
"}");
// Create class file to extract API from
new ToolBox().new JavacTask().sources(testSrc).run();
// Extract PubApi
Options options = Options.parseArgs("-d", "bin", "-cp", ".");
PubApiExtractor pubApiExtr = new PubApiExtractor(options);
PubApi actualApi = pubApiExtr.getPubApi("TestClass");
// Validate result
PubApi expectedApi = getExpectedPubApi();
if (!expectedApi.equals(actualApi)) {
List<String> diffs = expectedApi.diff(actualApi);
System.out.println(diffs.size() + " differences found.");
for (String diff : diffs) {
System.out.println(diff);
}
throw new AssertionError("Actual API differs from expected API.");
}
}
private static PubApi getExpectedPubApi() {
ReferenceTypeDesc string = new ReferenceTypeDesc("java.lang.String");
// Fields
// (s1 is private and therefore not included)
PubVar s2 = new PubVar(setOf(PUBLIC), string, "s2", null);
PubVar s4 = new PubVar(setOf(STATIC), string, "s4", null);
PubVar s3 = new PubVar(setOf(PROTECTED, FINAL), string, "s3",
"\"\\u0073\\u0074\\u0072\\u0020\\u0033\"");
// Methods
PubMethod init = new PubMethod(setOf(PUBLIC),
emptyList(),
new PrimitiveTypeDesc(TypeKind.VOID),
"<init>",
emptyList(),
emptyList());
PubMethod clinit = new PubMethod(setOf(STATIC),
emptyList(),
new PrimitiveTypeDesc(TypeKind.VOID),
"<clinit>",
emptyList(),
emptyList());
PubMethod m1 = new PubMethod(setOf(PROTECTED),
emptyList(),
new PrimitiveTypeDesc(TypeKind.VOID),
"m1",
emptyList(),
emptyList());
PubMethod m2 = new PubMethod(setOf(PUBLIC, STATIC),
emptyList(),
new ReferenceTypeDesc("java.util.Map"),
"m2",
emptyList(),
emptyList());
PubMethod m3 = new PubMethod(setOf(FINAL),
emptyList(),
new PrimitiveTypeDesc(TypeKind.VOID),
"m3",
asList(new ReferenceTypeDesc("java.util.Set")),
emptyList());
// Complete class
PubType testClass = new PubType(setOf(PUBLIC, FINAL),
"TestClass",
new PubApi(asList(getDummyInner1(), getDummyInner2()),
asList(s2, s3, s4),
asList(init, clinit, m1, m2, m3)));
// Wrap in "package level" PubApi
return new PubApi(asList(testClass), emptyList(), emptyList());
}
private static PubType getDummyInner1() {
PubMethod init = new PubMethod(setOf(),
emptyList(),
new PrimitiveTypeDesc(TypeKind.VOID),
"<init>",
emptyList(),
emptyList());
PubMethod run = new PubMethod(setOf(PUBLIC),
emptyList(),
new PrimitiveTypeDesc(TypeKind.VOID),
"run",
emptyList(),
emptyList());
PubVar field = new PubVar(setOf(PROTECTED),
new PrimitiveTypeDesc(TypeKind.INT),
"field",
null);
return new PubType(setOf(STATIC),
"TestClass$DummyInner1",
new PubApi(emptyList(),
asList(field),
asList(init, run)));
}
private static PubType getDummyInner2() {
PubMethod init = new PubMethod(setOf(),
emptyList(),
new PrimitiveTypeDesc(TypeKind.VOID),
"<init>",
emptyList(),
emptyList());
return new PubType(setOf(FINAL),
"TestClass$DummyInner2",
new PubApi(emptyList(),
emptyList(),
asList(init)));
}
@SafeVarargs
private static <T> Set<T> setOf(T... elements) {
return new HashSet<>(asList(elements));
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8054717
* @summary Make sure changes of public API on classpath triggers recompilation
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.sjavac
* @build Wrapper ToolBox
* @run main Wrapper ClasspathDependencies
*/
import static com.sun.tools.javac.util.Assert.check;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
public class ClasspathDependencies extends SjavacBase {
static final String server = "--server:portfile=testserver,background=false";
public static void main(String... args) throws Exception {
Path root = Paths.get(ClasspathDependencies.class.getSimpleName() + "Test");
delete(root);
Path src = root.resolve("src");
Path classes = root.resolve("classes");
Path srcDep = root.resolve("srcDep");
Path classesDep = root.resolve("classesDep");
////////////////////////////////////////////////////////////////////////
headline("Create a test dependency, Dep.class, and put it in the classpath dir");
String depCode = "package dep; public class Dep { public void m1() {} }";
toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
int rc = compile(server, "-d", classesDep, srcDep);
check(rc == 0, "Compilation failed unexpectedly");
////////////////////////////////////////////////////////////////////////
headline("Compile and link against the Dep.class");
toolbox.writeFile(src.resolve("pkg/C.java"),
"package pkg;" +
"import dep.Dep;" +
"public class C { Dep dep; public void m() { new Dep().m1(); } }");
rc = compile(server, "-d", classes, src, "-cp", classesDep);
check(rc == 0, "Compilation failed unexpectedly");
FileTime modTime1 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
////////////////////////////////////////////////////////////////////////
headline("Update dependency (without changing the public api)");
Thread.sleep(2000);
depCode = depCode.replaceAll("}$", "private void m2() {} }");
toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
rc = compile(server, "-d", classesDep, srcDep);
check(rc == 0, "Compilation failed unexpectedly");
////////////////////////////////////////////////////////////////////////
headline("Make sure that this does not trigger recompilation of C.java");
rc = compile(server, "-d", classes, src, "-cp", classesDep);
check(rc == 0, "Compilation failed unexpectedly");
FileTime modTime2 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
check(modTime1.equals(modTime2), "Recompilation erroneously triggered");
////////////////////////////////////////////////////////////////////////
headline("Update public API of dependency");
Thread.sleep(2000);
depCode = depCode.replace("m1()", "m1(String... arg)");
toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
rc = compile(server, "-d", classesDep, srcDep);
check(rc == 0, "Compilation failed unexpectedly");
////////////////////////////////////////////////////////////////////////
headline("Make sure that recompilation of C.java is triggered");
rc = compile(server, "-d", classes, src, "-cp", classesDep);
check(rc == 0, "Compilation failed unexpectedly");
FileTime modTime3 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
check(modTime2.compareTo(modTime3) < 0, "Recompilation not triggered");
}
static void headline(String str) {
System.out.println();
System.out.println(str);
System.out.println(str.replaceAll(".", "-"));
}
static void delete(Path root) throws IOException {
if (!Files.exists(root))
return;
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path f, BasicFileAttributes a)
throws IOException {
Files.delete(f);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException e)
throws IOException {
if (e != null)
throw e;
if (!dir.equals(root))
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
}

View File

@ -48,27 +48,33 @@ public class CompileCircularSources extends SJavacTester {
}
void test() throws Exception {
Files.createDirectory(BIN);
clean(TEST_ROOT);
Files.createDirectories(BIN);
clean(GENSRC, BIN);
Map<String,Long> previous_bin_state = collectState(BIN);
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; public class A { beta.B b; }");
"package alfa.omega; public class A { beta.B b; }");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; public class B { gamma.C c; }");
"package beta; public class B { gamma.C c; }");
tb.writeFile(GENSRC.resolve("gamma/C.java"),
"package gamma; public class C { alfa.omega.A a; }");
"package gamma; public class C { alfa.omega.A a; }");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3",
SERVER_ARG,"--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "3",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class",
"bin/beta/B.class",
"bin/gamma/C.class",
"bin/javac_state");
verifyThatFilesHaveBeenAdded(previous_bin_state,
new_bin_state,
BIN + "/alfa/omega/A.class",
BIN + "/beta/B.class",
BIN + "/gamma/C.class",
BIN + "/javac_state");
clean(GENSRC, BIN);
}
}

View File

@ -49,22 +49,27 @@ public class CompileExcludingDependency extends SJavacTester {
// Verify that excluding classes from compilation but not from linking works
void test() throws Exception {
Files.createDirectory(BIN);
clean(TEST_ROOT);
Files.createDirectories(BIN);
clean(GENSRC,BIN);
Map<String,Long> previous_bin_state = collectState(BIN);
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; public class A { beta.B b; }");
"package alfa.omega; public class A { beta.B b; }");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; public class B { }");
"package beta; public class B { }");
compile("-x", "beta", "-src", "gensrc", "-x", "alfa/omega", "-sourcepath", "gensrc",
"-d", "bin", SERVER_ARG);
compile("-x", "beta",
"-src", GENSRC.toString(),
"-x", "alfa/omega",
"-sourcepath", GENSRC.toString(),
"-d", BIN.toString(),
SERVER_ARG);
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class",
"bin/javac_state");
BIN + "/alfa/omega/A.class",
BIN + "/javac_state");
clean(GENSRC, BIN);
}
}

View File

@ -48,9 +48,13 @@ public class CompileWithAtFile extends SJavacTester {
}
void test() throws Exception {
clean(TEST_ROOT);
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("list.txt"),
"-if */alfa/omega/A.java\n-if */beta/B.java\ngensrc\n-d bin\n");
"-if */alfa/omega/A.java\n" +
"-if */beta/B.java\n" +
GENSRC + "\n" +
"-d " + BIN + "\n");
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; import beta.B; public class A { B b; }");
tb.writeFile(GENSRC.resolve("beta/B.java"),
@ -60,13 +64,14 @@ public class CompileWithAtFile extends SJavacTester {
Files.createDirectory(BIN);
Map<String,Long> previous_bin_state = collectState(BIN);
compile("@gensrc/list.txt", "--server:portfile=testserver,background=false");
compile("@" + GENSRC + "/list.txt", "--server:portfile=testserver,background=false");
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/javac_state",
"bin/alfa/omega/A.class",
"bin/beta/B.class");
BIN + "/javac_state",
BIN + "/alfa/omega/A.class",
BIN + "/beta/B.class");
clean(GENSRC, BIN);
}
}

View File

@ -51,35 +51,45 @@ public class CompileWithInvisibleSources extends SJavacTester {
// gensrc2 contains broken code in beta.B, thus exclude that package
// gensrc3 contains a proper beta.B
void test() throws Exception {
Files.createDirectory(BIN);
clean(TEST_ROOT);
Files.createDirectories(BIN);
clean(GENSRC, GENSRC2, GENSRC3, BIN);
Map<String,Long> previous_bin_state = collectState(BIN);
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
"package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
tb.writeFile(GENSRC2.resolve("beta/B.java"),
"package beta; public class B { broken");
"package beta; public class B { broken");
tb.writeFile(GENSRC2.resolve("gamma/C.java"),
"package gamma; public class C { }");
"package gamma; public class C { }");
tb.writeFile(GENSRC3.resolve("beta/B.java"),
"package beta; public class B { }");
"package beta; public class B { }");
compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2",
"-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1",
compile(GENSRC.toString(),
"-x", "beta",
"-sourcepath", GENSRC2.toString(),
"-sourcepath", GENSRC3.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG);
System.out.println("The first compile went well!");
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class",
"bin/javac_state");
BIN + "/alfa/omega/A.class",
BIN + "/javac_state");
System.out.println("----- Compile with exluded beta went well!");
clean(BIN);
compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3",
"-d", "bin", "-h", "headers", "-j", "1",
compileExpectFailure(GENSRC.toString(),
"-sourcepath", GENSRC2.toString(),
"-sourcepath", GENSRC3.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG);
System.out.println("----- Compile without exluded beta failed, as expected! Good!");

View File

@ -50,33 +50,43 @@ public class CompileWithOverrideSources extends SJavacTester {
// Compile gensrc and gensrc2. However do not compile broken beta.B in gensrc,
// only compile ok beta.B in gensrc2
void test() throws Exception {
Files.createDirectory(BIN);
clean(TEST_ROOT);
Files.createDirectories(BIN);
clean(GENSRC, GENSRC2, GENSRC3, BIN);
Map<String,Long> previous_bin_state = collectState(BIN);
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
"package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; public class B { broken");
"package beta; public class B { broken");
tb.writeFile(GENSRC.resolve("gamma/C.java"),
"package gamma; public class C { }");
"package gamma; public class C { }");
tb.writeFile(GENSRC2.resolve("beta/B.java"),
"package beta; public class B { }");
"package beta; public class B { }");
compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
compile("-x", "beta",
GENSRC.toString(),
GENSRC2.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG);
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class",
"bin/beta/B.class",
"bin/gamma/C.class",
"bin/javac_state");
BIN + "/alfa/omega/A.class",
BIN + "/beta/B.class",
BIN + "/gamma/C.class",
BIN + "/javac_state");
System.out.println("----- Compile with exluded beta went well!");
clean(BIN);
compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
compileExpectFailure(GENSRC.toString(),
GENSRC2.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG);
System.out.println("----- Compile without exluded beta failed, as expected! Good!");

View File

@ -1,139 +0,0 @@
/*
* Copyright (c) 2014, 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8056258 8048609
* @summary Ensures that the DependencyCollector covers various cases.
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util
* jdk.compiler/com.sun.tools.sjavac.comp
* jdk.compiler/com.sun.tools.sjavac.comp.dependencies
* @build Wrapper ToolBox
* @run main Wrapper DependencyCollection
*/
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.sjavac.comp.SmartFileManager;
import com.sun.tools.sjavac.comp.dependencies.DependencyCollector;
public class DependencyCollection {
public static void main(String[] args) throws IOException {
Path src = Paths.get(ToolBox.testSrc, "test-input", "src");
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
try (StandardJavaFileManager fileManager = javac.getStandardFileManager(null, null, null)) {
SmartFileManager smartFileManager = new SmartFileManager(fileManager);
smartFileManager.setSymbolFileEnabled(false);
Iterable<? extends JavaFileObject> fileObjects =
fileManager.getJavaFileObjectsFromFiles(Arrays.asList(src.resolve("pkg/Test.java").toFile()));
JavacTaskImpl task = (JavacTaskImpl) javac.getTask(new PrintWriter(System.out),
smartFileManager,
null,
Arrays.asList("-d", "classes",
"-sourcepath", src.toAbsolutePath().toString()),
null,
fileObjects);
DependencyCollector depsCollector = new DependencyCollector();
task.addTaskListener(depsCollector);
task.doCall();
// Find pkg symbol
PackageSymbol pkg = findPkgSymbolWithName(depsCollector.getSourcePackages(), "pkg");
Set<PackageSymbol> foundDependencies = depsCollector.getDependenciesForPkg(pkg);
// Print dependencies
System.out.println("Found dependencies:");
foundDependencies.stream()
.sorted(Comparator.comparing(DependencyCollection::extractNumber))
.forEach(p -> System.out.println(" " + p));
// Check result
Set<Integer> found = foundDependencies.stream()
.map(DependencyCollection::extractNumber)
.collect(Collectors.toSet());
found.remove(-1); // Dependencies with no number (java.lang etc)
Set<Integer> expected = new HashSet<>();
for (int i = 2; i <= 30; i++) {
if (i == 15) continue; // Case 15 correspond to the type of a throw-away return value.
expected.add(i);
}
Set<Integer> missing = new HashSet<>(expected);
missing.removeAll(found);
if (missing.size() > 0) {
System.out.println("Missing dependencies:");
missing.forEach(i -> System.out.println(" Dependency " + i));
}
Set<Integer> unexpected = new HashSet<>(found);
unexpected.removeAll(expected);
if (unexpected.size() > 0) {
System.out.println("Unexpected dependencies found:");
unexpected.forEach(i -> System.out.println(" Dependency " + i));
}
if (missing.size() > 0 || unexpected.size() > 0)
throw new AssertionError("Missing and/or unexpected dependencies found.");
}
}
private static PackageSymbol findPkgSymbolWithName(Set<PackageSymbol> syms, String name) {
for (PackageSymbol ps : syms)
if (ps.fullname.toString().equals("pkg"))
return ps;
throw new AssertionError("Could not find package named \"pkg\".");
}
public static int extractNumber(PackageSymbol p) {
Matcher m = Pattern.compile("\\d+").matcher(p.fullname.toString());
if (!m.find())
return -1;
return Integer.parseInt(m.group());
}
}

View File

@ -60,6 +60,7 @@ public class IncCompInheritance extends SjavacBase {
throw new AssertionError("Compilation failed unexpectedly");
// Remove method A.m
Thread.sleep(2500); // Make sure we get a new timestamp
String aModified = "package pkga; public class A { }";
toolbox.writeFile(src.resolve("pkga/A.java"), aModified);

View File

@ -51,9 +51,10 @@ public class IncCompileChangeNative extends SJavacTester {
ToolBox tb = new ToolBox();
void test() throws Exception {
Files.createDirectory(GENSRC);
Files.createDirectory(BIN);
Files.createDirectory(HEADERS);
clean(TEST_ROOT);
Files.createDirectories(GENSRC);
Files.createDirectories(BIN);
Files.createDirectories(HEADERS);
initialCompile();
incrementalCompileDropAllNatives();
@ -70,21 +71,25 @@ public class IncCompileChangeNative extends SJavacTester {
System.out.println("\nIn incrementalCompileDropAllNatives() ");
System.out.println("Verify that beta_B.h is removed");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; import alfa.omega.A; public class B {"+
"private int b() { return A.DEFINITION; } }");
"package beta; import alfa.omega.A; " +
"public class B { private int b() { return A.DEFINITION; } }");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyNewerFiles(previous_bin_state, new_bin_state,
"bin/beta/B.class",
"bin/beta/BINT.class",
"bin/javac_state");
BIN + "/beta/B.class",
BIN + "/beta/BINT.class",
BIN + "/javac_state");
previous_bin_state = new_bin_state;
Map<String,Long> new_headers_state = collectState(HEADERS);
verifyThatFilesHaveBeenRemoved(previous_headers_state, new_headers_state,
"headers/beta_B.h");
HEADERS + "/beta_B.h");
previous_headers_state = new_headers_state;
}
@ -94,22 +99,26 @@ public class IncCompileChangeNative extends SJavacTester {
System.out.println("\nIn incrementalCompileAddNative() ");
System.out.println("Verify that beta_B.h is added again");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; import alfa.omega.A; public class B {"+
"private int b() { return A.DEFINITION; } "+
"@java.lang.annotation.Native final static int alfa = 42; }");
"package beta; import alfa.omega.A; public class B {"+
"private int b() { return A.DEFINITION; } "+
"@java.lang.annotation.Native final static int alfa = 42; }");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyNewerFiles(previous_bin_state, new_bin_state,
"bin/beta/B.class",
"bin/beta/BINT.class",
"bin/javac_state");
BIN + "/beta/B.class",
BIN + "/beta/BINT.class",
BIN + "/javac_state");
previous_bin_state = new_bin_state;
Map<String,Long> new_headers_state = collectState(HEADERS);
verifyThatFilesHaveBeenAdded(previous_headers_state, new_headers_state,
"headers/beta_B.h");
HEADERS + "/beta_B.h");
previous_headers_state = new_headers_state;
}
}

View File

@ -51,9 +51,10 @@ public class IncCompileDropClasses extends SJavacTester {
ToolBox tb = new ToolBox();
void test() throws Exception {
Files.createDirectory(GENSRC);
Files.createDirectory(BIN);
Files.createDirectory(HEADERS);
clean(TEST_ROOT);
Files.createDirectories(GENSRC);
Files.createDirectories(BIN);
Files.createDirectories(HEADERS);
initialCompile();
incrementalCompileDroppingClasses();
@ -68,15 +69,19 @@ public class IncCompileDropClasses extends SJavacTester {
System.out.println("\nIn incrementalCompileDroppingClasses() ");
System.out.println("Testing that deleting AA.java deletes all generated inner class including AA.class");
removeFrom(GENSRC, "alfa/omega/AA.java");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state,
"bin/alfa/omega/AA$1.class",
"bin/alfa/omega/AA$AAAA.class",
"bin/alfa/omega/AA$AAA.class",
"bin/alfa/omega/AAAAA.class",
"bin/alfa/omega/AA.class");
BIN + "/alfa/omega/AA$1.class",
BIN + "/alfa/omega/AA$AAAA.class",
BIN + "/alfa/omega/AA$AAA.class",
BIN + "/alfa/omega/AAAAA.class",
BIN + "/alfa/omega/AA.class");
previous_bin_state = new_bin_state;
Map<String,Long> new_headers_state = collectState(HEADERS);

View File

@ -27,6 +27,7 @@
* @test
* @summary Verify that "alfa.omega.A a" does create a proper dependency
* @bug 8054689
* @ignore Requires dependency code to deal with in-method dependencies.
* @author Fredrik O
* @author sogoel (rewrite)
* @library /tools/lib
@ -38,8 +39,7 @@
* @run main Wrapper IncCompileFullyQualifiedRef
*/
import java.util.*;
import java.nio.file.*;
import java.util.Map;
public class IncCompileFullyQualifiedRef extends SJavacTester {
public static void main(String... args) throws Exception {
@ -48,36 +48,43 @@ public class IncCompileFullyQualifiedRef extends SJavacTester {
}
void test() throws Exception {
clean(TEST_ROOT);
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; public class A { "+
" public final static int DEFINITION = 18; "+
" public void hello() { }"+
"}");
"package alfa.omega; public class A { "+
" public final static int DEFINITION = 18; "+
" public void hello() { }"+
"}");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; public class B { "+
" public void world() { alfa.omega.A a; }"+
"}");
"package beta; public class B { "+
" public void world() { alfa.omega.A a; }"+
"}");
compile("gensrc", "-d", "bin", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> previous_bin_state = collectState(BIN);
// Change pubapi of A, this should trigger a recompile of B.
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; public class A { "+
" public final static int DEFINITION = 19; "+
" public void hello() { }"+
"}");
"package alfa.omega; public class A { "+
" public final static int DEFINITION = 19; "+
" public void hello() { }"+
"}");
compile("gensrc", "-d", "bin", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyNewerFiles(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class",
"bin/beta/B.class",
"bin/javac_state");
BIN + "/alfa/omega/A.class",
BIN + "/beta/B.class",
BIN + "/javac_state");
clean(GENSRC,BIN);
}
}

View File

@ -50,9 +50,10 @@ public class IncCompileNoChanges extends SJavacTester {
Map<String,Long> previous_headers_state;
void test() throws Exception {
Files.createDirectory(GENSRC);
Files.createDirectory(BIN);
Files.createDirectory(HEADERS);
clean(Paths.get(getClass().getSimpleName()));
Files.createDirectories(GENSRC);
Files.createDirectories(BIN);
Files.createDirectories(HEADERS);
initialCompile();
incrementalCompileNoChanges();
@ -66,8 +67,12 @@ public class IncCompileNoChanges extends SJavacTester {
previous_headers_state = collectState(HEADERS);
System.out.println("\nIn incrementalCompileNoChanges() ");
System.out.println("Testing that no change in sources implies no change in binaries");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyEqual(new_bin_state, previous_bin_state);
Map<String,Long> new_headers_state = collectState(HEADERS);

View File

@ -51,9 +51,10 @@ public class IncCompileUpdateNative extends SJavacTester {
ToolBox tb = new ToolBox();
void test() throws Exception {
Files.createDirectory(GENSRC);
Files.createDirectory(BIN);
Files.createDirectory(HEADERS);
clean(TEST_ROOT);
Files.createDirectories(GENSRC);
Files.createDirectories(BIN);
Files.createDirectories(HEADERS);
initialCompile();
incrementalCompileChangeNative();
@ -69,22 +70,26 @@ public class IncCompileUpdateNative extends SJavacTester {
System.out.println("\nIn incrementalCompileChangeNative() ");
System.out.println("Verify that beta_B.h is rewritten again");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; import alfa.omega.A; public class B {"+
"private int b() { return A.DEFINITION; } "+
"@java.lang.annotation.Native final static int alfa = 43; }");
"package beta; import alfa.omega.A; public class B {"+
"private int b() { return A.DEFINITION; } "+
"@java.lang.annotation.Native final static int alfa = 43; }");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyNewerFiles(previous_bin_state, new_bin_state,
"bin/beta/B.class",
"bin/beta/BINT.class",
"bin/javac_state");
BIN + "/beta/B.class",
BIN + "/beta/BINT.class",
BIN + "/javac_state");
previous_bin_state = new_bin_state;
Map<String,Long> new_headers_state = collectState(HEADERS);
verifyNewerFiles(previous_headers_state, new_headers_state,
"headers/beta_B.h");
HEADERS + "/beta_B.h");
previous_headers_state = new_headers_state;
}
}

View File

@ -24,6 +24,7 @@
/*
* @test
* @summary Verify incremental changes in gensrc are handled as expected
* @ignore Requires dependency code to deal with in-method dependencies.
* @bug 8054689
* @author Fredrik O
* @author sogoel (rewrite)
@ -51,14 +52,13 @@ public class IncCompileWithChanges extends SJavacTester {
ToolBox tb = new ToolBox();
void test() throws Exception {
Files.createDirectory(GENSRC);
Files.createDirectory(BIN);
Files.createDirectory(HEADERS);
clean(TEST_ROOT);
Files.createDirectories(GENSRC);
Files.createDirectories(BIN);
Files.createDirectories(HEADERS);
initialCompile();
incrementalCompileWithChange();
clean(GENSRC, BIN, HEADERS);
}
/* Update A.java with a new timestamp and new final static definition.
@ -72,24 +72,29 @@ public class IncCompileWithChanges extends SJavacTester {
System.out.println("A.java updated to trigger a recompile");
System.out.println("Generated native header should not be updated since native api of B was not modified");
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; public class A implements AINT { "+
"public final static int DEFINITION = 18; public void aint() { } private void foo() { } }");
"package alfa.omega; public class A implements AINT { " +
"public final static int DEFINITION = 18;" +
"public void aint() { } private void foo() { } }");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
Map<String,Long> new_bin_state = collectState(BIN);
verifyNewerFiles(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class",
"bin/alfa/omega/AINT.class",
"bin/alfa/omega/AA$AAAA.class",
"bin/alfa/omega/AAAAA.class",
"bin/alfa/omega/AA$AAA.class",
"bin/alfa/omega/AA.class",
"bin/alfa/omega/AA$1.class",
"bin/beta/B.class",
"bin/beta/BINT.class",
"bin/javac_state");
BIN + "/alfa/omega/A.class",
BIN + "/alfa/omega/AINT.class",
BIN + "/alfa/omega/AA$AAAA.class",
BIN + "/alfa/omega/AAAAA.class",
BIN + "/alfa/omega/AA$AAA.class",
BIN + "/alfa/omega/AA.class",
BIN + "/alfa/omega/AA$1.class",
BIN + "/beta/B.class",
BIN + "/beta/BINT.class",
BIN + "/javac_state");
previous_bin_state = new_bin_state;
Map<String,Long> new_headers_state = collectState(HEADERS);

View File

@ -83,6 +83,7 @@ public class JavacOptionPrep {
// Check the result
boolean destDirFound = false;
boolean userPathsFirst = false;
boolean headerDirFound = false;
boolean gensrcDirFound = false;
boolean classPathFound = false;
@ -95,6 +96,11 @@ public class JavacOptionPrep {
String option = javacArgIter.next();
// Ignore this option for now. When the file=... requirement goes
// away, this will be easier to handle.
if (option.startsWith("-XDcompletionDeps"))
continue;
switch (option) {
case "-classpath":
case "-cp":
@ -166,7 +172,6 @@ public class JavacOptionPrep {
if (!implicitNoneFound)
throw new AssertionError("\"-implicit:none\" not found.");
}
static void assertEquals(Object expected, Object actual) {

View File

@ -38,12 +38,8 @@
* @run main Wrapper PermittedArtifact
*/
import java.lang.reflect.Method;
import java.util.*;
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.charset.*;
import java.nio.file.Files;
import java.util.Map;
public class PermittedArtifact extends SJavacTester {
public static void main(String... args) throws Exception {
@ -53,26 +49,31 @@ public class PermittedArtifact extends SJavacTester {
//Verify that --permit-artifact=bin works
void test() throws Exception {
Files.createDirectory(BIN);
clean(TEST_ROOT);
Files.createDirectories(BIN);
clean(GENSRC, BIN);
Map<String,Long> previous_bin_state = collectState(BIN);
new ToolBox().writeFile(GENSRC+"/alfa/omega/A.java",
"package alfa.omega; public class A { }");
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC + "/alfa/omega/A.java",
"package alfa.omega; public class A { }");
new ToolBox().writeFile(BIN+"/alfa/omega/AA.class",
"Ugh, a messy build system (tobefixed) wrote this class file, "
+ "sjavac must not delete it.");
tb.writeFile(BIN + "/alfa/omega/AA.class",
"Ugh, a messy build system (tobefixed) wrote this class file, " +
"sjavac must not delete it.");
compile("--log=debug", "--permit-artifact=bin/alfa/omega/AA.class",
"-src", "gensrc", "-d", "bin", SERVER_ARG);
compile("--log=debug",
"--permit-artifact=" + BIN + "/alfa/omega/AA.class",
"-src", GENSRC.toString(),
"-d", BIN.toString(),
SERVER_ARG);
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class",
"bin/alfa/omega/AA.class",
"bin/javac_state");
BIN + "/alfa/omega/A.class",
BIN + "/alfa/omega/AA.class",
BIN + "/javac_state");
clean(GENSRC, BIN);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -25,7 +25,6 @@ import java.util.*;
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.charset.*;
import com.sun.tools.sjavac.Main;
@ -35,16 +34,18 @@ public class SJavacTester {
+ "portfile=testportfile,"
+ "background=false";
final Path TEST_ROOT = Paths.get(getClass().getSimpleName());
// Generated sources that will test aspects of sjavac
static final Path GENSRC = Paths.get("gensrc");
final Path GENSRC = TEST_ROOT.resolve("gensrc");
// Gensrc dirs used to test merging of serveral source roots.
static final Path GENSRC2 = Paths.get("gensrc2");
static final Path GENSRC3= Paths.get("gensrc3");
final Path GENSRC2 = TEST_ROOT.resolve("gensrc2");
final Path GENSRC3 = TEST_ROOT.resolve("gensrc3");
// Dir for compiled classes.
static final Path BIN = Paths.get("bin");
final Path BIN = TEST_ROOT.resolve("bin");
// Dir for c-header files.
Path HEADERS = Paths.get("headers");
final Path HEADERS = TEST_ROOT.resolve("headers");
// Remember the previous bin and headers state here.
Map<String,Long> previous_bin_state;
@ -54,10 +55,10 @@ public class SJavacTester {
System.out.println("\nInitial compile of gensrc.");
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("alfa/omega/AINT.java"),
"package alfa.omega; public interface AINT { void aint(); }");
"package alfa.omega; public interface AINT { void aint(); }");
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; public class A implements AINT { "+
"public final static int DEFINITION = 17; public void aint() { } }");
"package alfa.omega; public class A implements AINT { "+
"public final static int DEFINITION = 17; public void aint() { } }");
tb.writeFile(GENSRC.resolve("alfa/omega/AA.java"),
"package alfa.omega;"+
"// A package private class, not contributing to the public api.\n"+
@ -79,13 +80,17 @@ public class SJavacTester {
" // from outside of this source file, therefore it is ok.\n"+
"}\n");
tb.writeFile(GENSRC.resolve("beta/BINT.java"),
"package beta;public interface BINT { void foo(); }");
"package beta;public interface BINT { void foo(); }");
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; import alfa.omega.A; public class B {"+
"private int b() { return A.DEFINITION; } native void foo(); }");
"package beta; import alfa.omega.A; public class B {"+
"private int b() { return A.DEFINITION; } native void foo(); }");
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
SERVER_ARG, "--log=debug");
compile(GENSRC.toString(),
"-d", BIN.toString(),
"-h", HEADERS.toString(),
"-j", "1",
SERVER_ARG,
"--log=debug");
}
void removeFrom(Path dir, String... args) throws IOException {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, 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
@ -37,7 +37,7 @@ public class SjavacBase {
*/
public static int compile(Object... args) throws ReflectiveOperationException {
// Use reflection to avoid a compile-time dependency on sjavac Main
System.err.println("compile: " + Arrays.toString(args));
System.out.println("compile: " + Arrays.toString(args));
Class<?> c = Class.forName("com.sun.tools.sjavac.Main");
Method m = c.getDeclaredMethod("go", String[].class);
String[] strArgs = new String[args.length];

View File

@ -48,28 +48,29 @@ public class StateDir extends SJavacTester {
}
void test() throws Exception {
Path bar = Paths.get("bar");
Files.createDirectory(bar);
Files.createDirectory(BIN);
clean(GENSRC, BIN, bar);
clean(TEST_ROOT);
Path BAR = TEST_ROOT.resolve("bar");
Files.createDirectories(BAR);
Files.createDirectories(BIN);
Map<String,Long> previous_bin_state = collectState(BIN);
Map<String,Long> previous_bar_state = collectState(bar);
Map<String,Long> previous_bar_state = collectState(BAR);
ToolBox tb = new ToolBox();
tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
"package alfa.omega; public class A { }");
"package alfa.omega; public class A { }");
compile("--state-dir=bar", "-src", "gensrc", "-d", "bin",
compile("--state-dir=" + BAR,
"-src", GENSRC.toString(),
"-d", BIN.toString(),
SJavacTester.SERVER_ARG);
Map<String,Long> new_bin_state = collectState(BIN);
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
"bin/alfa/omega/A.class");
Map<String,Long> new_bar_state = collectState(bar);
BIN + "/alfa/omega/A.class");
Map<String,Long> new_bar_state = collectState(BAR);
verifyThatFilesHaveBeenAdded(previous_bar_state, new_bar_state,
"bar/javac_state");
clean(GENSRC, BIN, bar);
BAR + "/javac_state");
clean(GENSRC, BIN, BAR);
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package nondependency.pkg26;
public class Cls26 {
}

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
// Use fully qualified names to avoid accidentally capturing dependencies in import statements.
package pkg;
import pkg2.*; // pkg2 as a whole
import pkg3.Cls3; // pkg3.Cls3
import pkg25.Cls25; // pkg25.Cls25
import nondependency.pkg26.Cls26; // pkg26.Cls26 (but not nondependency)
import pkg28.Cls28.Inner28; // pkg29.Cls28, pkg29.Cls28.Inner28
import static pkg29.Cls29.Inner29; // pkg29.Cls29, pkg29.Cls29.Inner29
import static pkg30.Cls30.*; // pkg30.Cls30 as a whole
@pkg5.Anno5 // pkg5.Anno5
public class Test<S extends pkg23.Cls23> // pkg23.Cls23
extends pkg4.Cls4/*extends pkg11.Cls11*/<pkg6.Cls6/*extends pkg12.Cls12*/> // pkg4.Cls4, pkg11.Cls11, pkg6.Cls6, pkg12.Cls12
implements pkg7.Cls7, pkg8.Cls8<pkg9.Cls9> { // pkg7.Cls7, pkg8.Cls8, pkg9.Cls9
pkg27.Cls27 cls27[][][] = new pkg27.Cls27[0][0][0]; // pkg27.Cls27
pkg2.Cls2 cls2;
pkg19.Cls19 f19; // pkg19.Cls19
public static void main(String[] args) { // java.lang.String
pkg10.Cls10 o = new pkg10.Cls10(); // pkg10.Cls10
o.getCls13().getCls14().getCls15(); // pkg13.Cls13, pkg14.Cls14, pkg15.Cls15
pkg23.Cls23.f24 = null; // pkg23.Cls23, pkg24.Cls24
}
static pkg16.Cls16 m1(pkg17.Cls17 o) { // pkg16.Cls16, pkg17.Cls17
return null;
}
public <T extends pkg18.Cls18> void m2() { // pkg18.Cls18
}
public <T> T m3() {
T t;
t = null;
return t;
}
@pkg20.Anno20(pkg21.Cls21.class) // pkg20.Anno20, pkg21.Cls21
private void m3(@pkg22.Anno22 String s) { // pkg22.Anno22
Runnable r = () -> { System.out.println("hello"); };
}
private void m4() throws Cls25 { // pkg25.Cls25
}
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg11; public class Cls11 { }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg12; public class Cls12 { }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg15; public class Cls15 { }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg16; public class Cls16 { }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg17; public class Cls17 { }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg18; public class Cls18 { }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg19; public class Cls19 { }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg2; public class Cls2 { }

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg20;
public @interface Anno20 {
Class<?> value();
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg21; public class Cls21 { }

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg22;
public @interface Anno22 {
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg23;
public class Cls23 {
public static pkg24.Cls24 f24;
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg24; public class Cls24 { }

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg25;
public class Cls25 extends Throwable {
}

View File

@ -1,26 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg27;
public class Cls27 {}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg28;
public class Cls28 {
public static class Inner28 {}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg29;
public class Cls29 {
public static class Inner29 {}
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg3; public class Cls3 { }

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg30;
public class Cls30 {
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg4;
public class Cls4<T> extends pkg11.Cls11 {
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg5;
public @interface Anno5 {
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg6;
public class Cls6 extends pkg12.Cls12 {
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg7;
public interface Cls7 {
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg8;
public interface Cls8<T> {
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package pkg9; public class Cls9 { }