diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 044a333a8..2023913fd 100755 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -99,6 +99,12 @@ + + + + + + diff --git a/app/src/main/assets/data/common/tooling-api-all.jar b/app/src/main/assets/data/common/tooling-api-all.jar index 00f08db7e..c9316a443 100644 Binary files a/app/src/main/assets/data/common/tooling-api-all.jar and b/app/src/main/assets/data/common/tooling-api-all.jar differ diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt b/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt index 59d967ce6..c5ff5e079 100644 --- a/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt +++ b/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt @@ -74,7 +74,7 @@ class CommonCompletionProvider(private val server: ILanguageServer) { } // Do not log if completion was interrupted or cancelled - if (!(e is ProcessCancelledException || e is CompletionCancelledException)) { + if (!(e is ProcessCancelledException || e is CompletionCancelledException)) { if (!server.handleFailure(LSPFailure(COMPLETION, e))) { log.error("Unable to compute completions", e) } diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java index 7a97d2189..df9b9eb09 100644 --- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java +++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java @@ -95,7 +95,7 @@ public class CompileBatch implements AutoCloseable { private void processCompilationUnit(final CompilationUnitTree root) { roots.add(root); - updatePositions(root, false); +// updatePositions(root, false); } void updatePositions(CompilationUnitTree tree, boolean allowDuplicate) { diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt index ee9c70ef7..e644fa01e 100644 --- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt +++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt @@ -37,8 +37,12 @@ class DefaultCompilationTaskProcessor : CompilationTaskProcessor { trees.forEach(processCompilationUnit::accept) watch.lapFromLast("Processed trees") - - task.analyze() + + val entered = JavacTaskUtil.enterTrees(task, trees) + watch.lapFromLast("Entered trees") + + val analyzed = JavacTaskUtil.analyze(task, entered) +// task.analyze() watch.lapFromLast("Analyzed all trees") } } 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 32d3cf36c..fddde3797 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 @@ -269,22 +269,22 @@ public class JavaCompilerService implements CompilerProvider { } private synchronized void reparseOrRecompile(CompilationRequest request) { - if (needsRecompilation(request)) { - LOG.warn("Cannot reparse. Recompilation is required"); +// if (needsRecompilation(request)) { +// LOG.warn("Cannot reparse. Recompilation is required"); recompile(request); - } else { - LOG.debug("Trying to perform a reparse..."); - tryReparse(request); - } +// } else { +// LOG.debug("Trying to perform a reparse..."); +// tryReparse(request); +// } } private boolean needsRecompilation(final CompilationRequest request) { return this.cachedCompile == null - || this.cachedCompile.closed - || request.partialRequest == null - || request.partialRequest.cursor < 0 - || !isChangeValidForReparse() - || request.sources.size() != 1; // Cannot perform a reparse if there are multiple files + || this.cachedCompile.closed; +// || request.partialRequest == null +// || request.partialRequest.cursor < 0 +// || !isChangeValidForReparse() +// || request.sources.size() != 1; // Cannot perform a reparse if there are multiple files } private boolean isChangeValidForReparse() { 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 c3d66387d..45f52075f 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 @@ -43,10 +43,12 @@ import com.itsaky.androidide.lsp.java.providers.completion.MemberSelectCompletio import com.itsaky.androidide.lsp.java.providers.completion.SwitchConstantCompletionProvider; import com.itsaky.androidide.lsp.java.providers.completion.TopLevelSnippetsProvider; import com.itsaky.androidide.lsp.java.utils.ASTFixer; +import com.itsaky.androidide.lsp.java.utils.CancelChecker; import com.itsaky.androidide.lsp.java.visitors.FindCompletionsAt; import com.itsaky.androidide.lsp.java.visitors.PruneMethodBodies; import com.itsaky.androidide.lsp.models.CompletionParams; import com.itsaky.androidide.lsp.models.CompletionResult; +import com.itsaky.androidide.progress.ProcessCancelledException; import com.itsaky.androidide.utils.DocumentUtils; import com.itsaky.androidide.utils.ILogger; import com.itsaky.androidide.utils.StopWatch; @@ -104,6 +106,13 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp abortIfCancelled(); abortCompletionIfCancelled(); return completeInternal(params); + } catch (Throwable err) { + if (CancelChecker.isCancelled(err)) { + LOG.info("Completion request cancelled"); + } else { + LOG.error("An error occurred while computing completions", err); + } + throw err; } finally { completing.set(false); } diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt index e49481907..9c4a337de 100644 --- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt +++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt @@ -25,7 +25,6 @@ import com.itsaky.androidide.lsp.models.DiagnosticItem import com.itsaky.androidide.lsp.models.DiagnosticSeverity import com.itsaky.androidide.lsp.models.DiagnosticSeverity.WARNING import com.itsaky.androidide.models.Range -import com.itsaky.androidide.progress.ProgressManager import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled import com.itsaky.androidide.projects.FileManager import com.itsaky.androidide.utils.DocumentUtils.isSameFile @@ -37,11 +36,10 @@ import com.sun.source.tree.MethodTree import com.sun.source.tree.VariableTree import com.sun.source.util.TreePath import com.sun.source.util.Trees -import com.sun.tools.javac.code.Symbol.ClassSymbol import java.nio.file.Path import java.nio.file.Paths -import java.util.* -import java.util.regex.* +import java.util.Locale +import java.util.regex.Pattern import javax.lang.model.element.Element import javax.tools.Diagnostic import javax.tools.JavaFileObject @@ -74,15 +72,15 @@ object DiagnosticsProvider { break } } - + abortIfCancelled() - + if (root == null) { // CompilationUnitTree for the file was not found // Can't do anything... return result } - + addCompilerErrors(task, root, result) abortIfCancelled() addDiagnosticsByVisiting(task, root, result) diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt index 818959cc5..1f4a3381a 100644 --- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt +++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt @@ -84,12 +84,17 @@ class JavaDiagnosticProvider { } private fun doAnalyze(file: Path, task: CompileTask): DiagnosticResult { - return if (!isTaskValid(task)) { - // Do not use Collections.emptyList () - // The returned list is accessed and the list returned by Collections.emptyList() - // throws exception when trying to access. - cachedDiagnostics - } else DiagnosticResult(file, findDiagnostics(task, file).sortedBy { it.range }) + val result = + if (!isTaskValid(task)) { + // Do not use Collections.emptyList () + // The returned list is accessed and the list returned by Collections.emptyList() + // throws exception when trying to access. + log.info("Using cached diagnostics") + cachedDiagnostics + } else DiagnosticResult(file, findDiagnostics(task, file).sortedBy { it.range }) + return result.also { + log.info("Analyze file completed. Found ${result.diagnostics.size} diagnostic items") + } } private fun isTaskValid(task: CompileTask?): Boolean { @@ -105,11 +110,11 @@ class JavaDiagnosticProvider { try { compiler.compile(file).get { task -> doAnalyze(file, task) } } catch (err: Throwable) { - - if (!CancelChecker.isCancelled(err)) { + if (CancelChecker.isCancelled(err)) { + log.error("Analyze request cancelled") + } else { log.warn("Unable to analyze file", err) } - DiagnosticResult.NO_UPDATE } finally { compiler.destroy() diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt index 778f208b2..1994a5b93 100644 --- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt +++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt @@ -30,6 +30,7 @@ import com.sun.source.tree.MemberSelectTree import com.sun.source.tree.Scope import com.sun.source.util.TreePath import com.sun.source.util.Trees +import com.sun.tools.javac.code.Symbol import java.nio.file.Path import javax.lang.model.element.ElementKind.CONSTRUCTOR import javax.lang.model.element.ElementKind.METHOD @@ -59,7 +60,13 @@ class MemberSelectCompletionProvider( endsWithParen: Boolean, ): CompletionResult { val trees = Trees.instance(task.task) - val select = path.leaf as MemberSelectTree + val select = + path.leaf as? MemberSelectTree + ?: run { + log.error("A member select tree was expected but was ${path.leaf.javaClass}") + return CompletionResult.EMPTY + } + log.info("...complete members of " + select.expression) val exprPath = TreePath(path, select.expression) @@ -140,6 +147,8 @@ class MemberSelectCompletionProvider( val methods = mutableMapOf>() val matchLevels = mutableMapOf() + log.debug("DeclaredType $typeElement with members ${(typeElement as Symbol).members()} in scope: $scope") + abortIfCancelled() abortCompletionIfCancelled() for (member in task.task.elements.getAllMembers(typeElement)) { @@ -167,6 +176,8 @@ class MemberSelectCompletionProvider( } } + log.debug("Found ${list.size} members along with ${methods.size} methods") + abortIfCancelled() abortCompletionIfCancelled() for ((key, value) in methods) { diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java index 6de80d07c..7875f6e26 100644 --- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java +++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java @@ -37,7 +37,7 @@ public class ScopeHelper { Trees trees = Trees.instance(task.task); Elements elements = task.task.getElements(); boolean isStatic = false; - List list = new ArrayList(); + List list = new ArrayList<>(); for (Scope scope : fastScopes(inner)) { if (scope.getEnclosingMethod() != null) { isStatic = isStatic || scope.getEnclosingMethod().getModifiers().contains(Modifier.STATIC); @@ -88,9 +88,7 @@ public class ScopeHelper { // Scopes may be contained in an enclosing scope. // The outermost scope contains those elements available via "star import" declarations; // the scope within that contains the top level elements of the compilation unit, including - // any - // named - // imports. + // any named imports. // https://parent.docs.oracle.com/en/java/javase/11/docs/api/jdk.compiler/com/sun/source/tree/Scope.html return scopes.subList(0, scopes.size() - 2); } diff --git a/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt b/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt index 30ab03bd2..a0c0d32a1 100644 --- a/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt +++ b/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt @@ -24,12 +24,13 @@ package com.itsaky.androidide.utils * @param label The label for the log message. * @author Akash Yadav */ -class StopWatch( +class StopWatch +@JvmOverloads +constructor( val label: String, val start: Long = System.currentTimeMillis(), var lastLap: Long = start ) { - constructor(label: String) : this(label, System.currentTimeMillis()) private val log = ILogger.newInstance(javaClass.simpleName) diff --git a/subprojects/javac/build.gradle.kts b/subprojects/javac/build.gradle.kts index adabae9fa..87ef432aa 100644 --- a/subprojects/javac/build.gradle.kts +++ b/subprojects/javac/build.gradle.kts @@ -33,7 +33,8 @@ configurations.all { dependencies { - api (libs.androidide.javac) { - isChanging = true - } + api(files("libs/nb-javac-17.0.0.4-android.jar")) +// api (libs.androidide.javac) { +// isChanging = true +// } } \ No newline at end of file diff --git a/subprojects/javac/libs/nb-javac-17.0.0.4-android.jar b/subprojects/javac/libs/nb-javac-17.0.0.4-android.jar new file mode 100644 index 000000000..1b10bf6a4 Binary files /dev/null and b/subprojects/javac/libs/nb-javac-17.0.0.4-android.jar differ