Skip to content

Commit 2e0e8bf

Browse files
committed
Highlight Specific Parameter Types in SQL Bind Variables as Errors
1 parent f1556c0 commit 2e0e8bf

26 files changed

+277
-6
lines changed

src/main/kotlin/org/domaframework/doma/intellij/extension/psi/PsiMethodExtension.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ package org.domaframework.doma.intellij.extension.psi
1818
import com.intellij.psi.PsiMethod
1919
import com.intellij.psi.PsiParameter
2020

21-
fun PsiMethod.findParameter(searchName: String): PsiParameter? = this.methodParameters.firstOrNull { it.name == searchName }
21+
fun PsiMethod.findParameter(searchName: String): PsiParameter? =
22+
this.methodParameters.firstOrNull {
23+
it.name == searchName &&
24+
!it.isIgnoreUsageCheck()
25+
}
2226

2327
val PsiMethod.methodParameters: List<PsiParameter>
2428
get() = this.parameterList.parameters.toList()

src/main/kotlin/org/domaframework/doma/intellij/extension/psi/PsiParameterExtension.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ fun PsiParameter.isIgnoreUsageCheck(): Boolean =
3232
when (type) {
3333
DomaClassName.SELECT_OPTIONS -> {
3434
// Only ignore the exact SelectOptions class, not its subtypes
35-
val clazzType = this.typeElement?.type as? PsiClassType
35+
val clazzType = this.type as? PsiClassType
3636
clazzType?.rawType()?.canonicalText == type.className
3737
}
3838
else -> getSuperClassType(type) != null
3939
}
4040
}
4141

