@@ -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,8 +34,10 @@ 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
40+ import org.domaframework.doma.intellij.common.sql.PsiClassTypeUtil
3841import org.domaframework.doma.intellij.common.sql.cleanString
3942import org.domaframework.doma.intellij.common.sql.directive.DirectiveCompletion
4043import org.domaframework.doma.intellij.common.sql.validator.result.ValidationCompleteResult
@@ -45,8 +48,6 @@ import org.domaframework.doma.intellij.extension.psi.findNodeParent
4548import org.domaframework.doma.intellij.extension.psi.findSelfBlocks
4649import org.domaframework.doma.intellij.extension.psi.findStaticField
4750import org.domaframework.doma.intellij.extension.psi.findStaticMethod
48- import org.domaframework.doma.intellij.extension.psi.getDomaAnnotationType
49- import org.domaframework.doma.intellij.extension.psi.getIterableClazz
5051import org.domaframework.doma.intellij.extension.psi.isNotWhiteSpace
5152import org.domaframework.doma.intellij.extension.psi.searchParameter
5253import org.domaframework.doma.intellij.extension.psi.searchStaticField
@@ -270,66 +271,49 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
270271 originalFile : PsiFile ,
271272 result : CompletionResultSet ,
272273 ) {
274+ val daoMethod = findDaoMethod(originalFile)
273275 val searchText = cleanString(getSearchElementText(position))
274276 var topElementType: PsiType ? = null
275- if (elements.isEmpty()) {
276- getElementTypeByFieldAccess(originalFile, elements, result)
277+ if (elements.isEmpty() && daoMethod != null ) {
278+ getElementTypeByFieldAccess(originalFile, elements, daoMethod, result)
277279 return
278280 }
279281 val top = elements.first()
280-
281282 val topText = cleanString(getSearchElementText(top))
282283 val prevWord = PsiPatternUtil .getBindSearchWord(originalFile, elements.last(), " " )
283284 if (prevWord.startsWith(" @" ) && prevWord.endsWith(" @" )) {
284- setStaticFieldAccess (top, prevWord, topText, result)
285+ setCompletionStaticFieldAccess (top, prevWord, topText, result)
285286 return
286287 }
288+
289+ var isBatchAnnotation = false
287290 if (top.parent !is PsiFile && top.parent?.parent !is PsiDirectory ) {
288291 val staticDirective = top.findNodeParent(SqlTypes .EL_STATIC_FIELD_ACCESS_EXPR )
289292 staticDirective?.let {
290293 topElementType = getElementTypeByStaticFieldAccess(top, it, topText) ? : return
291294 }
292295 }
293296
297+ if (daoMethod == null ) return
298+ val project = originalFile.project
299+ val psiDaoMethod = PsiDaoMethod (project, daoMethod)
294300 if (topElementType == null ) {
295- if (isFieldAccessByForItem(top, elements, searchText, result)) return
301+ isBatchAnnotation = psiDaoMethod.daoType.isBatchAnnotation()
302+ if (isFieldAccessByForItem(top, elements, searchText, isBatchAnnotation, result)) return
296303 topElementType =
297- getElementTypeByFieldAccess(originalFile, elements, result) ? : return
304+ getElementTypeByFieldAccess(originalFile, elements, daoMethod, result) ? : return
298305 }
299306
300- var psiParentClass = PsiParentClass (topElementType)
301- // FieldAccess Completion
302- ForDirectiveUtil .getFieldAccessLastPropertyClassType(
307+ setCompletionFieldAccess(
308+ topElementType,
309+ originalFile.project,
310+ isBatchAnnotation,
303311 elements,
304- top.project,
305- psiParentClass,
306- shortName = " " ,
307- dropLastIndex = 1 ,
308- complete = { lastType ->
309- val searchWord = cleanString(getSearchElementText(position))
310- setFieldsAndMethodsCompletionResultSet(
311- lastType.searchField(searchWord)?.toTypedArray() ? : emptyArray(),
312- lastType.searchMethod(searchWord)?.toTypedArray() ? : emptyArray(),
313- result,
314- )
315- },
312+ searchText,
313+ result,
316314 )
317315 }
318316
319- private fun setStaticFieldAccess (
320- top : PsiElement ,
321- prevWord : String ,
322- topText : String ,
323- result : CompletionResultSet ,
324- ) {
325- val clazz = getRefClazz(top) { prevWord.replace(" @" , " " ) } ? : return
326- val matchFields = clazz.searchStaticField(topText)
327- val matchMethod = clazz.searchStaticMethod(topText)
328-
329- // When you enter here, it is the top element, so return static fields and methods.
330- setFieldsAndMethodsCompletionResultSet(matchFields, matchMethod, result)
331- }
332-
333317 private fun getSearchElementText (elm : PsiElement ? ): String =
334318 if (elm is SqlElIdExpr || elm.elementType == SqlTypes .EL_IDENTIFIER ) {
335319 elm?.text ? : " "
@@ -368,9 +352,9 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
368352 private fun getElementTypeByFieldAccess (
369353 originalFile : PsiFile ,
370354 elements : List <PsiElement >,
355+ daoMethod : PsiMethod ,
371356 result : CompletionResultSet ,
372357 ): PsiType ? {
373- val daoMethod = findDaoMethod(originalFile) ? : return null
374358 val topText = cleanString(getSearchElementText(elements.firstOrNull()))
375359 val matchParams = daoMethod.searchParameter(topText)
376360 val findParam = matchParams.find { it.name == topText }
@@ -384,8 +368,8 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
384368 if (findParam == null ) {
385369 return null
386370 }
387- val immediate = findParam.getIterableClazz(daoMethod.getDomaAnnotationType())
388- return immediate.type
371+ val immediate = findParam.type
372+ return PsiClassTypeUtil .convertOptionalType( immediate, originalFile.project)
389373 }
390374
391375 private fun getRefClazz (
@@ -416,10 +400,10 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
416400 private fun isFieldAccessByForItem (
417401 top : PsiElement ,
418402 elements : List <PsiElement >,
419- positionText : String ,
403+ searchWord : String ,
404+ isBatchAnnotation : Boolean = false,
420405 result : CompletionResultSet ,
421406 ): Boolean {
422- val searchWord = cleanString(positionText)
423407 val project = top.project
424408 val forDirectiveBlocks = ForDirectiveUtil .getForDirectiveBlocks(top)
425409 ForDirectiveUtil .findForItem(top, forDirectives = forDirectiveBlocks) ? : return false
@@ -438,6 +422,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
438422 elements,
439423 project,
440424 topClassType,
425+ isBatchAnnotation = isBatchAnnotation,
441426 shortName = " " ,
442427 dropLastIndex = 1 ,
443428 complete = { lastType ->
@@ -450,4 +435,46 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
450435 )
451436 return result is ValidationCompleteResult
452437 }
438+
439+ private fun setCompletionFieldAccess (
440+ topElementType : PsiType ,
441+ project : Project ,
442+ isBatchAnnotation : Boolean ,
443+ elements : List <PsiElement >,
444+ searchWord : String ,
445+ result : CompletionResultSet ,
446+ ) {
447+ var psiParentClass = PsiParentClass (topElementType)
448+
449+ // FieldAccess Completion
450+ ForDirectiveUtil .getFieldAccessLastPropertyClassType(
451+ elements,
452+ project,
453+ psiParentClass,
454+ isBatchAnnotation = isBatchAnnotation,
455+ shortName = " " ,
456+ dropLastIndex = 1 ,
457+ complete = { lastType ->
458+ setFieldsAndMethodsCompletionResultSet(
459+ lastType.searchField(searchWord)?.toTypedArray() ? : emptyArray(),
460+ lastType.searchMethod(searchWord)?.toTypedArray() ? : emptyArray(),
461+ result,
462+ )
463+ },
464+ )
465+ }
466+
467+ private fun setCompletionStaticFieldAccess (
468+ top : PsiElement ,
469+ prevWord : String ,
470+ topText : String ,
471+ result : CompletionResultSet ,
472+ ) {
473+ val clazz = getRefClazz(top) { prevWord.replace(" @" , " " ) } ? : return
474+ val matchFields = clazz.searchStaticField(topText)
475+ val matchMethod = clazz.searchStaticMethod(topText)
476+
477+ // When you enter here, it is the top element, so return static fields and methods.
478+ setFieldsAndMethodsCompletionResultSet(matchFields, matchMethod, result)
479+ }
453480}
0 commit comments