From 4aa63e345e17da4e8f8bf0cd4a7b4d1688b8de71 Mon Sep 17 00:00:00 2001 From: Snjezana Peco Date: Mon, 28 Oct 2024 19:06:35 +0100 Subject: [PATCH] Improve JavacBindingResolver --- .../jdt/core/dom/JavacBindingResolver.java | 34 ++++++++++++++++- .../dom/JavacCompilationUnitResolver.java | 37 +++++++++++-------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java index a75271224d1..a967f8e3337 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.lang.reflect.Field; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -39,10 +40,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; @@ -74,6 +77,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; @@ -419,13 +423,15 @@ public IBinding getBinding(String key) { public final Bindings bindings = new Bindings(); private WorkingCopyOwner owner; private HashMap resolvedBindingsCache = new HashMap<>(); + private JCCompilationUnit javacCompilationUnit; - public JavacBindingResolver(IJavaProject javaProject, JavacTask javacTask, Context context, JavacConverter converter, WorkingCopyOwner owner) { + public JavacBindingResolver(IJavaProject javaProject, JavacTask javacTask, Context context, JavacConverter converter, WorkingCopyOwner owner, JCCompilationUnit javacCompilationUnit) { this.javac = javacTask; this.context = context; this.javaProject = javaProject; this.converter = converter; this.owner = owner; + this.javacCompilationUnit = javacCompilationUnit; } private void resolve() { @@ -438,7 +444,31 @@ private void resolve() { if (!alreadyAnalyzed) { // symbols not already present: analyze try { - this.javac.analyze(); + Iterable elements; + long start = System.currentTimeMillis(); + if (this.javac instanceof JavacTaskImpl javacTaskImpl) { + if (javacCompilationUnit != null) { + Iterable trees = Collections.singletonList(javacCompilationUnit); + 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 e) { ILog.get().error(e.getMessage(), e); } diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java index 90821148d5a..b05c0c4e202 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java @@ -66,7 +66,6 @@ import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.compiler.util.Util; import org.eclipse.jdt.internal.core.CancelableNameEnvironment; -import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.dom.ICompilationUnitResolver; import org.eclipse.jdt.internal.core.util.BindingKeyParser; @@ -282,7 +281,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) { @@ -488,20 +487,21 @@ public CompilationUnit toCompilationUnit(org.eclipse.jdt.internal.compiler.env.I WorkingCopyOwner workingCopyOwner, WorkingCopyOwner typeRootWorkingCopyOwner, int flags, IProgressMonitor monitor) { // collect working copies - var workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(workingCopyOwner, true); - if (workingCopies == null) { - workingCopies = new ICompilationUnit[0]; - } + // do we need this +// var workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(workingCopyOwner, true); +// if (workingCopies == null) { +// workingCopies = new ICompilationUnit[0]; +// } Map pathToUnit = new HashMap<>(); - Arrays.stream(workingCopies) // - .filter(inMemoryCu -> { - 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); - }); - +// Arrays.stream(workingCopies) // +// .filter(inMemoryCu -> { +// 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, @@ -786,7 +786,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, javacCompilationUnit); resolver.isRecoveringBindings = (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0; ast.setBindingResolver(resolver); } @@ -821,6 +821,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) {