4242
fun PsiParameter.getSuperClassType(superClassType: DomaClassName): PsiClassType? {
43-
val clazzType = this.typeElement?.type as? PsiClassType
43+
val clazzType = this.type as? PsiClassType
4444
var superCollection: PsiClassType? = clazzType
4545
while (superCollection != null &&
4646
!superClassType.isTargetClassNameStartsWith(superCollection.canonicalText)

src/test/kotlin/org/domaframework/doma/intellij/inspection/sql/ParameterDefinedTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import org.domaframework.doma.intellij.inspection.sql.inspector.SqlLoopDirective
2424
* A test that inspects whether a bind variable's parameters are defined.
2525
*/
2626
class ParameterDefinedTest : DomaSqlTest() {
27-
private val testDaoName = "EmployeeSummaryDao"
27+
private val testDaoName = "inspection/ParamDefinedTestDao"
2828

2929
override fun setUp() {
3030
super.setUp()
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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.inspection.sql
17+
18+
import org.domaframework.doma.intellij.DomaSqlTest
19+
import org.domaframework.doma.intellij.inspection.sql.inspector.SqlBindVariableInspection
20+
import org.domaframework.doma.intellij.inspection.sql.inspector.SqlFunctionCallInspection
21+
import org.domaframework.doma.intellij.inspection.sql.inspector.SqlLoopDirectiveTypeInspection
22+
23+
/**
24+
* Test cases for error highlighting when specific parameter types are used within SQL files.
25+
*
26+
* This test class verifies that the inspection correctly identifies and highlights errors
27+
* when method parameters of specific types (such as Optional, List, Entity classes, etc.)
28+
* are referenced in SQL bind variables and directives.
29+
*/
30+
class SpecificParameterTypeDefinedTest : DomaSqlTest() {
31+
private val testDaoName = "inspection/option/SpecificParamTypeBindVariableInspectionTestDao"
32+
33+
override fun setUp() {
34+
super.setUp()
35+
addDaoJavaFile("$testDaoName.java")
36+
addOtherJavaFile("function", "HogeFunction.java")
37+
addOtherJavaFile("function", "HogeBiFunction.java")
38+
addOtherJavaFile("option", "HogeSelectOptions.java")
39+
addOtherJavaFile("collector", "HogeCollector.java")
40+
myFixture.enableInspections(
41+
SqlBindVariableInspection(),
42+
SqlLoopDirectiveTypeInspection(),
43+
SqlFunctionCallInspection(),
44+
)
45+
}
46+
47+
fun testSelectOptions() {
48+
val sqlFileName = "$testDaoName/selectSelectOption.sql"
49+
inspectionSql(sqlFileName)
50+
}
51+
52+
fun testSubTypeSelectOption() {
53+
val sqlFileName = "$testDaoName/selectSubTypeSelectOption.sql"
54+
inspectionSql(sqlFileName)
55+
}
56+
57+
fun testCollector() {
58+
val sqlFileName = "$testDaoName/selectCollector.sql"
59+
inspectionSql(sqlFileName)
60+
}
61+
62+
fun testSubTypeCollector() {
63+
val sqlFileName = "$testDaoName/selectSubTypeCollector.sql"
64+
inspectionSql(sqlFileName)
65+
}
66+
67+
fun testFunction() {
68+
val sqlFileName = "$testDaoName/selectFunction.sql"
69+
inspectionSql(sqlFileName)
70+
}
71+
72+
fun testSubTypeFunction() {
73+
val sqlFileName = "$testDaoName/selectSubTypeFunction.sql"
74+
inspectionSql(sqlFileName)
75+
}
76+
77+
fun testBiFunction() {
78+
val sqlFileName = "$testDaoName/executeBiFunction.sql"
79+
inspectionSql(sqlFileName)
80+
}
81+
82+
fun testSubTypeBiFunction() {
83+
val sqlFileName = "$testDaoName/executeSubTypeBiFunction.sql"
84+
inspectionSql(sqlFileName)
85+
}
86+
87+
private fun inspectionSql(sqlFileName: String) {
88+
addSqlFile(sqlFileName)
89+
val sqlFile = findSqlFile(sqlFileName)
90+
assertNotNull("Not Found SQL File", sqlFile)
91+
if (sqlFile == null) return
92+
93+
myFixture.testHighlighting(false, false, false, sqlFile)
94+
}
95+
}

src/test/testData/src/main/java/doma/example/dao/EmployeeSummaryDao.java renamed to src/test/testData/src/main/java/doma/example/dao/inspection/ParamDefinedTestDao.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package doma.example.dao;
1+
package doma.example.dao.inspection;
22

33
import doma.example.entity.*:
44
import org.seasar.doma.*;
@@ -11,7 +11,7 @@
1111
import java.util.function.BiFunction;
1212

1313
@Dao
14-
interface EmployeeSummaryDao {
14+
interface ParamDefinedTestDao {
1515

1616
@Select
1717
EmployeeSummary bindVariableForNonEntityClass(EmployeeSummary employee, User user);
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package doma.example.dao.inspection.option;
2+
3+
import doma.example.collector.HogeCollector;
4+
import doma.example.entity.*;
5+
import doma.example.function.HogeFunction;
6+
import doma.example.option.HogeSelectOptions;
7+
import org.seasar.doma.*;
8+
import org.seasar.doma.jdbc.Config;
9+
import org.seasar.doma.jdbc.PreparedSql;
10+
import org.seasar.doma.jdbc.SelectOptions;
11+
import doma.example.function.HogeBiFunction;
12+
13+
import java.util.function.BiFunction;
14+
import java.util.function.Function;
15+
import java.util.stream.Collector;
16+
import java.util.stream.Stream;
17+
18+
/**
19+
* Tests that specific types are correctly highlighted as errors when used as bind variables in SQL.
20+
* Verifies that SelectOptions, Collector, Function, and BiFunction types (and their subtypes)
21+
*/
22+
@Dao
23+
public interface SpecificParamTypeBindVariableInspectionTestDao {
24+
25+
/**
26+
* SelectOptions do not cause errors even when unused
27+
* @param searchName
28+
* @param options
29+
* @return
30+
*/
31+
@Select
32+
Project selectSelectOption(Integer id, String searchName, SelectOptions options);
33+
34+
/**
35+
* SelectOptions subtypes cause errors even when unused
36+
* @param searchName
37+
* @param hogeSelectOptions
38+
* @return
39+
*/
40+
@Select
41+
Project selectSubTypeSelectOption(Employee employee,
42+
String searchName,
43+
HogeSelectOptions hogeSelectOptions);
44+
45+
/**
46+
* Collector do not cause errors even when unused in SQL
47+
* @param salary
48+
* @param collector
49+
* @return
50+
*/
51+
@Select(strategy = SelectType.COLLECT)
52+
Pckt selectCollector(BigDecimal salary, Collector<Packet, BigDecimal, Pckt> collector);
53+
54+
/**
55+
* Collector subclasses do not cause errors even when unused in SQL
56+
* @param employee
57+
* @param id
58+
* @param hogeCollector
59+
* @return
60+
*/
61+
@Select(strategy = SelectType.COLLECT)
62+
String selectSubTypeCollector(Employee employee,
63+
Integer id,
64+
HogeCollector hogeCollector);
65+
66+
/**
67+
* Function parameters do not cause errors even when unused
68+
* @param employee
69+
* @param id
70+
* @param function
71+
* @return
72+
*/
73+
@Select(strategy = SelectType.STREAM)
74+
String selectFunction(Employee employee,
75+
Integer id,
76+
Function<Stream<Employee>, String> function);
77+
78+
/**
79+
* Function subtypes do not cause errors even when unused
80+
* @param employee
81+
* @param id
82+
* @param function
83+
* @return
84+
*/
85+
@Select(strategy = SelectType.STREAM)
86+
String selectSubTypeFunction(Employee employee,
87+
Integer id,
88+
HogeFunction function);
89+
90+
/**
91+
* BiFunction parameters do not cause errors even when unused
92+
* @param tableName
93+
* @param func
94+
* @return
95+
*/
96+
@SqlProcessor
97+
Pckt executeBiFunction(String tableName, BiFunction<Config, PreparedSql, Pckt> func);
98+
99+
/**
100+
* BiFunction subtypes do not cause errors even when unused
101+
* @param tableName
102+
* @param func
103+
* @return
104+
*/
105+
@SqlProcessor
106+
String executeSubTypeBiFunction(String tableName, HogeBiFunction func);
107+
108+
}

0 commit comments

Comments
 (0)