@@ -17,13 +17,12 @@ package org.domaframework.doma.intellij.inspection
1717
1818import com.intellij.psi.PsiClassType
1919import com.intellij.psi.PsiElement
20- import com.intellij.psi.PsiFile
20+ import com.intellij.psi.PsiMethod
2121import com.intellij.psi.util.CachedValue
2222import com.intellij.psi.util.CachedValueProvider
2323import com.intellij.psi.util.CachedValuesManager
2424import com.intellij.psi.util.PsiTreeUtil
2525import com.intellij.psi.util.elementType
26- import org.domaframework.doma.intellij.common.dao.findDaoMethod
2726import org.domaframework.doma.intellij.common.psi.PsiParentClass
2827import org.domaframework.doma.intellij.common.sql.PsiClassTypeUtil
2928import org.domaframework.doma.intellij.common.sql.foritem.ForDeclarationDaoBaseItem
@@ -32,6 +31,7 @@ import org.domaframework.doma.intellij.common.sql.foritem.ForItem
3231import org.domaframework.doma.intellij.common.sql.validator.SqlElForItemFieldAccessorChildElementValidator
3332import org.domaframework.doma.intellij.common.sql.validator.result.ValidationCompleteResult
3433import org.domaframework.doma.intellij.common.sql.validator.result.ValidationDaoParamResult
34+ import org.domaframework.doma.intellij.common.sql.validator.result.ValidationPropertyResult
3535import org.domaframework.doma.intellij.common.sql.validator.result.ValidationResult
3636import org.domaframework.doma.intellij.extension.psi.findParameter
3737import org.domaframework.doma.intellij.extension.psi.getDomaAnnotationType
@@ -42,8 +42,8 @@ import org.domaframework.doma.intellij.psi.SqlElIdExpr
4242import org.domaframework.doma.intellij.psi.SqlTypes
4343
4444class ForDirectiveInspection (
45+ private val daoMethod : PsiMethod ,
4546 private val shortName : String = " " ,
46- private val file : PsiFile ,
4747) {
4848 data class BlockToken (
4949 val type : BlockType ,
@@ -64,12 +64,7 @@ class ForDirectiveInspection(
6464
6565 fun getForItem (targetElement : PsiElement ): ForItem ? {
6666 val forBlocks = getForDirectiveBlock(targetElement)
67- val targetName =
68- targetElement.text
69- .replace(" _has_next" , " " )
70- .replace(" _index" , " " )
71- val forItem = forBlocks.lastOrNull { it.item.text == targetName }
72- forItem?.let { return ForItem (it.item) } ? : return null
67+ return getForItem(targetElement, forBlocks)
7368 }
7469
7570 fun getForItem (
@@ -95,12 +90,11 @@ class ForDirectiveInspection(
9590 val firDirectives = getForDirectiveBlock(targetElement)
9691 val forItem = getForItem(targetElement, firDirectives)
9792 var errorElement: ValidationResult ? = ValidationDaoParamResult (targetElement, " " , shortName)
98- val daoMethod = findDaoMethod(file) ? : return null
9993 val domaAnnotationType = daoMethod.getDomaAnnotationType()
10094
10195 if (forItem != null ) {
10296 val declarationItem =
103- getDeclarationItem (forItem, file )
97+ getDeclarationTopItem (forItem, 0 )
10498
10599 if (declarationItem != null && declarationItem is ForDeclarationDaoBaseItem ) {
106100 val daoParamDeclarativeType =
@@ -123,12 +117,7 @@ class ForDirectiveInspection(
123117
124118 // Each time searching for the next for directive item, recursively analyze the type if the field is Access.
125119 while (nestClassType != null &&
126- i <= nestIndex &&
127-
128- PsiClassTypeUtil .isIterableType(
129- nestClassType,
130- topElm.project,
131- )
120+ i <= nestIndex
132121 ) {
133122 // Get the definition type for each for directive passed through
134123 val targetForDirective = firDirectives[i]
@@ -147,6 +136,18 @@ class ForDirectiveInspection(
147136 )
148137 val currentLastType = validator.validateChildren()
149138 nestClassType = currentLastType?.parentClass?.type as ? PsiClassType ?
139+ if (nestClassType != null &&
140+ ! PsiClassTypeUtil .isIterableType(
141+ nestClassType,
142+ topElm.project,
143+ )
144+ ) {
145+ return ValidationPropertyResult (
146+ currentForItem.element,
147+ currentLastType?.parentClass,
148+ " " ,
149+ )
150+ }
150151 listIndex = 1
151152 } else {
152153 // Get the nesting count from the List type definition obtained along the way
@@ -175,32 +176,6 @@ class ForDirectiveInspection(
175176 return errorElement
176177 }
177178
178- fun getFieldAccessParentClass (blockElements : List <PsiElement >): ValidationResult ? {
179- val targetElement: PsiElement = blockElements.firstOrNull() ? : return null
180- val file = targetElement.containingFile ? : return null
181-
182- val forItem = getForItem(targetElement)
183- var errorElement: ValidationResult ? = ValidationDaoParamResult (targetElement, " " , shortName)
184- if (forItem != null ) {
185- val declarationItem =
186- getDeclarationItem(forItem, file)
187-
188- if (declarationItem != null && declarationItem is ForDeclarationDaoBaseItem ) {
189- val forItemElementsParentClass = declarationItem.getPsiParentClass()
190- if (forItemElementsParentClass != null ) {
191- val validator =
192- SqlElForItemFieldAccessorChildElementValidator (
193- blockElements,
194- forItemElementsParentClass,
195- shortName,
196- )
197- errorElement = validator.validateChildren(dropIndex = 1 )
198- }
199- }
200- }
201- return errorElement
202- }
203-
204179 fun getForDirectiveBlockSize (target : PsiElement ): Int = getForDirectiveBlock(target).size
205180
206181 /* *
@@ -212,6 +187,7 @@ class ForDirectiveInspection(
212187 val cachedValue =
213188 cachedForDirectiveBlocks.getOrPut(targetElement) {
214189 CachedValuesManager .getManager(targetElement.project).createCachedValue {
190+ val file = targetElement.containingFile ? : return @createCachedValue null
215191 val directiveBlocks =
216192 PsiTreeUtil
217193 .findChildrenOfType(file, PsiElement ::class .java)
@@ -255,9 +231,11 @@ class ForDirectiveInspection(
255231 return cachedValue.value
256232 }
257233
258- private fun getDeclarationItem (
234+ /* **
235+ * Get the top element to define the item.
236+ */
237+ private fun getDeclarationTopItem (
259238 forItem : ForItem ,
260- file : PsiFile ,
261239 searchIndex : Int = 0,
262240 ): ForDirectiveItemBase ? {
263241 val forDirectiveParent = forItem.getParentForDirectiveExpr() ? : return null
@@ -269,19 +247,10 @@ class ForDirectiveInspection(
269247 val parentForItem = getForItem(topElm)
270248 val index = searchIndex + 1
271249 if (parentForItem != null ) {
272- val parentDeclaration = getDeclarationItem (parentForItem, file , index)
250+ val parentDeclaration = getDeclarationTopItem (parentForItem, index)
273251 if (parentDeclaration is ForDeclarationDaoBaseItem ) return parentDeclaration
274252 }
275253
276- return getForDeclarationDaoParamBase(topElm, searchIndex, file)
277- }
278-
279- private fun getForDeclarationDaoParamBase (
280- topElm : PsiElement ,
281- searchIndex : Int ,
282- file : PsiFile ,
283- ): ForDeclarationDaoBaseItem ? {
284- val daoMethod = findDaoMethod(file) ? : return null
285254 val validDaoParam = daoMethod.findParameter(topElm.text)
286255 if (validDaoParam == null ) return null
287256
0 commit comments