diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.java
deleted file mode 100644
index a77454616..000000000
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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 .
- */
-
-/*
- * 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 androidx.annotation.NonNull;
-
-import com.itsaky.androidide.lsp.java.CompilationCancellationException;
-import com.itsaky.androidide.lsp.java.utils.CancelChecker;
-import com.itsaky.androidide.utils.ILogger;
-
-import java.util.concurrent.Semaphore;
-import java.util.function.Consumer;
-
-import kotlin.jvm.functions.Function1;
-
-public class SynchronizedTask {
-
- private static final ILogger LOG = ILogger.newInstance("SynchronizedTask");
- private volatile boolean isCompiling = false;
- private final Semaphore semaphore = new Semaphore(1);
- private CompileTask task;
-
- public void run(@NonNull Consumer taskConsumer) {
- try {
- semaphore.acquire();
- } catch (InterruptedException e) {
- throw new CompilationCancellationException(e);
- }
- try {
- taskConsumer.accept(this.task);
- } catch (Throwable err) {
- if (!CancelChecker.isCancelled(err)) {
- LOG.error("An error occurred while working with compilation task", err);
- }
- throw err;
- } finally {
- semaphore.release();
- }
- }
-
- public T get(@NonNull Function1 function) {
- try {
- semaphore.acquire();
- } catch (InterruptedException e) {
- throw new CompilationCancellationException(e);
- }
-
- try {
- return function.invoke(this.task);
- } catch (Throwable err) {
- if (!CancelChecker.isCancelled(err)) {
- LOG.error("An error occurred while working with compilation task", err);
- }
- throw err;
- } finally {
- semaphore.release();
- }
- }
-
- void post(@NonNull Runnable run) {
- try {
- semaphore.acquire();
- } catch (InterruptedException e) {
- throw new CompilationCancellationException(e);
- }
-
- isCompiling = true;
-
- try {
- if (this.task != null) {
- this.task.close();
- }
- run.run();
- } catch (Throwable err) {
- if (!CancelChecker.isCancelled(err)) {
- LOG.error("An error occurred", err);
- }
- throw err;
- } finally {
- semaphore.release();
- isCompiling = false;
- }
- }
-
- void setTask(CompileTask task) {
- this.task = task;
- }
-
- public synchronized boolean isBusy() {
- return isCompiling || semaphore.availablePermits() == 0;
- }
-
- /**
- * FOR INTERNAL USE ONLY!
- */
- public void logStats() {
- LOG.warn("[SynchronizedTask] isCompiling =", isCompiling);
- LOG.warn("[SynchronizedTask] queuedLength =", semaphore.getQueueLength());
- }
-}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.kt
new file mode 100644
index 000000000..120b73c7a
--- /dev/null
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.kt
@@ -0,0 +1,135 @@
+/*
+ * 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 .
+ */
+/*
+ * 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.lsp.java.CompilationCancellationException
+import com.itsaky.androidide.lsp.java.utils.CancelChecker.Companion.isCancelled
+import com.itsaky.androidide.utils.ILogger
+import java.util.concurrent.Semaphore
+
+class SynchronizedTask {
+
+ @Volatile
+ @PublishedApi
+ internal var isCompiling = false
+
+ @PublishedApi
+ internal val semaphore = Semaphore(1)
+
+ @PublishedApi
+ internal var task: CompileTask? = null
+ private set
+
+ inline fun run(crossinline taskConsumer: (CompileTask) -> Unit) {
+ try {
+ semaphore.acquire()
+ } catch (e: InterruptedException) {
+ throw CompilationCancellationException(e)
+ }
+ try {
+ taskConsumer(task!!)
+ } catch (err: Throwable) {
+ if (!isCancelled(err)) {
+ log.error("An error occurred while working with compilation task", err)
+ }
+ throw err
+ } finally {
+ semaphore.release()
+ }
+ }
+
+ inline fun get(crossinline action: (CompileTask) -> T): T {
+ try {
+ semaphore.acquire()
+ } catch (e: InterruptedException) {
+ throw CompilationCancellationException(e)
+ }
+ return try {
+ action(task!!)
+ } catch (err: Throwable) {
+ if (!isCancelled(err)) {
+ log.error("An error occurred while working with compilation task", err)
+ }
+ throw err
+ } finally {
+ semaphore.release()
+ }
+ }
+
+ fun post(action: Runnable) = post { action.run() }
+
+ inline fun post(action: () -> Unit) {
+ try {
+ semaphore.acquire()
+ } catch (e: InterruptedException) {
+ throw CompilationCancellationException(e)
+ }
+ isCompiling = true
+ try {
+ if (task != null) {
+ task!!.close()
+ }
+ action()
+ } catch (err: Throwable) {
+ if (!isCancelled(err)) {
+ log.error("An error occurred", err)
+ }
+ throw err
+ } finally {
+ semaphore.release()
+ isCompiling = false
+ }
+ }
+
+ fun setTask(task: CompileTask?) {
+ this.task = task
+ }
+
+ @get:Synchronized
+ val isBusy: Boolean
+ get() = isCompiling || semaphore.availablePermits() == 0
+
+ /**
+ * **FOR INTERNAL USE ONLY!**
+ */
+ fun logStats() {
+ log.warn("[SynchronizedTask] isCompiling =", isCompiling)
+ log.warn("[SynchronizedTask] queuedLength =", semaphore.queueLength)
+ }
+
+ companion object {
+
+ @PublishedApi
+ internal val log: ILogger = ILogger.newInstance("SynchronizedTask")
+ }
+}
\ No newline at end of file