Skip to content

Commit 4dd0725

Browse files
committed
Add package and Class name suggestions
1 parent bf230a7 commit 4dd0725

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

src/main/kotlin/org/domaframework/doma/intellij/common/FileTypeCheck.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ fun isJavaOrKotlinFileType(daoFile: PsiFile): Boolean {
4646
}
4747
}
4848

49+
fun isJavaOrKotlinFileType(file: VirtualFile): Boolean {
50+
val fileType = file.fileType
51+
return when (fileType.name) {
52+
"JAVA", "Kotlin", "CLASS" -> true
53+
else -> false
54+
}
55+
}
56+
4957
/*
5058
* Determine whether the open file is an SQL template file extension
5159
*/

src/main/kotlin/org/domaframework/doma/intellij/common/sql/directive/StaticDirectiveHandler.kt

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,30 @@
1616
package org.domaframework.doma.intellij.common.sql.directive
1717

1818
import com.intellij.codeInsight.completion.CompletionResultSet
19+
import com.intellij.codeInsight.lookup.AutoCompletionPolicy
1920
import com.intellij.codeInsight.lookup.LookupElement
2021
import com.intellij.codeInsight.lookup.LookupElementBuilder
2122
import com.intellij.codeInsight.lookup.VariableLookupItem
2223
import com.intellij.openapi.project.Project
24+
import com.intellij.openapi.vfs.VirtualFile
2325
import com.intellij.psi.PsiElement
26+
import com.intellij.psi.PsiFile
2427
import com.intellij.psi.PsiManager
2528
import com.intellij.psi.PsiType
2629
import com.intellij.psi.search.GlobalSearchScope
2730
import com.intellij.psi.util.PsiTreeUtil
2831
import com.intellij.psi.util.elementType
32+
import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType
2933
import org.domaframework.doma.intellij.common.psi.PsiParentClass
34+
import org.domaframework.doma.intellij.common.psi.PsiPatternUtil
3035
import org.domaframework.doma.intellij.common.psi.PsiStaticElement
36+
import org.domaframework.doma.intellij.common.sql.cleanString
37+
import org.domaframework.doma.intellij.extension.getContentRoot
3138
import org.domaframework.doma.intellij.extension.psi.psiClassType
3239
import org.domaframework.doma.intellij.psi.SqlElClass
3340
import org.domaframework.doma.intellij.psi.SqlElStaticFieldAccessExpr
3441
import org.domaframework.doma.intellij.psi.SqlTypes
42+
import org.jetbrains.kotlin.idea.util.getSourceRoot
3543

3644
class StaticDirectiveHandler(
3745
private val originalFile: PsiElement,
@@ -80,7 +88,63 @@ class StaticDirectiveHandler(
8088
CompletionSuggest(fields ?: emptyList(), methods ?: emptyList())
8189
}
8290
}
83-
} else if (element.prevSibling?.elementType == SqlTypes.AT_SIGN) {
91+
}
92+
if (handleResult) return true
93+
94+
if (PsiTreeUtil.nextLeaf(element)?.elementType == SqlTypes.AT_SIGN ||
95+
element.elementType == SqlTypes.AT_SIGN
96+
) {
97+
handleResult =
98+
staticClassPath(
99+
result,
100+
) { file, root ->
101+
val rootChildren = root.children
102+
if (PsiTreeUtil.prevLeaf(element)?.elementType == SqlTypes.AT_SIGN) {
103+
return@staticClassPath rootChildren.map {
104+
LookupElementBuilder
105+
.create(it.name)
106+
.withAutoCompletionPolicy(AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE)
107+
}
108+
} else {
109+
val prevPackageNames =
110+
PsiPatternUtil.getBindSearchWord(file, element, "@").split(".")
111+
val topPackage =
112+
rootChildren.firstOrNull { it.name == prevPackageNames.firstOrNull() }
113+
?: return@staticClassPath null
114+
var nextPackage: VirtualFile? =
115+
topPackage
116+
if (prevPackageNames.size > 2) {
117+
for (packageName in prevPackageNames.drop(1).dropLast(1)) {
118+
if (nextPackage == null) break
119+
nextPackage =
120+
nextPackage.children.firstOrNull {
121+
it.name == cleanString(packageName)
122+
}
123+
}
124+
}
125+
return@staticClassPath nextPackage
126+
?.children
127+
?.filter {
128+
it.name.contains(cleanString(prevPackageNames.lastOrNull() ?: ""))
129+
}?.map {
130+
val packageName = prevPackageNames.joinToString(".").plus(it.nameWithoutExtension)
131+
val suggestName =
132+
it.nameWithoutExtension
133+
if (!isJavaOrKotlinFileType(it)) {
134+
suggestName.plus(".")
135+
}
136+
LookupElementBuilder
137+
.create(packageName)
138+
.withPresentableText(suggestName)
139+
.withTailText("($packageName)", true)
140+
.withAutoCompletionPolicy(AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE)
141+
}
142+
}
143+
}
144+
}
145+
if (handleResult) return true
146+
147+
if (element.prevSibling?.elementType == SqlTypes.AT_SIGN) {
84148
// Built-in function completion
85149
handleResult =
86150
builtInDirectiveHandler(element, result) { bind ->
@@ -208,13 +272,31 @@ class StaticDirectiveHandler(
208272
return true
209273
}
210274

275+
private fun staticClassPath(
276+
result: CompletionResultSet,
277+
processor: (PsiFile, VirtualFile) -> List<LookupElement>?,
278+
): Boolean {
279+
val file = originalFile.containingFile ?: return false
280+
val virtualFile = file.virtualFile ?: return false
281+
val root =
282+
project
283+
.getContentRoot(virtualFile)
284+
?.children
285+
?.firstOrNull()
286+
?.getSourceRoot(project)
287+
?: return false
288+
val candidates = processor(file, root) ?: return false
289+
result.addAllElements(candidates)
290+
return true
291+
}
292+
211293
private fun builtInDirectiveHandler(
212294
element: PsiElement,
213295
result: CompletionResultSet,
214296
processor: (String) -> List<LookupElement>?,
215297
): Boolean {
216298
if (BindDirectiveUtil.getDirectiveType(element) == DirectiveType.BUILT_IN) {
217-
val prefix = getBindSearchWord(element, "@")
299+
val prefix = getBindSearchWord(element, bindText)
218300
val candidates = processor(prefix)
219301
candidates?.let { it1 -> result.addAllElements(it1) }
220302
return true

0 commit comments

Comments
 (0)