@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.CompletionProvider
2020import com.intellij.codeInsight.completion.CompletionResultSet
2121import com.intellij.codeInsight.lookup.LookupElementBuilder
2222import com.intellij.codeInsight.lookup.VariableLookupItem
23+ import com.intellij.openapi.project.Project
2324import com.intellij.psi.PsiClass
2425import com.intellij.psi.PsiDirectory
2526import com.intellij.psi.PsiElement
@@ -33,6 +34,7 @@ import com.intellij.psi.util.elementType
3334import com.intellij.psi.util.prevLeafs
3435import com.intellij.util.ProcessingContext
3536import org.domaframework.doma.intellij.common.dao.findDaoMethod
37+ import org.domaframework.doma.intellij.common.psi.PsiDaoMethod
3638import org.domaframework.doma.intellij.common.psi.PsiParentClass
3739import org.domaframework.doma.intellij.common.psi.PsiPatternUtil
3840import org.domaframework.doma.intellij.common.sql.PsiClassTypeUtil
@@ -271,66 +273,49 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
271273 originalFile : PsiFile ,
272274 result : CompletionResultSet ,
273275 ) {
276+ val daoMethod = findDaoMethod(originalFile)
274277 val searchText = cleanString(getSearchElementText(position))
275278 var topElementType: PsiType ? = null
276- if (elements.isEmpty()) {
277- getElementTypeByFieldAccess(originalFile, elements, result)
279+ if (elements.isEmpty() && daoMethod != null ) {
280+ getElementTypeByFieldAccess(originalFile, elements, daoMethod, result)
278281 return
279282 }
280283 val top = elements.first()
281-
282284 val topText = cleanString(getSearchElementText(top))
283285 val prevWord = PsiPatternUtil .getBindSearchWord(originalFile, elements.last(), " " )
284286 if (prevWord.startsWith(" @" ) && prevWord.endsWith(" @" )) {
285- setStaticFieldAccess (top, prevWord, topText, result)
287+ setCompletionStaticFieldAccess (top, prevWord, topText, result)
286288 return
287289 }
290+
291+ var isBatchAnnotation = false
288292 if (top.parent !is PsiFile && top.parent?.parent !is PsiDirectory ) {
289293 val staticDirective = top.findNodeParent(SqlTypes .EL_STATIC_FIELD_ACCESS_EXPR )
290294 staticDirective?.let {
291295 topElementType = getElementTypeByStaticFieldAccess(top, it, topText) ? : return
292296 }
293297 }
294298
299+ if (daoMethod == null ) return
300+ val project = originalFile.project
301+ val psiDaoMethod = PsiDaoMethod (project, daoMethod)
295302 if (topElementType == null ) {
296- if (isFieldAccessByForItem(top, elements, searchText, result)) return
303+ isBatchAnnotation = psiDaoMethod.daoType.isBatchAnnotation()
304+ if (isFieldAccessByForItem(top, elements, searchText, isBatchAnnotation, result)) return
297305 topElementType =
298- getElementTypeByFieldAccess(originalFile, elements, result) ? : return
306+ getElementTypeByFieldAccess(originalFile, elements, daoMethod, result) ? : return
299307 }
300308
301- var psiParentClass = PsiParentClass (topElementType)
302- // FieldAccess Completion
303- ForDirectiveUtil .getFieldAccessLastPropertyClassType(
309+ setCompletionFieldAccess(
310+ topElementType,
311+ originalFile.project,
312+ isBatchAnnotation,
304313 elements,
305- top.project,
306- psiParentClass,
307- shortName = " " ,
308- dropLastIndex = 1 ,
309- complete = { lastType ->
310- val searchWord = cleanString(getSearchElementText(position))
311- setFieldsAndMethodsCompletionResultSet(
312- lastType.searchField(searchWord)?.toTypedArray() ? : emptyArray(),
313- lastType.searchMethod(searchWord)?.toTypedArray() ? : emptyArray(),
314- result,
315- )
316- },
314+ searchText,
315+ result,
317316 )
318317 }
319318
320- private fun setStaticFieldAccess (
321- top : PsiElement ,
322- prevWord : String ,
323- topText : String ,
324- result : CompletionResultSet ,
325- ) {
326- val clazz = getRefClazz(top) { prevWord.replace(" @" , " " ) } ? : return
327- val matchFields = clazz.searchStaticField(topText)
328- val matchMethod = clazz.searchStaticMethod(topText)
329-
330- // When you enter here, it is the top element, so return static fields and methods.
331- setFieldsAndMethodsCompletionResultSet(matchFields, matchMethod, result)
332- }
333-
334319 private fun getSearchElementText (elm : PsiElement ? ): String =
335320 if (elm is SqlElIdExpr || elm.elementType == SqlTypes .EL_IDENTIFIER ) {
336321 elm?.text ? : " "
@@ -369,9 +354,9 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
369354 private fun getElementTypeByFieldAccess (
370355 originalFile : PsiFile ,
371356 elements : List <PsiElement >,
357+ daoMethod : PsiMethod ,
372358 result : CompletionResultSet ,
373359 ): PsiType ? {
374- val daoMethod = findDaoMethod(originalFile) ? : return null
375360 val topText = cleanString(getSearchElementText(elements.firstOrNull()))
376361 val matchParams = daoMethod.searchParameter(topText)
377362 val findParam = matchParams.find { it.name == topText }
@@ -417,10 +402,10 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
417402 private fun isFieldAccessByForItem (
418403 top : PsiElement ,
419404 elements : List <PsiElement >,
420- positionText : String ,
405+ searchWord : String ,
406+ isBatchAnnotation : Boolean = false,
421407 result : CompletionResultSet ,
422408 ): Boolean {
423- val searchWord = cleanString(positionText)
424409 val project = top.project
425410 val forDirectiveBlocks = ForDirectiveUtil .getForDirectiveBlocks(top)
426411 ForDirectiveUtil .findForItem(top, forDirectives = forDirectiveBlocks) ? : return false
@@ -439,6 +424,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
439424 elements,
440425 project,
441426 topClassType,
427+ isBatchAnnotation = isBatchAnnotation,
442428 shortName = " " ,
443429 dropLastIndex = 1 ,
444430 complete = { lastType ->
@@ -451,4 +437,46 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
451437 )
452438 return result is ValidationCompleteResult
453439 }
440+
441+ private fun setCompletionFieldAccess (
442+ topElementType : PsiType ,
443+ project : Project ,
444+ isBatchAnnotation : Boolean ,
445+ elements : List <PsiElement >,
446+ searchWord : String ,
447+ result : CompletionResultSet ,
448+ ) {
449+ var psiParentClass = PsiParentClass (topElementType)
450+
451+ // FieldAccess Completion
452+ ForDirectiveUtil .getFieldAccessLastPropertyClassType(
453+ elements,
454+ project,
455+ psiParentClass,
456+ isBatchAnnotation = isBatchAnnotation,
457+ shortName = " " ,
458+ dropLastIndex = 1 ,
459+ complete = { lastType ->
460+ setFieldsAndMethodsCompletionResultSet(
461+ lastType.searchField(searchWord)?.toTypedArray() ? : emptyArray(),
462+ lastType.searchMethod(searchWord)?.toTypedArray() ? : emptyArray(),
463+ result,
464+ )
465+ },
466+ )
467+ }
468+
469+ private fun setCompletionStaticFieldAccess (
470+ top : PsiElement ,
471+ prevWord : String ,
472+ topText : String ,
473+ result : CompletionResultSet ,
474+ ) {
475+ val clazz = getRefClazz(top) { prevWord.replace(" @" , " " ) } ? : return
476+ val matchFields = clazz.searchStaticField(topText)
477+ val matchMethod = clazz.searchStaticMethod(topText)
478+
479+ // When you enter here, it is the top element, so return static fields and methods.
480+ setFieldsAndMethodsCompletionResultSet(matchFields, matchMethod, result)
481+ }
454482}
0 commit comments