Skip to content

Commit 70990bb

Browse files
committed
Add validation results for directive item types and enhance for directive handling
1 parent 68c9bb6 commit 70990bb

File tree

7 files changed

+173
-10
lines changed

7 files changed

+173
-10
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.common.sql.validator.result
17+
18+
import com.intellij.codeInspection.ProblemsHolder
19+
import com.intellij.openapi.project.Project
20+
import com.intellij.openapi.util.TextRange
21+
import com.intellij.psi.PsiElement
22+
import org.domaframework.doma.intellij.bundle.MessageBundle
23+
import org.domaframework.doma.intellij.common.psi.PsiParentClass
24+
25+
class ValidationForDirectiveItemTypeResult(
26+
override val identify: PsiElement?,
27+
override val shortName: String = "",
28+
) : ValidationResult(identify, null, shortName) {
29+
override fun setHighlight(
30+
highlightRange: TextRange,
31+
identify: PsiElement,
32+
holder: ProblemsHolder,
33+
parent: PsiParentClass?,
34+
project: Project,
35+
) {
36+
val project = identify.project
37+
holder.registerProblem(
38+
identify,
39+
MessageBundle.message("inspection.invalid.sql.iterable"),
40+
problemHighlightType(project, shortName),
41+
highlightRange,
42+
)
43+
}
44+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.common.sql.validator.result
17+
18+
import com.intellij.codeInspection.ProblemsHolder
19+
import com.intellij.openapi.project.Project
20+
import com.intellij.openapi.util.TextRange
21+
import com.intellij.psi.PsiElement
22+
import org.domaframework.doma.intellij.bundle.MessageBundle
23+
import org.domaframework.doma.intellij.common.psi.PsiParentClass
24+
25+
class ValidationNotFoundStaticPropertyResult(
26+
override val identify: PsiElement?,
27+
override val shortName: String = "",
28+
) : ValidationResult(identify, null, shortName) {
29+
override fun setHighlight(
30+
highlightRange: TextRange,
31+
identify: PsiElement,
32+
holder: ProblemsHolder,
33+
parent: PsiParentClass?,
34+
project: Project,
35+
) {
36+
val project = identify.project
37+
holder.registerProblem(
38+
identify,
39+
MessageBundle.message(
40+
"inspection.invalid.sql.staticProperty",
41+
identify.text,
42+
),
43+
problemHighlightType(project, shortName),
44+
highlightRange,
45+
)
46+
}
47+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.common.sql.validator.result
17+
18+
import com.intellij.codeInspection.ProblemsHolder
19+
import com.intellij.openapi.project.Project
20+
import com.intellij.openapi.util.TextRange
21+
import com.intellij.psi.PsiElement
22+
import org.domaframework.doma.intellij.bundle.MessageBundle
23+
import org.domaframework.doma.intellij.common.psi.PsiParentClass
24+
25+
class ValidationNotFoundTopTypeResult(
26+
override val identify: PsiElement?,
27+
override val shortName: String = "",
28+
) : ValidationResult(identify, null, shortName) {
29+
override fun setHighlight(
30+
highlightRange: TextRange,
31+
identify: PsiElement,
32+
holder: ProblemsHolder,
33+
parent: PsiParentClass?,
34+
project: Project,
35+
) {
36+
val project = identify.project
37+
holder.registerProblem(
38+
identify,
39+
MessageBundle.message("inspection.invalid.sql.topType"),
40+
problemHighlightType(project, shortName),
41+
highlightRange,
42+
)
43+
}
44+
}

src/main/kotlin/org/domaframework/doma/intellij/common/util/ForDirectiveUtil.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ class ForDirectiveUtil {
173173
fun getForDirectiveItemClassType(
174174
project: Project,
175175
forDirectiveBlocks: List<BlockToken>,
176+
targetForItem: PsiElement? = null,
176177
): PsiParentClass? {
177178
// Get the type of the top for directive definition element
178179
// Defined in Dao parameters or static property calls
@@ -185,6 +186,9 @@ class ForDirectiveUtil {
185186
forDirectiveBlocks.drop(1).forEach { directive ->
186187
// Get the definition type of the target directive
187188
val formItem = ForItem(directive.item)
189+
if (targetForItem != null && formItem.element.textOffset > targetForItem.textOffset) {
190+
return parentClassType
191+
}
188192
val forDirectiveExpr = formItem.getParentForDirectiveExpr()
189193
val forDirectiveDeclaration = forDirectiveExpr?.getForItemDeclaration()
190194
if (forDirectiveDeclaration != null) {

src/main/kotlin/org/domaframework/doma/intellij/inspection/sql/visitor/SqlInspectionVisitor.kt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import org.domaframework.doma.intellij.common.psi.PsiStaticElement
3131
import org.domaframework.doma.intellij.common.sql.cleanString
3232
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationClassPathResult
3333
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationDaoParamResult
34+
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationForDirectiveItemTypeResult
3435
import org.domaframework.doma.intellij.common.sql.validator.result.ValidationPropertyResult
3536
import org.domaframework.doma.intellij.common.util.ForDirectiveUtil
3637
import org.domaframework.doma.intellij.extension.expr.accessElements
@@ -92,10 +93,25 @@ class SqlInspectionVisitor(
9293
PsiTreeUtil.getParentOfType(element, SqlElStaticFieldAccessExpr::class.java)?.let { return }
9394

9495
val forDirectiveExp = PsiTreeUtil.getParentOfType(element, SqlElForDirective::class.java)
95-
if (forDirectiveExp != null && forDirectiveExp.getForItem() == element) return
96-
97-
val forItem = ForDirectiveUtil.findForItem(element)
98-
if (forItem != null) return
96+
val isSkip = forDirectiveExp != null && forDirectiveExp.getForItem() != element
97+
98+
var forDirectiveBlocks = ForDirectiveUtil.getForDirectiveBlocks(element, skipSelf = isSkip)
99+
val forItem = ForDirectiveUtil.findForItem(element, skipSelf = isSkip, forDirectives = forDirectiveBlocks)
100+
if (forItem != null) {
101+
val forDeclarationType =
102+
ForDirectiveUtil.getForDirectiveItemClassType(
103+
element.project,
104+
forDirectiveBlocks,
105+
forItem,
106+
)
107+
if (forDeclarationType == null) {
108+
ValidationForDirectiveItemTypeResult(
109+
element,
110+
this.shortName,
111+
).highlightElement(holder)
112+
}
113+
return
114+
}
99115

100116
val daoMethod = findDaoMethod(visitFile) ?: return
101117
val param = daoMethod.findParameter(cleanString(element.text))
@@ -130,10 +146,12 @@ class SqlInspectionVisitor(
130146
var isBatchAnnotation = false
131147
val topElementParentClass =
132148
if (forItem != null) {
133-
val result = ForDirectiveUtil.getForDirectiveItemClassType(project, forDirectiveBlocks)
149+
val result = ForDirectiveUtil.getForDirectiveItemClassType(project, forDirectiveBlocks, forItem)
134150
if (result == null) {
135-
// TODO Add an error message when the type of element used in the For directory is not a List type.
136-
errorHighlight(topElement, daoMethod, holder)
151+
ValidationForDirectiveItemTypeResult(
152+
topElement,
153+
this.shortName,
154+
).highlightElement(holder)
137155
return
138156
}
139157
val specifiedClassType =

src/main/resources/messages/DomaToolsBundle.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@ inspector.invalid.class.property=The field or method [{1}] does not exist in the
66
inspection.dao.method.variable.error=There are unused parameters in the SQL [{0}]
77
inspector.invalid.dao.parameter=The bind variable [{1}] does not exist in the Dao method [{0}]
88
config.enable.sql.format=Enable SQL Format
9+
inspection.invalid.sql.topType=Can't get type of first element
10+
inspection.invalid.sql.staticProperty=[{0}] is not a public or static property
911
inspection.invalid.sql.testdata=Bind variables must be followed by test data
10-
inspection.invalid.sql.classpath=A non-existent package or class name was specified. [{0}]
12+
inspection.invalid.sql.classpath=A non-existent package or class name was specified [{0}]
13+
inspection.invalid.sql.iterable=The type that can be used in the for directive is an Iterable type

src/main/resources/messages/DomaToolsBundle_ja.properties

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ jump.to.dao.tooltip.title=Dao\u30E1\u30BD\u30C3\u30C9\u5B9A\u7FA9\u306B\u9077\u7
33
generate.sql.quickfix.title=SQL\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
44
inspection.sql.not.exist.error=SQL\u30D5\u30A1\u30A4\u30EB\u304C\u5B58\u5728\u3057\u307E\u305B\u3093
55
inspector.invalid.class.property=\u30AF\u30E9\u30B9[{0}]\u306B\u5B58\u5728\u3057\u306A\u3044\u30D5\u30A3\u30FC\u30EB\u30C9\u3001\u307E\u305F\u306F\u30E1\u30BD\u30C3\u30C9\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059:[{1}]
6-
inspection.dao.method.variable.error=SQL\u3067\u4F7F\u7528\u3055\u308C\u3066\u3044\u306A\u3044\u5F15\u6570\u304C\u3042\u308A\u307E\u3059[{0}]
6+
inspection.dao.method.variable.error=SQL\u3067\u4F7F\u7528\u3055\u308C\u3066\u3044\u306A\u3044\u5F15\u6570\u304C\u3042\u308A\u307E\u3059:[{0}]
77
inspector.invalid.dao.parameter=Dao\u30E1\u30BD\u30C3\u30C9[{0}]\u306B\u5B58\u5728\u3057\u306A\u3044\u30D0\u30A4\u30F3\u30C9\u5909\u6570\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059:[{1}]
88
config.enable.sql.format=SQL\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3092\u6709\u52B9\u5316
9+
inspection.invalid.sql.topType=\u6700\u521D\u306E\u8981\u7D20\u306E\u578B\u304C\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093
10+
inspection.invalid.sql.staticProperty=[{0}]\u306F\u0070\u0075\u0062\u006C\u0069\u0063\u304B\u3064\u0073\u0074\u0061\u0074\u0069\u0063\u30D7\u30ED\u30D1\u30C6\u30A3\u3067\u306F\u3042\u308A\u307E\u305B\u3093
911
inspection.invalid.sql.testdata=\u30D0\u30A4\u30F3\u30C9\u5909\u6570\u306E\u5F8C\u308D\u306B\u306F\u30C6\u30B9\u30C8\u30C7\u30FC\u30BF\u304C\u5FC5\u8981\u3067\u3059
10-
inspection.invalid.sql.classpath=\u0041\u0020\u006E\u006F\u006E\u002D\u0065\u0078\u0069\u0073\u0074\u0065\u006E\u0074\u0020\u0070\u0061\u0063\u006B\u0061\u0067\u0065\u0020\u006F\u0072\u0020\u0063\u006C\u0061\u0073\u0073\u0020\u006E\u0061\u006D\u0065\u0020\u0077\u0061\u0073\u0020\u0073\u0070\u0065\u0063\u0069\u0066\u0069\u0065\u0064\u002E [{0}]
12+
inspection.invalid.sql.classpath=\u5B58\u5728\u3057\u306A\u3044\u30D1\u30C3\u30B1\u30FC\u30B8\u307E\u305F\u306F\u30AF\u30E9\u30B9\u540D\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F\u3002:[{0}]
13+
inspection.invalid.sql.iterable=\u0066\u006F\u0072\u30C7\u30A3\u30EC\u30AF\u30C6\u30A3\u30D6\u306B\u4F7F\u7528\u3067\u304D\u308B\u578B\u306F\u0049\u0074\u0065\u0072\u0061\u0062\u006C\u0065\u578B\u3067\u3059

0 commit comments

Comments
 (0)