Skip to content

Commit 6bbaeae

Browse files
committed
Support custom functions and improve method collection logic
1 parent db2aec6 commit 6bbaeae

File tree

2 files changed

+62
-115
lines changed

2 files changed

+62
-115
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class StaticDirectiveHandler(
9595
): Boolean {
9696
if (BindDirectiveUtil.getDirectiveType(element) == DirectiveType.BUILT_IN) {
9797
val prefix = getBindSearchWord(element, bindText)
98-
val collector = StaticBuildFunctionCollector(project, prefix)
98+
val collector = StaticBuildFunctionCollector(element.project, prefix)
9999
val candidates = collector.collect()
100100
candidates?.let { it1 -> result.addAllElements(it1) }
101101
return true

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

Lines changed: 61 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -18,126 +18,73 @@ package org.domaframework.doma.intellij.common.sql.directive.collector
1818
import com.intellij.codeInsight.lookup.LookupElement
1919
import com.intellij.codeInsight.lookup.LookupElementBuilder
2020
import com.intellij.openapi.project.Project
21-
import com.intellij.psi.PsiManager
22-
import com.intellij.psi.PsiType
23-
import com.intellij.psi.search.GlobalSearchScope
24-
import org.domaframework.doma.intellij.common.sql.directive.DomaFunction
21+
import com.intellij.psi.PsiMethod
22+
import com.intellij.psi.PsiModifier
23+
import org.domaframework.doma.intellij.common.helper.ExpressionFunctionsHelper
24+
import org.domaframework.doma.intellij.common.psi.PsiParentClass
25+
import org.domaframework.doma.intellij.extension.getJavaClazz
26+
import org.domaframework.doma.intellij.extension.psi.psiClassType
27+
import org.domaframework.doma.intellij.setting.state.DomaToolsCustomFunctionSettings
28+
import kotlin.collections.mutableSetOf
2529

2630
class StaticBuildFunctionCollector(
2731
private val project: Project,
2832
private val bind: String,
2933
) : StaticDirectiveHandlerCollector() {
30-
public override fun collect(): List<LookupElement>? =
31-
listOf(
32-
DomaFunction(
33-
"escape",
34-
getJavaLangString(),
35-
listOf(
36-
getPsiTypeByClassName("java.lang.CharSequence"),
37-
getPsiTypeByClassName("java.lang.Char"),
38-
),
39-
),
40-
DomaFunction(
41-
"prefix",
42-
getJavaLangString(),
43-
listOf(
44-
getPsiTypeByClassName("java.lang.CharSequence"),
45-
getPsiTypeByClassName("java.lang.Char"),
46-
),
47-
),
48-
DomaFunction(
49-
"infix",
50-
getJavaLangString(),
51-
listOf(
52-
getPsiTypeByClassName("java.lang.CharSequence"),
53-
getPsiTypeByClassName("java.lang.Char"),
54-
),
55-
),
56-
DomaFunction(
57-
"suffix",
58-
getJavaLangString(),
59-
listOf(
60-
getPsiTypeByClassName("java.lang.CharSequence"),
61-
getPsiTypeByClassName("java.lang.Char"),
62-
),
63-
),
64-
DomaFunction(
65-
"roundDownTimePart",
66-
getPsiTypeByClassName("java.util.Date"),
67-
listOf(getPsiTypeByClassName("java.util.Date")),
68-
),
69-
DomaFunction(
70-
"roundDownTimePart",
71-
getPsiTypeByClassName("java.sql.Date"),
72-
listOf(getPsiTypeByClassName("java.util.Date")),
73-
),
74-
DomaFunction(
75-
"roundDownTimePart",
76-
getPsiTypeByClassName("java.sql.Timestamp"),
77-
listOf(getPsiTypeByClassName("java.sql.Timestamp")),
78-
),
79-
DomaFunction(
80-
"roundDownTimePart",
81-
getPsiTypeByClassName("java.time.LocalDateTime"),
82-
listOf(getPsiTypeByClassName("java.time.LocalDateTime")),
83-
),
84-
DomaFunction(
85-
"roundUpTimePart",
86-
getPsiTypeByClassName("java.util.Date"),
87-
listOf(getPsiTypeByClassName("java.sql.Date")),
88-
),
89-
DomaFunction(
90-
"roundUpTimePart",
91-
getPsiTypeByClassName("java.sql.Timestamp"),
92-
listOf(getPsiTypeByClassName("java.sql.Timestamp")),
93-
),
94-
DomaFunction(
95-
"roundUpTimePart",
96-
getPsiTypeByClassName("java.time.LocalDate"),
97-
listOf(getPsiTypeByClassName("java.time.LocalDate")),
98-
),
99-
DomaFunction(
100-
"isEmpty",
101-
getPsiTypeByClassName("boolean"),
102-
listOf(getPsiTypeByClassName("java.lang.CharSequence")),
103-
),
104-
DomaFunction(
105-
"isNotEmpty",
106-
getPsiTypeByClassName("boolean"),
107-
listOf(getPsiTypeByClassName("java.lang.CharSequence")),
108-
),
109-
DomaFunction(
110-
"isBlank",
111-
getPsiTypeByClassName("boolean"),
112-
listOf(getPsiTypeByClassName("java.lang.CharSequence")),
113-
),
114-
DomaFunction(
115-
"isNotBlank",
116-
getPsiTypeByClassName("boolean"),
117-
listOf(getPsiTypeByClassName("java.lang.CharSequence")),
118-
),
119-
).filter {
120-
it.name.startsWith(bind.substringAfter("@"))
121-
}.map {
122-
LookupElementBuilder
123-
.create("${it.name}()")
124-
.withPresentableText(it.name)
125-
.withTailText(
126-
"(${
127-
it.parameters.joinToString(",") { param ->
128-
param.toString().replace("PsiType:", "")
129-
}
130-
})",
131-
true,
132-
).withTypeText(it.returnType.presentableText)
34+
public override fun collect(): List<LookupElement>? {
35+
var functions = mutableSetOf<PsiMethod>()
36+
val setting = DomaToolsCustomFunctionSettings.getInstance(project)
37+
val state = setting.state
38+
val customFunctions = state.customFunctionClassNames
39+
40+
val expressionFunctionInterface =
41+
ExpressionFunctionsHelper.setExpressionFunctionsInterface(project)
42+
?: return null
43+
44+
customFunctions.forEach { function ->
45+
val expressionClazz = project.getJavaClazz(function)
46+
if (expressionClazz != null &&
47+
ExpressionFunctionsHelper.isInheritor(expressionClazz)
48+
) {
49+
val psiParent = PsiParentClass(expressionClazz.psiClassType)
50+
psiParent.searchMethod("")?.let { methods ->
51+
functions.addAll(
52+
methods.filter {
53+
isPublicFunction(it)
54+
},
55+
)
56+
}
57+
}
58+
}
59+
60+
if (functions.isEmpty()) {
61+
functions.addAll(
62+
expressionFunctionInterface.allMethods.filter {
63+
isPublicFunction(it)
64+
},
65+
)
13366
}
13467

135-
private fun getJavaLangString(): PsiType =
136-
PsiType.getJavaLangString(
137-
PsiManager.getInstance(project),
138-
GlobalSearchScope.allScope(project),
139-
)
68+
return functions
69+
.filter {
70+
it.name.startsWith(bind.substringAfter("@"))
71+
}.map {
72+
val parameters = it.parameterList.parameters.toList()
73+
LookupElementBuilder
74+
.create("${it.name}()")
75+
.withPresentableText(it.name)
76+
.withTailText(
77+
"(${
78+
parameters.joinToString(",") { "${it.type.presentableText} ${it.name}" }
79+
})",
80+
true,
81+
).withTypeText(it.returnType?.presentableText ?: "void")
82+
}
83+
}
14084

141-
private fun getPsiTypeByClassName(className: String): PsiType =
142-
PsiType.getTypeByName(className, project, GlobalSearchScope.allScope(project))
85+
private fun isPublicFunction(method: PsiMethod): Boolean =
86+
!method.isConstructor &&
87+
method.hasModifierProperty(
88+
PsiModifier.PUBLIC,
89+
)
14390
}

0 commit comments

Comments
 (0)