Incremental java compile AKA javac print compile dependencies
Joshua Maurice
joshuamaurice at gmail.com
Thu May 27 23:36:53 PDT 2010
On Thu, May 27, 2010 at 11:33 AM, Jonathan Gibbons <
jonathan.gibbons at oracle.com> wrote:
> On 05/27/2010 12:20 AM, Joshua Maurice wrote:
>
>> Thank you again, but do you know any good examples of those APIs? I am
>> unable to quickly find some good documentation or examples on Types, type
>> mirrors, and such.
>>
>
> For docs, start with
> http://java.sun.com/javase/6/docs/technotes/guides/javac/index.html
>
> Roughly speaking, once you get to the point of being able to call parse()
> and analyze() ...
>
> -- walk the trees with a TreeScanner
> -- you're looking for nodes which reference other classes; this mostly
> means you need to look for declarations and expressions
>
> -- expressions have a type (TypeMirror), from a type you want to get to its
> element.
> -- a type is an "instance", like List<String>, an element is an entity
> in the source and is like a decl of a family of types, like List<T>
> -- move between types and elements using the Types and Elements utility
> APIs
>
> -- from an element, use getEnclosingElement to get to the element that you
> wish to record a dependency on
> -- e.g. your class might use X.foo, but you might want to record a
> dependency on class X, not field foo.
>
> -- from an element, if you need to you can get to its tree (via
> Trees.getTree) or its compilation unit (via Trees.getPath)
>
> -- from a compilation unit, you can get the source file
>
> And Robert's your father's brother.
>
Well, thank you again sir. Through some random googling, I managed to whip
up the file at the end, which is near exactly what I need, I think. With
this, my experimental build system is outperforming my company's current
Maven solution for a full clean rebuild by a factor of 4 or 5. The
incremental build is so fast I'm not even sure it's correct! (Further
testing is in order.)
Also, if / when that JavacTask.generate bug gets fixed, my profiling
indicates that it may speed it up by another 40% or so. (At least, it's
taking ~40% of the CPU time in the extra parse and analyze calls according
to the profiler YourKit.)
Relevant code to get compile dependencies for a java file. Note that I think
you have to close the result transitively over all super types to get
accurate results (in addition to Ghost Dependencies).
package com.informatica.devops.jicb.incr_java;
import java.util.HashSet;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeInfo;
public class CompileDependencies {
//must call this after JavacTask.analyze to get useful information
public static Set<String> get(final CompilationUnitTree tree) {
final Visitor visitor = new Visitor();
visitor.scan(tree, null);
return visitor.fullNamesOfAllFoundTypes;
}
private static class Visitor extends TreeScanner<Void, Void> {
public final Set<String> fullNamesOfAllFoundTypes = new
HashSet<String>();
@Override public Void scan(Tree node, Void v) {
if (node != null) {
Element ele = TreeInfo.symbol((JCTree)node);
for ( ; ele != null; ele = ele.getEnclosingElement()) {
final ElementKind kind = ele.getKind();
if (ElementKind.CLASS == kind
|| ElementKind.INTERFACE == kind
|| ElementKind.ANNOTATION_TYPE == kind
|| ElementKind.ENUM == kind) {
fullNamesOfAllFoundTypes.add(ele.toString());
}
}
}
super.scan(node, null);
return null;
}
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20100527/4d2cc86a/attachment.html
More information about the compiler-dev
mailing list