--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java Wed Oct 21 18:40:01 2015 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java Thu Oct 22 09:05:54 2015 +0200
@@ -30,7 +30,7 @@
import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.GraphUtils.DependencyKind;
import com.sun.tools.javac.util.GraphUtils.DotVisitor;
import com.sun.tools.javac.util.GraphUtils.NodeVisitor;
@@ -42,13 +42,13 @@
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
-import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.Set;
import java.util.Stack;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.tools.JavaFileObject;
@@ -78,69 +78,23 @@
}
/**
- * This enum models different kinds of attribution actions triggered during
- * symbol completion.
- */
- public enum AttributionKind {
- /**
- * Attribution of superclass (i.e. @{code extends} clause).
- */
- EXTENDS {
- @Override
- String format(JCTree tree) {
- return "extends " + super.format(tree);
- }
- },
- /**
- * Attribution of superinterface (i.e. an type in the @{code interface} clause).
- */
- IMPLEMENTS {
- @Override
- String format(JCTree tree) {
- return "implements " + super.format(tree);
- }
- },
- /**
- * Attribution of an import statement
- */
- IMPORT,
- /**
- * Attribution of type-variable bound
- */
- TVAR {
- @Override
- String format(JCTree tree) {
- return "<" + super.format(tree) + ">";
- }
- };
-
- String format(JCTree tree) {
- return tree.toString();
- }
- }
-
- /**
* Push a new completion node on the stack.
*/
abstract public void push(ClassSymbol s, CompletionCause phase);
/**
- * Push a new attribution node on the stack.
- */
- abstract public void push(AttributionKind ak, JCTree t);
-
- /**
* Remove current dependency node from the stack.
*/
abstract public void pop();
- public enum CompletionCause {
+ public enum CompletionCause implements GraphUtils.DependencyKind {
CLASS_READER,
HEADER_PHASE,
HIERARCHY_PHASE,
IMPORTS_PHASE,
MEMBER_ENTER,
- MEMBERS_PHASE;
+ MEMBERS_PHASE,
+ OTHER;
}
/**
@@ -163,13 +117,8 @@
/**
* Register a Context.Factory to create a Dependencies.
*/
- public static void preRegister(final Context context) {
- context.put(dependenciesKey, new Context.Factory<Dependencies>() {
- public Dependencies make(Context c) {
- Dependencies deps = new GraphDependencies(context);
- return deps;
- }
- });
+ public static void preRegister(Context context) {
+ context.put(dependenciesKey, (Context.Factory<Dependencies>) GraphDependencies::new);
}
/**
@@ -195,12 +144,11 @@
enum DependenciesMode {
SOURCE("source"),
CLASS("class"),
- REDUNDANT("redundant"),
- SIDE_EFFECTS("side-effects");
+ REDUNDANT("redundant");
final String opt;
- private DependenciesMode(String opt) {
+ DependenciesMode(String opt) {
this.opt = opt;
}
@@ -228,46 +176,19 @@
}
/**
- * Class representing a node in the dependency graph. Nodes are of two main
- * kinds: (i) symbol nodes, corresponding to symbol completion requests
- * (either from source or classfile); (ii) attribution nodes, corresponding to
- * attribution actions triggered during (source) completion.
+ * Class representing a node in the dependency graph.
*/
- public static abstract class Node extends GraphUtils.AbstractNode<String, Node>
- implements GraphUtils.DottableNode<String, Node> {
-
- /**
- * Model the dependencies between nodes.
- */
- public enum DependencyKind implements GraphUtils.DependencyKind {
- /**
- * standard dependency - i.e. completion of the source node depends
- * on completion of the sink node.
- */
- REQUIRES("solid"),
- /**
- * soft dependencies - i.e. completion of the source node depends
- * on side-effects of the source node. These dependencies are meant
- * to capture the order in which javac processes all dependants of a given node.
- */
- SIDE_EFFECTS("dashed");
-
- final String dotStyle;
-
- DependencyKind(String dotStyle) {
- this.dotStyle = dotStyle;
- }
- }
-
+ public static abstract class Node extends GraphUtils.AbstractNode<ClassSymbol, Node>
+ implements GraphUtils.DottableNode<ClassSymbol, Node> {
/**
* dependant nodes grouped by kind
*/
- EnumMap<DependencyKind, List<Node>> depsByKind;
+ EnumMap<CompletionCause, List<Node>> depsByKind;
- Node(String value) {
+ Node(ClassSymbol value) {
super(value);
- this.depsByKind = new EnumMap<>(DependencyKind.class);
- for (DependencyKind depKind : DependencyKind.values()) {
+ this.depsByKind = new EnumMap<>(CompletionCause.class);
+ for (CompletionCause depKind : CompletionCause.values()) {
depsByKind.put(depKind, new ArrayList<Node>());
}
}
@@ -281,8 +202,7 @@
@Override
public boolean equals(Object obj) {
- return obj instanceof Node &&
- data.equals(((Node) obj).data);
+ return obj instanceof Node && data.equals(((Node) obj).data);
}
@Override
@@ -292,19 +212,12 @@
@Override
public GraphUtils.DependencyKind[] getSupportedDependencyKinds() {
- return DependencyKind.values();
+ return CompletionCause.values();
}
@Override
- public java.util.Collection<? extends Node> getDependenciesByKind(GraphUtils.DependencyKind dk) {
- List<Node> deps = depsByKind.get(dk);
- if (dk == DependencyKind.REQUIRES) {
- return deps;
- } else {
- Set<Node> temp = new HashSet<>(deps);
- temp.removeAll(depsByKind.get(DependencyKind.REQUIRES));
- return temp;
- }
+ public java.util.Collection<? extends Node> getDependenciesByKind(DependencyKind dk) {
+ return depsByKind.get(dk);
}
@Override
@@ -317,9 +230,14 @@
@Override
public Properties dependencyAttributes(Node to, GraphUtils.DependencyKind dk) {
Properties p = new Properties();
- p.put("style", ((DependencyKind) dk).dotStyle);
+ p.put("label", dk);
return p;
}
+
+ @Override
+ public String toString() {
+ return data.getQualifiedName().toString();
+ }
}
/**
@@ -349,11 +267,9 @@
}
final Kind ck;
- final ClassSymbol sym;
CompletionNode(ClassSymbol sym) {
- super(sym.getQualifiedName().toString());
- this.sym = sym;
+ super(sym);
//infer completion kind by looking at the symbol fields
boolean fromClass = (sym.classfile == null && sym.sourcefile == null) ||
(sym.classfile != null && sym.classfile.getKind() == JavaFileObject.Kind.CLASS);
@@ -371,27 +287,7 @@
}
public ClassSymbol getClassSymbol() {
- return sym;
- }
- }
-
- /**
- * This is a dependency node used to model attribution actions triggered during
- * source symbol completion. The possible kinds of attribution actions are
- * captured in {@link AttributionNode}.
- */
- static class AttributionNode extends Node {
-
- AttributionNode(AttributionKind ak, JCTree tree) {
- super(ak.format(tree));
- }
-
- @Override
- public Properties nodeAttributes() {
- Properties p = super.nodeAttributes();
- p.put("shape", "box");
- p.put("style", "solid");
- return p;
+ return data;
}
}
@@ -403,25 +299,20 @@
/**
* map containing all dependency nodes seen so far
*/
- Map<String, Node> dependencyNodeMap = new LinkedHashMap<>();
+ Map<ClassSymbol, Node> dependencyNodeMap = new LinkedHashMap<>();
@Override
public void push(ClassSymbol s, CompletionCause phase) {
Node n = new CompletionNode(s);
- if (n == push(n)) {
+ if (n == push(n, phase)) {
s.completer = this;
}
}
- @Override
- public void push(AttributionKind ak, JCTree t) {
- push(new AttributionNode(ak, t));
- }
-
/**
* Push a new dependency on the stack.
*/
- protected Node push(Node newNode) {
+ protected Node push(Node newNode, CompletionCause cc) {
Node cachedNode = dependencyNodeMap.get(newNode.data);
if (cachedNode == null) {
dependencyNodeMap.put(newNode.data, newNode);
@@ -430,7 +321,7 @@
}
if (!nodeStack.isEmpty()) {
Node currentNode = nodeStack.peek();
- currentNode.addDependency(Node.DependencyKind.REQUIRES, newNode);
+ currentNode.addDependency(cc, newNode);
}
nodeStack.push(newNode);
return newNode;
@@ -455,10 +346,6 @@
//filter source completions
new FilterVisitor(CompletionNode.Kind.CLASS).visit(dependencyNodeMap.values(), null);
}
- if (dependenciesModes.contains(DependenciesMode.SIDE_EFFECTS)) {
- //add side-effects edges
- new SideEffectVisitor().visit(dependencyNodeMap.values(), null);
- }
if (dependenciesFile != null) {
//write to file
try (FileWriter fw = new FileWriter(dependenciesFile)) {
@@ -469,7 +356,7 @@
@Override
public void complete(Symbol sym) throws CompletionFailure {
- push((ClassSymbol) sym, null);
+ push((ClassSymbol)sym, CompletionCause.OTHER);
pop();
sym.completer = this;
}
@@ -484,31 +371,9 @@
}
/**
- * This visitor is used to generate the special side-effect dependencies
- * given a graph containing only standard dependencies.
- */
- private static class SideEffectVisitor extends NodeVisitor<String, Node, Void> {
- @Override
- public void visitNode(Node node, Void arg) {
- //do nothing
- }
-
- @Override
- public void visitDependency(GraphUtils.DependencyKind dk, Node from, Node to, Void arg) {
- //if we are adding multiple dependencies to same node
- //make order explicit via special 'side-effect' dependencies
- List<Node> deps = from.depsByKind.get(dk);
- int pos = deps.indexOf(to);
- if (dk == Node.DependencyKind.REQUIRES && pos > 0) {
- to.addDependency(Node.DependencyKind.SIDE_EFFECTS, deps.get(pos - 1));
- }
- }
- }
-
- /**
* This visitor is used to prune the graph from spurious edges using some heuristics.
*/
- private static class PruneVisitor extends NodeVisitor<String, Node, Void> {
+ private static class PruneVisitor extends NodeVisitor<ClassSymbol, Node, Void> {
@Override
public void visitNode(Node node, Void arg) {
//do nothing
@@ -517,8 +382,7 @@
@Override
public void visitDependency(GraphUtils.DependencyKind dk, Node from, Node to, Void arg) {
//heuristic - skips dependencies that are likely to be fake
- if (from.equals(to) ||
- from.depsByKind.get(Node.DependencyKind.REQUIRES).contains(to)) {
+ if (from.equals(to)) {
to.depsByKind.get(dk).remove(from);
}
}
@@ -527,7 +391,7 @@
/**
* This visitor is used to retain only completion nodes with given kind.
*/
- private class FilterVisitor extends NodeVisitor<String, Node, Void> {
+ private class FilterVisitor extends NodeVisitor<ClassSymbol, Node, Void> {
CompletionNode.Kind ck;
@@ -571,11 +435,6 @@
}
@Override
- public void push(AttributionKind ak, JCTree t) {
- //do nothing
- }
-
- @Override
public void pop() {
//do nothing
}