@@ -64,6 +64,7 @@ import org.domaframework.doma.intellij.psi.SqlElLeExpr
6464import org.domaframework.doma.intellij.psi.SqlElLtExpr
6565import org.domaframework.doma.intellij.psi.SqlElNeExpr
6666import org.domaframework.doma.intellij.psi.SqlElOrExpr
67+ import org.domaframework.doma.intellij.psi.SqlElParameters
6768import org.domaframework.doma.intellij.psi.SqlElPrimaryExpr
6869import org.domaframework.doma.intellij.psi.SqlTypes
6970import org.jetbrains.kotlin.idea.base.util.module
@@ -164,11 +165,12 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
164165 return prevElms
165166 }
166167 }
168+
167169 // If the parent has field access, get its child element
168- if (targetElement. parent is SqlElFieldAccessExpr ) {
170+ if (parent is SqlElFieldAccessExpr ) {
169171 blocks =
170172 PsiTreeUtil
171- .getChildrenOfTypeAsList(targetElement. parent, PsiElement ::class .java)
173+ .getChildrenOfTypeAsList(parent, PsiElement ::class .java)
172174 .filter {
173175 (
174176 it is SqlElPrimaryExpr ||
@@ -178,7 +180,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
178180 }.toList()
179181 if (blocks.isEmpty()) {
180182 val parent =
181- PsiTreeUtil .findFirstParent(targetElement. parent) {
183+ PsiTreeUtil .findFirstParent(parent) {
182184 it !is PsiDirectory &&
183185 it !is PsiFile &&
184186 it is SqlElFieldAccessExpr
@@ -192,14 +194,38 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
192194 (targetElement.startOffsetInParent) >= it.startOffsetInParent
193195 }.toList()
194196 }
197+ } else {
198+ // Completion for the first argument
199+ var parameterParent: PsiElement ? =
200+ PsiTreeUtil .getParentOfType(targetElement, SqlElParameters ::class .java)
201+ if (parameterParent != null ) {
202+ blocks = emptyList()
203+ } else {
204+ // Completion for subsequent arguments
205+ parameterParent =
206+ targetElement.prevLeafs
207+ .takeWhile {
208+ it.isNotWhiteSpace() &&
209+ it.elementType != SqlTypes .LEFT_PAREN
210+ }.firstOrNull {
211+ PsiTreeUtil .getParentOfType(
212+ it,
213+ SqlElParameters ::class .java,
214+ ) != null
215+ }
216+ if (parameterParent != null ) {
217+ blocks = emptyList()
218+ }
219+ }
195220 }
221+
196222 // If the element has no parent-child relationship,
197223 // create a list that also adds itself at the end.
198224 if (blocks.isEmpty()) {
199225 val prevElms =
200226 targetElement.findSelfBlocks()
201227 if (prevElms.isNotEmpty()) {
202- return prevElms
228+ blocks = prevElms
203229 }
204230 }
205231 return blocks.sortedBy { it.textOffset }
@@ -220,7 +246,8 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
220246 elements.isEmpty() -> return
221247 else -> elements.first()
222248 }
223- val topText = cleanString(top.text)
249+
250+ val topText = cleanString(getSearchElementText(top))
224251 val prevWord = PsiPatternUtil .getBindSearchWord(originalFile, elements.last(), " " )
225252 if (prevWord.startsWith(" @" ) && prevWord.endsWith(" @" )) {
226253 val clazz = getRefClazz(top) { prevWord.replace(" @" , " " ) } ? : return
@@ -252,7 +279,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
252279 var listParamIndex = 0
253280 for (elm in elements.drop(1 )) {
254281 index++
255- val searchElm = cleanString(elm.text )
282+ val searchElm = cleanString(getSearchElementText( elm) )
256283 if (searchElm.isEmpty()) {
257284 setFieldsAndMethodsCompletionResultSet(
258285 (psiParentClass.searchField(searchElm)?.toTypedArray() ? : emptyArray()),
@@ -287,6 +314,18 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
287314 }
288315 }
289316
317+ private fun getSearchElementText (elm : PsiElement ): String =
318+ if (elm is SqlElPrimaryExpr || elm.elementType == SqlTypes .EL_IDENTIFIER ) {
319+ elm.text
320+ } else {
321+ " "
322+ }
323+
324+ /* *
325+ * Retrieves the referenced class from a static field access element
326+ * and searches for a field or method matching the specified identifier name.
327+ * If no match is found, returns null.
328+ */
290329 private fun getElementTypeByStaticFieldAccess (
291330 top : PsiElement ,
292331 staticDirective : PsiElement ,
@@ -295,7 +334,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
295334 val clazz =
296335 getRefClazz(top) {
297336 staticDirective.children
298- .firstOrNull { it.elementType == SqlTypes . EL_CLASS }
337+ .firstOrNull { it is SqlElClass }
299338 ?.text
300339 ? : " "
301340 } ? : return null
@@ -304,6 +343,12 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
304343 ? : clazz.findStaticMethod(topText)?.returnType
305344 }
306345
346+ /* *
347+ * Retrieves the DAO method parameters that match the text of the top element.
348+ * If the element list contains one or fewer items,
349+ * the DAO method parameters are registered as suggestions and this method returns null.
350+ * If there are additional elements, it returns the class type of the top element.
351+ */
307352 private fun getElementTypeByFieldAccess (
308353 originalFile : PsiFile ,
309354 topText : String ,
0 commit comments