mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
On-demand additional edits computation for Class completion items
This commit is contained in:
Binary file not shown.
@@ -50,6 +50,7 @@ dependencies {
|
||||
implementation androidx.appcompat
|
||||
implementation androidx.ktx
|
||||
implementation common.kotlin
|
||||
implementation common.utilcode
|
||||
implementation google.material
|
||||
|
||||
api project (':build-tools:tooling-api-model')
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package com.itsaky.lsp.models
|
||||
|
||||
import android.os.Looper
|
||||
import com.blankj.utilcode.util.ThreadUtils
|
||||
import com.itsaky.androidide.fuzzysearch.FuzzySearch
|
||||
import com.itsaky.androidide.tooling.api.model.IdeGradleProject
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
@@ -31,6 +33,9 @@ import com.itsaky.lsp.models.MatchLevel.PARTIAL_MATCH
|
||||
import io.github.rosemoe.sora.text.Content
|
||||
import io.github.rosemoe.sora.widget.CodeEditor
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.*
|
||||
import java.util.concurrent.TimeUnit.*
|
||||
import java.util.function.*
|
||||
|
||||
data class CompletionParams(var position: Position, var file: Path) {
|
||||
var content: CharSequence? = null
|
||||
@@ -57,13 +62,12 @@ open class CompletionResult(items: List<CompletionItem>) {
|
||||
val items: List<CompletionItem> = run {
|
||||
var temp = items.toMutableList()
|
||||
temp.sort()
|
||||
|
||||
if (TRIM_TO_MAX && temp.size > MAX_ITEMS) {
|
||||
temp = temp.subList(0, MAX_ITEMS)
|
||||
}
|
||||
return@run temp
|
||||
}
|
||||
|
||||
|
||||
var isIncomplete = this.items.size < items.size
|
||||
var isCached = false
|
||||
|
||||
@@ -88,7 +92,7 @@ open class CompletionResult(items: List<CompletionItem>) {
|
||||
// Max limit has been reached
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (items is MutableList) {
|
||||
this.items.add(item)
|
||||
}
|
||||
@@ -118,6 +122,8 @@ open class CompletionItem(
|
||||
) :
|
||||
io.github.rosemoe.sora.lang.completion.CompletionItem(label, detail), Comparable<CompletionItem> {
|
||||
|
||||
private val log = ILogger.newInstance(javaClass.simpleName)
|
||||
|
||||
var sortText: String? = sortText
|
||||
get() {
|
||||
if (field == null) {
|
||||
@@ -138,6 +144,8 @@ open class CompletionItem(
|
||||
|
||||
var insertTextFormat: InsertTextFormat = insertTextFormat ?: PLAIN_TEXT
|
||||
|
||||
var postComputeAdditionalEdits: Supplier<List<TextEdit>>? = null
|
||||
|
||||
constructor() :
|
||||
this(
|
||||
"", // label
|
||||
@@ -191,6 +199,11 @@ open class CompletionItem(
|
||||
fun getLabel(): String = this.label as String
|
||||
|
||||
override fun performCompletion(editor: CodeEditor, text: Content, line: Int, column: Int) {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
ThreadUtils.runOnUiThread { performCompletion(editor, text, line, column) }
|
||||
return
|
||||
}
|
||||
|
||||
val start = getIdentifierStart(text.getLine(line), column)
|
||||
val shift = insertText.contains("$0")
|
||||
|
||||
@@ -204,7 +217,6 @@ open class CompletionItem(
|
||||
if (i != 0) {
|
||||
commit = "\n" + commit
|
||||
}
|
||||
|
||||
editor.commitText(commit)
|
||||
i++
|
||||
}
|
||||
@@ -223,6 +235,17 @@ open class CompletionItem(
|
||||
}
|
||||
}
|
||||
|
||||
if (postComputeAdditionalEdits != null) {
|
||||
try {
|
||||
log.debug("Computing text edits for selected completion item...")
|
||||
this.additionalTextEdits =
|
||||
CompletableFuture.supplyAsync(postComputeAdditionalEdits).get(200, MILLISECONDS)
|
||||
} catch (e: Throwable) {
|
||||
log.error("Unable to compute additional edits for completion item", e)
|
||||
this.additionalTextEdits = null
|
||||
}
|
||||
}
|
||||
|
||||
if (additionalTextEdits != null && additionalTextEdits!!.isNotEmpty()) {
|
||||
additionalTextEdits!!.forEach {
|
||||
val s = it.range.start
|
||||
@@ -250,17 +273,14 @@ open class CompletionItem(
|
||||
}
|
||||
|
||||
private fun getIdentifierStart(text: CharSequence, end: Int): Int {
|
||||
|
||||
var start = end
|
||||
while (start > 0) {
|
||||
if (Character.isJavaIdentifierPart(text[start - 1])) {
|
||||
start--
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
return start
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public class CompletionProvider extends AbstractServiceProvider implements IComp
|
||||
|
||||
result.markCached();
|
||||
|
||||
if (!result.isIncomplete() && result.getItems().size() > 10) {
|
||||
if (!result.isIncomplete() && !result.getItems().isEmpty()) {
|
||||
LOG.info("...using cached completion");
|
||||
logCompletionDuration(started, result);
|
||||
return result;
|
||||
|
||||
+6
-3
@@ -39,6 +39,7 @@ import com.itsaky.lsp.models.MatchLevel
|
||||
import com.sun.source.tree.Tree
|
||||
import com.sun.source.util.TreePath
|
||||
import java.nio.file.Path
|
||||
import java.util.function.*
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind.ANNOTATION_TYPE
|
||||
import javax.lang.model.element.ElementKind.CLASS
|
||||
@@ -75,7 +76,7 @@ abstract class IJavaCompletionProvider(
|
||||
protected val log: ILogger = ILogger.newInstance(javaClass.name)
|
||||
protected lateinit var filePackage: String
|
||||
protected lateinit var fileImports: Set<String>
|
||||
|
||||
|
||||
open fun complete(
|
||||
task: CompileTask,
|
||||
path: TreePath,
|
||||
@@ -85,7 +86,7 @@ abstract class IJavaCompletionProvider(
|
||||
val root = task.root(completingFile)
|
||||
filePackage = root.`package`.packageName.toString()
|
||||
fileImports = root.imports.map { it.qualifiedIdentifier.toString() }.toSet()
|
||||
return doComplete(task, path, partial, endsWithParen)
|
||||
return doComplete(task, path, partial, endsWithParen);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,7 +202,9 @@ abstract class IJavaCompletionProvider(
|
||||
val data = CompletionData()
|
||||
data.className = className
|
||||
item.data = data
|
||||
item.additionalTextEdits = EditHelper.addImportIfNeeded(compiler, file, imports, className)
|
||||
item.postComputeAdditionalEdits = Supplier {
|
||||
EditHelper.addImportIfNeeded(compiler, file, imports, className)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -179,7 +179,7 @@ class ScopeCompletionProvider(
|
||||
if (item.additionalTextEdits == null) {
|
||||
item.additionalTextEdits = mutableListOf()
|
||||
}
|
||||
|
||||
|
||||
imports.removeIf { "java.lang." == it || fileImports.contains(it) || filePackage == it }
|
||||
if (imports.isNotEmpty()) {
|
||||
for (className in imports) {
|
||||
|
||||
@@ -56,6 +56,7 @@ public class AddImport extends Rewrite {
|
||||
file, new TextEdit[] {new TextEdit(new Range(point, point), text)});
|
||||
}
|
||||
|
||||
@SuppressWarnings("Since15")
|
||||
private Position insertPosition(@NonNull ParseTask task) {
|
||||
List<? extends ImportTree> imports = task.root.getImports();
|
||||
for (ImportTree i : imports) {
|
||||
|
||||
Reference in New Issue
Block a user