diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JCReusableCompiler.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JCReusableCompiler.kt
new file mode 100644
index 000000000..ca821b9cc
--- /dev/null
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JCReusableCompiler.kt
@@ -0,0 +1,36 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AndroidIDE 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.lsp.java.compiler
+
+import com.itsaky.androidide.javac.services.compiler.ReusableCompiler
+import com.itsaky.androidide.javac.services.compiler.ReusableContext
+
+/**
+ * Implementation of the [ReusableCompiler] which replaces necessary components from the
+ * [ReusableContext].
+ *
+ * @author Akash Yadav
+ */
+class JCReusableCompiler : ReusableCompiler() {
+
+ override fun onCreateContext(): ReusableContext {
+ return super.onCreateContext().also {
+ JavaCompilerImpl.preRegister(context = it, replace = true)
+ }
+ }
+}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerImpl.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerImpl.kt
new file mode 100644
index 000000000..d1dc4b83f
--- /dev/null
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerImpl.kt
@@ -0,0 +1,42 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AndroidIDE 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
+
+package com.itsaky.androidide.lsp.java.compiler
+
+import com.itsaky.androidide.javac.services.compiler.ReusableContext
+import com.itsaky.androidide.javac.services.compiler.ReusableJavaCompiler
+import jdkx.tools.JavaFileObject
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit
+import openjdk.tools.javac.util.Context
+
+class JavaCompilerImpl(context: Context?) : ReusableJavaCompiler(context) {
+
+ override fun parse(filename: JavaFileObject?, content: CharSequence?): JCCompilationUnit {
+ // TODO Prune unnecessary methods to speed up compilation
+ return super.parse(filename, content)
+ }
+
+ companion object {
+ @JvmStatic
+ fun preRegister(context: ReusableContext, replace: Boolean = false) {
+ if (replace) {
+ context.drop(compilerKey)
+ }
+ context.put(compilerKey, Context.Factory { JavaCompilerImpl(it) })
+ }
+ }
+}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java
index bc2776242..114cd8be7 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java
@@ -86,7 +86,7 @@ public class JavaCompilerService implements CompilerProvider {
protected final SynchronizedTask synchronizedTask = new SynchronizedTask();
protected final SourceFileManager fileManager;
protected final ModuleProject module;
- public ReusableCompiler compiler = new ReusableCompiler();
+ public ReusableCompiler compiler = new JCReusableCompiler();
protected Set bootClasspathClasses =
BootClasspathProvider.getTopLevelClasses(
Collections.singleton(Environment.ANDROID_JAR.getAbsolutePath()));
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java
index 6c48a2d14..9846deccf 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java
@@ -156,7 +156,7 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
final var sourceObject = new SourceFileObject(file);
final var contentBuilder = new StringBuilder(sourceObject.getCharContent(true));
- if (!VMUtils.isJvm()) {
+ if (false && !VMUtils.isJvm()) {
// Cannot use tree sitter in tests
// TODO(itsaky): Should we use the legacy method pruner for tests?
final StopWatch watch = new StopWatch("Prune method bodies");
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java
index 747909708..004c14ada 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java
@@ -59,9 +59,9 @@ import openjdk.tools.javac.util.Position;
*/
public class NBParserFactory extends ParserFactory {
- private final ScannerFactory scannerFactory;
- private final Names names;
- private final CancelService cancelService;
+ protected final ScannerFactory scannerFactory;
+ protected final Names names;
+ protected final CancelService cancelService;
public static void preRegister(Context context) {
context.put(parserFactoryKey, (Context.Factory) NBParserFactory::new);
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt
index 6be568e41..e41c50f5a 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt
@@ -31,6 +31,10 @@ import com.itsaky.androidide.javac.services.fs.CacheFSInfoSingleton
import com.itsaky.androidide.javac.services.fs.JarPackageProviderImpl
import com.itsaky.androidide.utils.VMUtils
import com.itsaky.androidide.zipfs2.JarPackageProvider
+import java.net.URI
+import jdkx.tools.DiagnosticListener
+import jdkx.tools.JavaFileManager
+import jdkx.tools.JavaFileObject
import openjdk.source.util.JavacTask
import openjdk.source.util.TaskEvent
import openjdk.source.util.TaskEvent.Kind.ANALYZE
@@ -53,35 +57,41 @@ import openjdk.tools.javac.util.Context
import openjdk.tools.javac.util.DefinedBy
import openjdk.tools.javac.util.DefinedBy.Api.COMPILER_TREE
import openjdk.tools.javac.util.Log
-import java.io.PrintWriter
-import java.net.URI
-import jdkx.tools.DiagnosticListener
-import jdkx.tools.JavaFileManager
-import jdkx.tools.JavaFileObject
/**
* Reusable [Context] for [ReusableCompiler].
+ *
* @author Akash Yadav
*/
class ReusableContext(cancelService: CancelService) : Context(), TaskListener {
-
+
private val flowCompleted = mutableSetOf()
-
+
init {
put(Log.logKey, ReusableLog.factory)
put(FSInfo::class.java, if (VMUtils.isJvm()) CacheFSInfo() else CacheFSInfoSingleton)
put(JavaCompiler.compilerKey, ReusableJavaCompiler.factory)
put(JavacFlowListener.flowListenerKey, JavacFlowListener { this.hasFlowCompleted(it) })
put(JarPackageProvider::class.java, JarPackageProviderImpl)
- registerNBServices(cancelService)
+
+ NBAttr.preRegister(this)
+ NBParserFactory.preRegister(this)
+ NBTreeMaker.preRegister(this)
+ NBJavacTrees.preRegister(this)
+ NBResolve.preRegister(this)
+ NBEnter.preRegister(this)
+ NBMemberEnter.preRegister(this, false)
+ NBClassFinder.preRegister(this)
+ NBClassReader.preRegister(this)
+ CancelService.preRegister(this, cancelService)
}
-
+
@DefinedBy(COMPILER_TREE)
override fun started(e: TaskEvent) {
// log.debug("Started: $e")
// Do nothing
}
-
+
@DefinedBy(COMPILER_TREE)
override fun finished(e: TaskEvent) {
if (e.kind == ANALYZE) {
@@ -91,7 +101,7 @@ class ReusableContext(cancelService: CancelService) : Context(), TaskListener {
}
}
}
-
+
fun clear() {
drop(Arguments.argsKey)
drop(DiagnosticListener::class.java)
@@ -101,7 +111,7 @@ class ReusableContext(cancelService: CancelService) : Context(), TaskListener {
drop(JavacTask::class.java)
drop(JavacTrees::class.java)
drop(JavacElements::class.java)
-
+
if (ht[Log.logKey] is ReusableLog) {
// log already init-ed - not first round
(Log.instance(this) as ReusableLog).clear()
@@ -115,15 +125,17 @@ class ReusableContext(cancelService: CancelService) : Context(), TaskListener {
MultiTaskListener.instance(this).clear()
}
}
-
- private fun drop(k: Key?) {
+
+ /** **FOR INTERNAL USE ONLY!** */
+ fun drop(k: Key?) {
ht.remove(k)
}
-
- private fun drop(c: Class?) {
- ht.remove(key(c))
+
+ /** **FOR INTERNAL USE ONLY!** */
+ fun drop(c: Class?) {
+ drop(key(c))
}
-
+
private fun hasFlowCompleted(fo: JavaFileObject?): Boolean {
return if (fo == null) {
false
@@ -135,17 +147,4 @@ class ReusableContext(cancelService: CancelService) : Context(), TaskListener {
}
}
}
-
- private fun registerNBServices(cancelService: CancelService) {
- NBAttr.preRegister(this)
- NBParserFactory.preRegister(this)
- NBTreeMaker.preRegister(this)
- NBJavacTrees.preRegister(this)
- NBResolve.preRegister(this)
- NBEnter.preRegister(this)
- NBMemberEnter.preRegister(this, false)
- NBClassFinder.preRegister(this)
- NBClassReader.preRegister(this)
- CancelService.preRegister(this, cancelService)
- }
}
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt
index 9dd5fad08..f5e1c44d4 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt
@@ -25,7 +25,7 @@ import openjdk.tools.javac.util.Context
* Reusable JavaCompiler; exposes a method to clean up the component from leftovers associated
* with previous compilations.
*/
-internal class ReusableJavaCompiler(context: Context?) : NBJavaCompiler(context) {
+open class ReusableJavaCompiler(context: Context?) : NBJavaCompiler(context) {
companion object {
val factory = Context.Factory { ReusableJavaCompiler(it) }