Skip to content

Commit

Permalink
Improve JavacBindingResolver
Browse files Browse the repository at this point in the history
  • Loading branch information
snjeza committed Oct 29, 2024
1 parent a57e537 commit 85e0ab9
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@
import org.eclipse.jdt.internal.javac.dom.JavacTypeVariableBinding;
import org.eclipse.jdt.internal.javac.dom.JavacVariableBinding;

import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.DocTreePath;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Attribute.Compound;
Expand Down Expand Up @@ -74,6 +76,7 @@
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
Expand Down Expand Up @@ -419,13 +422,15 @@ public IBinding getBinding(String key) {
public final Bindings bindings = new Bindings();
private WorkingCopyOwner owner;
private HashMap<ASTNode, IBinding> resolvedBindingsCache = new HashMap<>();
private List<JCCompilationUnit> javacCompilationUnits;

public JavacBindingResolver(IJavaProject javaProject, JavacTask javacTask, Context context, JavacConverter converter, WorkingCopyOwner owner) {
public JavacBindingResolver(IJavaProject javaProject, JavacTask javacTask, Context context, JavacConverter converter, WorkingCopyOwner owner, List<JCCompilationUnit> javacCompilationUnits) {
this.javac = javacTask;
this.context = context;
this.javaProject = javaProject;
this.converter = converter;
this.owner = owner;
this.javacCompilationUnits = javacCompilationUnits;
}

private void resolve() {
Expand All @@ -438,8 +443,32 @@ private void resolve() {
if (!alreadyAnalyzed) {
// symbols not already present: analyze
try {
this.javac.analyze();
} catch (IOException | IllegalStateException e) {
Iterable<? extends Element> elements;
// long start = System.currentTimeMillis();
if (this.javac instanceof JavacTaskImpl javacTaskImpl) {
if (javacCompilationUnits != null && !javacCompilationUnits.isEmpty()) {
Iterable<? extends CompilationUnitTree> trees = javacCompilationUnits;
elements = javacTaskImpl.enter(trees);
} else {
elements = javacTaskImpl.enter();
}
elements = javacTaskImpl.analyze(elements);
// long count = StreamSupport.stream(elements.spliterator(), false).count();
// String name = elements.iterator().hasNext()
// ? elements.iterator().next().getSimpleName().toString()
// : "";
// ILog.get().info("enter/analyze elements=" + count + ", took: "
// + (System.currentTimeMillis() - start) + ", first=" + name);
} else {
elements = this.javac.analyze();
// long count = StreamSupport.stream(elements.spliterator(), false).count();
// String name = elements.iterator().hasNext()
// ? elements.iterator().next().getSimpleName().toString()
// : "";
// ILog.get().info("analyze elements=" + count + ", took: " + (System.currentTimeMillis() - start)
// + ", first=" + name);
}
} catch (IOException | IllegalStateException | Error e) {
ILog.get().error(e.getMessage(), e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ private void resolveRequestedBindingKeys(JavacBindingResolver bindingResolver, S
var compiler = ToolProvider.getSystemJavaCompiler();
var context = new Context();
JavacTask task = (JavacTask) compiler.getTask(null, null, null, List.of(), List.of(), List.of());
bindingResolver = new JavacBindingResolver(null, task, context, new JavacConverter(null, null, context, null, true, -1), null);
bindingResolver = new JavacBindingResolver(null, task, context, new JavacConverter(null, null, context, null, true, -1), null, null);
}

for (CompilationUnit cu : units) {
Expand Down Expand Up @@ -495,13 +495,17 @@ public CompilationUnit toCompilationUnit(org.eclipse.jdt.internal.compiler.env.I
Map<String, org.eclipse.jdt.internal.compiler.env.ICompilationUnit> pathToUnit = new HashMap<>();
Arrays.stream(workingCopies) //
.filter(inMemoryCu -> {
return project == null || (inMemoryCu.getElementName() != null && !inMemoryCu.getElementName().contains("module-info")) || inMemoryCu.getJavaProject() == project;
try {
return inMemoryCu.hasUnsavedChanges() && (project == null || (inMemoryCu.getElementName() != null && !inMemoryCu.getElementName().contains("module-info")) || inMemoryCu.getJavaProject() == project);
} catch (JavaModelException e) {
return project == null || (inMemoryCu.getElementName() != null && !inMemoryCu.getElementName().contains("module-info")) || inMemoryCu.getJavaProject() == project;
}
})
.map(org.eclipse.jdt.internal.compiler.env.ICompilationUnit.class::cast) //
.forEach(inMemoryCu -> {
pathToUnit.put(new String(inMemoryCu.getFileName()), inMemoryCu);
});

// `sourceUnit`'s path might contain only the last segment of the path.
// this presents a problem, since if there is a working copy of the class,
// we want to use `sourceUnit` instead of the working copy,
Expand Down Expand Up @@ -692,6 +696,7 @@ public Void visitClass(ClassTree node, Void p) {
javac.lineDebugInfo = true;
}

List<JCCompilationUnit> javacCompilationUnits = new ArrayList<>();
try {
var elements = task.parse().iterator();
var aptPath = fileManager.getLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH);
Expand All @@ -705,6 +710,7 @@ public Void visitClass(ClassTree node, Void p) {
for (int i = 0 ; i < sourceUnits.length; i++) {
if (elements.hasNext() && elements.next() instanceof JCCompilationUnit u) {
javacCompilationUnit = u;
javacCompilationUnits.add(u);
} else {
return Map.of();
}
Expand Down Expand Up @@ -786,7 +792,7 @@ public void postVisit(ASTNode node) {
});
}
if (resolveBindings) {
JavacBindingResolver resolver = new JavacBindingResolver(javaProject, task, context, converter, workingCopyOwner);
JavacBindingResolver resolver = new JavacBindingResolver(javaProject, task, context, converter, workingCopyOwner, javacCompilationUnits);
resolver.isRecoveringBindings = (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
ast.setBindingResolver(resolver);
}
Expand Down Expand Up @@ -821,6 +827,11 @@ public static void cleanup(Context context) {
if (context.get(DiagnosticListener.class) instanceof ForwardDiagnosticsAsDOMProblems listener) {
listener.filesToUnits.clear(); // no need to keep handle on generated ASTs in the context
}
// based on com.sun.tools.javac.api.JavacTaskImpl.cleanup()
var javac = com.sun.tools.javac.main.JavaCompiler.instance(context);
if (javac != null) {
javac.close();
}
}
/// destroys the context, it's not usable at all after
public void destroy(Context context) {
Expand Down

0 comments on commit 85e0ab9

Please sign in to comment.