com.sun.tools.sjavac.BuildState Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jdk.compiler Show documentation
Show all versions of jdk.compiler Show documentation
Maven repackaging of OpenJDK's jdk.compiler module
The newest version!
/*
* Copyright (c) 2012, 2013, 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.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* The build state class captures the source code and generated artifacts
* from a build. There are usually two build states, the previous one (prev),
* loaded from the javac_state file, and the current one (now).
*
* 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.
*/
public class BuildState {
private Map modules = new HashMap();
private Map packages = new HashMap();
private Map sources = new HashMap();
private Map artifacts = new HashMap();
// Map from package to a set of packages that depend on said package.
private Map> dependents = new HashMap>();
public Map modules() { return modules; }
public Map packages() { return packages; }
public Map sources() { return sources; }
public Map artifacts() { return artifacts; }
public Map> dependents() { return dependents; }
/**
* Lookup a module from a name. Create the module if it does
* not exist yet.
*/
public Module lookupModule(String mod) {
Module m = modules.get(mod);
if (m == null) {
m = new Module(mod, "???");
modules.put(mod, m);
}
return m;
}
/**
* Find a module from a given package name. For example:
* The package name "base:java.lang" will fetch the module named "base".
* The package name ":java.net" will fetch the default module.
*/
Module findModuleFromPackageName(String pkg) {
int cp = pkg.indexOf(':');
assert(cp != -1);
String mod = pkg.substring(0, cp);
return lookupModule(mod);
}
/**
* Store references to all packages, sources and artifacts for all modules
* into the build state. I.e. flatten the module tree structure
* into global maps stored in the BuildState for easy access.
*
* @param m The set of modules.
*/
public void flattenPackagesSourcesAndArtifacts(Map m) {
modules = m;
// Extract all the found packages.
for (Module i : modules.values()) {
for (Map.Entry j : i.packages().entrySet()) {
Package p = packages.get(j.getKey());
// Check that no two different packages are stored under same name.
assert(p == null || p == j.getValue());
if (p == null) {
p = j.getValue();
packages.put(j.getKey(),j.getValue());
}
for (Map.Entry k : p.sources().entrySet()) {
Source s = sources.get(k.getKey());
// Check that no two different sources are stored under same name.
assert(s == null || s == k.getValue());
if (s == null) {
s = k.getValue();
sources.put(k.getKey(), k.getValue());
}
}
for (Map.Entry g : p.artifacts().entrySet()) {
File f = artifacts.get(g.getKey());
// Check that no two artifacts are stored under the same file.
assert(f == null || f == g.getValue());
if (f == null) {
f = g.getValue();
artifacts.put(g.getKey(), g.getValue());
}
}
}
}
}
/**
* Store references to all artifacts found in the module tree into the maps
* stored in the build state.
*
* @param m The set of modules.
*/
public void flattenArtifacts(Map m) {
modules = m;
// Extract all the found packages.
for (Module i : modules.values()) {
for (Map.Entry j : i.packages().entrySet()) {
Package p = packages.get(j.getKey());
// Check that no two different packages are stored under same name.
assert(p == null || p == j.getValue());
p = j.getValue();
packages.put(j.getKey(),j.getValue());
for (Map.Entry g : p.artifacts().entrySet()) {
File f = artifacts.get(g.getKey());
// Check that no two artifacts are stored under the same file.
assert(f == null || f == g.getValue());
artifacts.put(g.getKey(), g.getValue());
}
}
}
}
/**
* Calculate the package dependents (ie the reverse of the dependencies).
*/
public void calculateDependents() {
dependents = new HashMap>();
for (String s : packages.keySet()) {
Package p = packages.get(s);
for (String d : p.dependencies()) {
Set ss = dependents.get(d);
if (ss == null) {
ss = new HashSet();
dependents.put(d, ss);
}
// Add the dependent information to the global dependent map.
ss.add(s);
Package dp = packages.get(d);
// 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.
if (dp != null) {
// But this package did exist in the state database.
dp.addDependent(p.name());
}
}
}
}
/**
* Verify that the setModules method above did the right thing when
* running through the module->package->source structure.
*/
public void checkInternalState(String msg, boolean linkedOnly, Map srcs) {
boolean baad = false;
Map original = new HashMap();
Map calculated = new HashMap();
for (String s : sources.keySet()) {
Source ss = sources.get(s);
if (ss.isLinkedOnly() == linkedOnly) {
calculated.put(s,ss);
}
}
for (String s : srcs.keySet()) {
Source ss = srcs.get(s);
if (ss.isLinkedOnly() == linkedOnly) {
original.put(s,ss);
}
}
if (original.size() != calculated.size()) {
Log.error("INTERNAL ERROR "+msg+" original and calculated are not the same size!");
baad = true;
}
if (!original.keySet().equals(calculated.keySet())) {
Log.error("INTERNAL ERROR "+msg+" original and calculated do not have the same domain!");
baad = true;
}
if (!baad) {
for (String s : original.keySet()) {
Source s1 = original.get(s);
Source s2 = calculated.get(s);
if (s1 == null || s2 == null || !s1.equals(s2)) {
Log.error("INTERNAL ERROR "+msg+" original and calculated have differing elements for "+s);
}
baad = true;
}
}
if (baad) {
for (String s : original.keySet()) {
Source ss = original.get(s);
Source sss = calculated.get(s);
if (sss == null) {
Log.error("The file "+s+" does not exist in calculated tree of sources.");
}
}
for (String s : calculated.keySet()) {
Source ss = calculated.get(s);
Source sss = original.get(s);
if (sss == null) {
Log.error("The file "+s+" does not exist in original set of found sources.");
}
}
}
}
/**
* Load a module from the javac state file.
*/
public Module loadModule(String l) {
Module m = Module.load(l);
modules.put(m.name(), m);
return m;
}
/**
* Load a package from the javac state file.
*/
public Package loadPackage(Module lastModule, String l) {
Package p = Package.load(lastModule, l);
lastModule.addPackage(p);
packages.put(p.name(), p);
return p;
}
/**
* Load a source from the javac state file.
*/
public Source loadSource(Package lastPackage, String l, boolean is_generated) {
Source s = Source.load(lastPackage, l, is_generated);
lastPackage.addSource(s);
sources.put(s.name(), s);
return s;
}
/**
* During an incremental compile we need to copy the old javac state
* information about packages that were not recompiled.
*/
public void copyPackagesExcept(BuildState prev, Set recompiled, Set removed) {
for (String pkg : prev.packages().keySet()) {
// Do not copy recompiled or removed packages.
if (recompiled.contains(pkg) || removed.contains(pkg)) continue;
Module mnew = findModuleFromPackageName(pkg);
Package pprev = prev.packages().get(pkg);
mnew.addPackage(pprev);
// Do not forget to update the flattened data.
packages.put(pkg, pprev);
}
}
}