Skip to content

Commit e0451b8

Browse files
committed
Support for directive definition items in reference resolution
1 parent 76708fb commit e0451b8

File tree

8 files changed

+173
-190
lines changed

8 files changed

+173
-190
lines changed

src/main/kotlin/org/domaframework/doma/intellij/common/sql/validator/SqlElChildElementValidator.kt

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,51 @@ abstract class SqlElChildElementValidator(
3434
open val blocks: List<PsiElement>,
3535
open val shorName: String,
3636
) {
37-
abstract fun validateChildren(): ValidationResult?
37+
abstract fun validateChildren(dropIndex: Int = 0): ValidationResult?
3838

3939
open fun validateChildren(
40+
dropIndex: Int = 0,
4041
findFieldMethod: (PsiType) -> PsiParentClass = { type: PsiType -> PsiParentClass(type) },
4142
complete: (PsiParentClass) -> Unit,
4243
): ValidationResult? = null
4344

4445
protected fun validateFieldAccess(
4546
topParent: PsiParentClass,
47+
dropLastIndex: Int = 0,
48+
findFieldMethod: ((PsiType) -> PsiParentClass)? = { type -> PsiParentClass(type) },
49+
complete: ((PsiParentClass) -> Unit) = { parent: PsiParentClass? -> },
50+
): ValidationResult? =
51+
getFieldAccessParentClass(
52+
topParent,
53+
dropLastIndex,
54+
findFieldMethod = findFieldMethod,
55+
complete = complete,
56+
)
57+
58+
protected fun getFieldAccessParentClass(
59+
topParent: PsiParentClass,
60+
dropLastIndex: Int = 0,
4661
findFieldMethod: ((PsiType) -> PsiParentClass)? = { type -> PsiParentClass(type) },
4762
complete: ((PsiParentClass) -> Unit) = { parent: PsiParentClass? -> },
4863
): ValidationResult? {
4964
var parent = topParent
5065
var competeResult: ValidationCompleteResult? = null
5166

67+
if (dropLastIndex > 0 && blocks.drop(1).dropLast(dropLastIndex).isEmpty()) {
68+
return ValidationCompleteResult(
69+
blocks.last(),
70+
parent,
71+
)
72+
}
73+
5274
var getMethodReturnType: PsiType? =
5375
if (PsiClassTypeUtil.isCollect(topParent.type)) {
5476
topParent.type
5577
} else {
5678
null
5779
}
5880
var listParamIndex = 0
59-
for (element in blocks.drop(1)) {
81+
for (element in blocks.drop(1).dropLast(dropLastIndex)) {
6082
val searchElm = cleanString(getSearchElementText(element))
6183
if (searchElm.isEmpty()) {
6284
complete.invoke(parent)

src/main/kotlin/org/domaframework/doma/intellij/common/sql/validator/SqlElFieldAccessorChildElementValidator.kt

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiParameter
2121
import com.intellij.psi.PsiType
2222
import org.domaframework.doma.intellij.common.dao.findDaoMethod
2323
import org.domaframework.doma.intellij.common.psi.PsiParentClass
24+
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationCompleteResult
2425
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationDaoParamResult
2526
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationResult
2627
import org.domaframework.doma.intellij.extension.psi.findParameter
@@ -34,33 +35,33 @@ class SqlElFieldAccessorChildElementValidator(
3435
private val topDaoParameter: PsiParameter? = null,
3536
) : SqlElChildElementValidator(blocks, shorName) {
3637
override fun validateChildren(
38+
dropIndex: Int,
3739
findFieldMethod: (PsiType) -> PsiParentClass,
3840
complete: (PsiParentClass) -> Unit,
3941
): ValidationResult? {
40-
val daoMethod = findDaoMethod(file) ?: return null
41-
val topElement: PsiElement = blocks.firstOrNull() ?: return null
42-
val validDaoParam =
43-
topDaoParameter
44-
?: daoMethod.findParameter(topElement.text)
45-
46-
if (validDaoParam == null) {
47-
return ValidationDaoParamResult(
48-
topElement,
49-
daoMethod.name,
50-
shorName,
42+
val parentClassResult = getParentClass()
43+
val parentClass = parentClassResult?.parentClass
44+
if (parentClassResult is ValidationCompleteResult && parentClass != null) {
45+
return validateFieldAccess(
46+
parentClass,
47+
complete = complete,
5148
)
5249
}
5350

54-
val parentClass =
55-
validDaoParam.getIterableClazz(daoMethod.getDomaAnnotationType())
51+
return parentClassResult
52+
}
5653

57-
return validateFieldAccess(
58-
parentClass,
59-
complete = complete,
60-
)
54+
override fun validateChildren(dropIndex: Int): ValidationResult? {
55+
val parentClassResult = getParentClass()
56+
val parentClass = parentClassResult?.parentClass
57+
if (parentClassResult is ValidationCompleteResult && parentClass != null) {
58+
return validateFieldAccess(parentClass)
59+
}
60+
61+
return parentClassResult
6162
}
6263

63-
override fun validateChildren(): ValidationResult? {
64+
private fun getParentClass(): ValidationResult? {
6465
val daoMethod = findDaoMethod(file) ?: return null
6566
val topElement: PsiElement = blocks.firstOrNull() ?: return null
6667
val validDaoParam =
@@ -75,9 +76,9 @@ class SqlElFieldAccessorChildElementValidator(
7576
)
7677
}
7778

78-
val parentClass =
79-
validDaoParam.getIterableClazz(daoMethod.getDomaAnnotationType())
80-
81-
return validateFieldAccess(parentClass)
79+
return ValidationCompleteResult(
80+
topElement,
81+
validDaoParam.getIterableClazz(daoMethod.getDomaAnnotationType()),
82+
)
8283
}
8384
}

src/main/kotlin/org/domaframework/doma/intellij/common/sql/validator/SqlElForItemFieldAccessorChildElementValidator.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ class SqlElForItemFieldAccessorChildElementValidator(
2626
override val shorName: String = "",
2727
) : SqlElChildElementValidator(blocks, shorName) {
2828
override fun validateChildren(
29+
dropIndex: Int,
2930
findFieldMethod: (PsiType) -> PsiParentClass,
3031
complete: (PsiParentClass) -> Unit,
3132
): ValidationResult? =
3233
validateFieldAccess(
3334
declarationType,
35+
dropIndex,
3436
complete = complete,
3537
)
3638

37-
override fun validateChildren(): ValidationResult? = validateFieldAccess(declarationType)
39+
override fun validateChildren(dropIndex: Int): ValidationResult? = validateFieldAccess(declarationType, dropIndex)
3840
}

src/main/kotlin/org/domaframework/doma/intellij/common/sql/validator/SqlElStaticFieldAccessorChildElementValidator.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class SqlElStaticFieldAccessorChildElementValidator(
3535
override val shorName: String,
3636
) : SqlElChildElementValidator(blocks, shorName) {
3737
override fun validateChildren(
38+
dropIndex: Int,
3839
findFieldMethod: (PsiType) -> PsiParentClass,
3940
complete: (PsiParentClass) -> Unit,
4041
): ValidationResult? {
@@ -52,7 +53,7 @@ class SqlElStaticFieldAccessorChildElementValidator(
5253
}
5354
}
5455

55-
override fun validateChildren(): ValidationResult? {
56+
override fun validateChildren(dropIndex: Int): ValidationResult? {
5657
val getParentResult = getParent()
5758
when (getParentResult) {
5859
is ValidationCompleteResult -> {

src/main/kotlin/org/domaframework/doma/intellij/contributor/sql/provider/SqlParameterCompletionProvider.kt

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,29 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
265265
}
266266

267267
if (topElementType == null) {
268-
topElementType = getTopElementClassType(top, elements, originalFile, topText, result) ?: return
268+
val forDeclaration = ForDirectiveInspection("")
269+
val forItem = forDeclaration.getForItem(top)
270+
if (forItem != null) {
271+
val errorElement = forDeclaration.checkForItem(elements)
272+
if (errorElement is ValidationCompleteResult) {
273+
topElementType = errorElement.parentClass.type
274+
val parentClass = errorElement.parentClass
275+
val searchWord = cleanString(positionText)
276+
setFieldsAndMethodsCompletionResultSet(
277+
parentClass.searchField(searchWord)?.toTypedArray() ?: emptyArray(),
278+
parentClass.searchMethod(searchWord)?.toTypedArray() ?: emptyArray(),
279+
result,
280+
)
281+
return
282+
}
283+
topElementType =
284+
getElementTypeByFieldAccess(originalFile, topText, elements, result)
285+
?: return
286+
}
269287
}
270288

289+
if (topElementType == null) return
290+
271291
val fieldAccessorChildElementValidator =
272292
SqlElForItemFieldAccessorChildElementValidator(
273293
elements,
@@ -304,25 +324,6 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
304324
}
305325
}
306326

307-
private fun getTopElementClassType(
308-
top: PsiElement,
309-
elements: List<PsiElement>,
310-
originalFile: PsiFile,
311-
topText: String,
312-
result: CompletionResultSet,
313-
): PsiType? {
314-
val forDeclaration = ForDirectiveInspection("")
315-
val forItem = forDeclaration.getForItem(top)
316-
if (forItem != null) {
317-
val errorElement = forDeclaration.checkForItem(elements)
318-
if (errorElement is ValidationCompleteResult) {
319-
return errorElement.parentClass.type
320-
}
321-
return null
322-
}
323-
return getElementTypeByFieldAccess(originalFile, topText, elements, result)
324-
}
325-
326327
private fun setStaticFieldAccess(
327328
top: PsiElement,
328329
prevWord: String,

src/main/kotlin/org/domaframework/doma/intellij/inspection/ForDirectiveInspection.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,32 @@ class ForDirectiveInspection(
9797
return errorElement
9898
}
9999

100+
fun getFieldAccessParentClass(blockElements: List<PsiElement>): ValidationResult? {
101+
val targetElement: PsiElement = blockElements.firstOrNull() ?: return null
102+
val file = targetElement.containingFile ?: return null
103+
104+
val forItem = getForItem(targetElement)
105+
var errorElement: ValidationResult? = ValidationDaoParamResult(targetElement, "", shorName)
106+
if (forItem != null) {
107+
val declarationItem =
108+
getDeclarationItem(forItem, file)
109+
110+
if (declarationItem != null && declarationItem is ForDeclarationDaoBaseItem) {
111+
val forItemElementsParentClass = declarationItem.getPsiParentClass()
112+
if (forItemElementsParentClass != null) {
113+
val validator =
114+
SqlElForItemFieldAccessorChildElementValidator(
115+
blockElements,
116+
forItemElementsParentClass,
117+
shorName,
118+
)
119+
errorElement = validator.validateChildren(dropIndex = 1)
120+
}
121+
}
122+
}
123+
return errorElement
124+
}
125+
100126
/**
101127
* Count the `for`, `if`, and `end` elements from the beginning
102128
* to the target element (`targetElement`)

src/main/kotlin/org/domaframework/doma/intellij/reference/SqlElForDirectiveIdExprReference.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,18 @@ class SqlElForDirectiveIdExprReference(
6161

6262
override fun getVariants(): Array<Any> = emptyArray()
6363

64+
/**
65+
* In the for directive, set the reference on the left side to the element on the right side.
66+
*/
6467
private fun getDeclarationItem(): PsiElement? {
65-
val forDirectiveParent = PsiTreeUtil.getParentOfType(element, SqlElForDirective::class.java)
66-
if (forDirectiveParent == null) return null
68+
val forDirectiveParent =
69+
PsiTreeUtil.getParentOfType(element, SqlElForDirective::class.java) ?: return null
6770

68-
return PsiTreeUtil.getChildrenOfType(forDirectiveParent, SqlElFieldAccessExpr::class.java)?.last()
69-
?: PsiTreeUtil.getChildrenOfType(forDirectiveParent, SqlElFieldAccessExpr::class.java)?.last()
71+
return PsiTreeUtil
72+
.getChildrenOfType(forDirectiveParent, SqlElFieldAccessExpr::class.java)
73+
?.last()
74+
?: PsiTreeUtil
75+
.getChildrenOfType(forDirectiveParent, SqlElFieldAccessExpr::class.java)
76+
?.last()
7077
}
7178
}

0 commit comments

Comments
 (0)