Skip to content

Commit 8060066

Browse files
committed
perf(devins): optimize Java symbol provider and adjust DevIn completion order
- JavaCustomDevInsSymbolProvider: - Remove package statement processing for better performance - Optimize class, method, and field lookup logic - Add support for qualified class names and methods - DevIn language: - Change DevInCompletionContributor order to "last"
1 parent 0295531 commit 8060066

File tree

1 file changed

+30
-38
lines changed

1 file changed

+30
-38
lines changed

java/src/main/kotlin/cc/unitmesh/idea/provider/JavaCustomDevInsSymbolProvider.kt

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import com.intellij.ide.highlighter.JavaFileType
88
import com.intellij.lang.java.JavaLanguage
99
import com.intellij.openapi.application.runReadAction
1010
import com.intellij.openapi.project.Project
11-
import com.intellij.psi.*
11+
import com.intellij.psi.PsiElement
12+
import com.intellij.psi.PsiManager
13+
import com.intellij.psi.PsiPackageStatement
1214
import com.intellij.psi.impl.file.impl.JavaFileManagerImpl
1315
import com.intellij.psi.search.FileTypeIndex
1416
import com.intellij.psi.search.GlobalSearchScope
@@ -38,25 +40,38 @@ class JavaCustomDevInsSymbolProvider : DevInsSymbolProvider {
3840
): List<LookupElement> {
3941
val lookupElements: MutableList<LookupElement> = SmartList()
4042
val searchScope = ProjectScope.getProjectScope(project)
43+
val javaFiles = FileTypeIndex.getFiles(JavaFileType.INSTANCE, searchScope)
44+
if (javaFiles.isEmpty()) return lookupElements
4145

4246
val prefixMatcher = CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)
4347
result.withPrefixMatcher(prefixMatcher)
4448

4549
val text = parameters.position.text.removePrefix(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED)
4650

51+
val packageStatements = javaFiles.mapNotNull {
52+
val psi = PsiManager.getInstance(project).findFile(it) ?: return@mapNotNull null
53+
PsiTreeUtil.getChildrenOfTypeAsList(psi, PsiPackageStatement::class.java).firstOrNull()
54+
}
55+
56+
packageStatements.forEach {
57+
if (it.packageName.startsWith(text)) {
58+
val element = LookupElementBuilder.create(it.packageName)
59+
.withIcon(JavaFileType.INSTANCE.icon)
60+
.withTypeText("package")
61+
lookupElements.add(element)
62+
}
63+
}
64+
4765
val psiShortNamesCache = PsiShortNamesCache.getInstance(project)
4866
val classNames = psiShortNamesCache.allClassNames
49-
5067
classNames.forEach { className ->
51-
if (className.startsWith(text) || text.isEmpty()) {
52-
val psiClasses = psiShortNamesCache.getClassesByName(className, searchScope)
53-
psiClasses.forEach { psiClass ->
54-
val qualifiedName = psiClass.qualifiedName ?: return@forEach
55-
val element = LookupElementBuilder.create(qualifiedName)
56-
.withIcon(JavaFileType.INSTANCE.icon)
57-
.withTypeText("class")
58-
lookupElements.add(element)
59-
}
68+
val psiClasses = psiShortNamesCache.getClassesByName(className, searchScope)
69+
psiClasses.forEach { psiClass ->
70+
val qualifiedName = psiClass.qualifiedName ?: return@forEach
71+
val element = LookupElementBuilder.create(qualifiedName)
72+
.withIcon(JavaFileType.INSTANCE.icon)
73+
.withTypeText("class")
74+
lookupElements.add(element)
6075
}
6176
}
6277

@@ -72,28 +87,19 @@ class JavaCustomDevInsSymbolProvider : DevInsSymbolProvider {
7287
if (symbol.contains(".").not()) {
7388
val psiClasses = PsiShortNamesCache.getInstance(project).getClassesByName(symbol, scope)
7489
if (psiClasses.isNotEmpty()) {
75-
return psiClasses.mapNotNull { it.qualifiedName }
90+
return psiClasses.map { it.qualifiedName!! }
7691
}
7792
}
7893

7994
// for package name only, like `cc.unitmesh`
8095
JavaFileManagerImpl(project).findPackage(symbol)?.let { pkg ->
81-
return pkg.classes.mapNotNull { it.qualifiedName }
96+
return pkg.classes.map { it.qualifiedName!! }
8297
}
8398

8499
// for single class, with function name, like `cc.unitmesh.idea.provider.JavaCustomDevInsSymbolProvider`
85100
val clazz = JavaFileManagerImpl(project).findClass(symbol, scope)
86101
if (clazz != null) {
87-
// Return class details if no specific method is requested
88-
val classInfo = mutableListOf(clazz.qualifiedName ?: "")
89-
90-
// Add methods information
91-
classInfo.addAll(clazz.methods.map { "${clazz.qualifiedName ?: ""}#${it.name}" })
92-
93-
// Add field information
94-
classInfo.addAll(clazz.fields.map { "${clazz.qualifiedName ?: ""}.${it.name}" })
95-
96-
return classInfo
102+
return clazz.methods.map { "${clazz.qualifiedName}#${it.name}" }
97103
}
98104

99105
// for lookup for method
@@ -148,21 +154,6 @@ class JavaCustomDevInsSymbolProvider : DevInsSymbolProvider {
148154
return lookupElementWithMethodName(project, clazzName, scope, methodName)
149155
}
150156

151-
// for lookup class field
152-
val fieldSplit = symbol.split(".")
153-
if (fieldSplit.size >= 2) {
154-
val className = fieldSplit.dropLast(1).joinToString(".")
155-
val fieldName = fieldSplit.last()
156-
157-
val psiClass = JavaFileManagerImpl(project).findClass(className, scope)
158-
if (psiClass != null) {
159-
val field = psiClass.findFieldByName(fieldName, true)
160-
if (field != null) {
161-
return listOf(field)
162-
}
163-
}
164-
}
165-
166157
// may by not our format, like <package>.<class>.<method> split last
167158
val lastDotIndex = symbol.lastIndexOf(".")
168159
if (lastDotIndex != -1) {
@@ -174,6 +165,7 @@ class JavaCustomDevInsSymbolProvider : DevInsSymbolProvider {
174165
return emptyList()
175166
}
176167

168+
177169
private fun lookupWithMethodName(
178170
project: Project,
179171
clazzName: String,

0 commit comments

Comments
 (0)