Skip to content

Commit a765a02

Browse files
committed
Enhance the usage checks of DAO method parameters for subtypes.
1 parent b7b4f98 commit a765a02

File tree

10 files changed

+110
-16
lines changed

10 files changed

+110
-16
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ enum class DomaClassName(
3838
VOID("java.lang.Void"),
3939
RETURNING("org.seasar.doma.Returning"),
4040
REFERENCE("org.seasar.doma.jdbc.Reference"),
41+
SELECT_OPTIONS("org.seasar.doma.jdbc.SelectOptions"),
4142

4243
STRING("java.lang.String"),
4344
OBJECT("java.lang.Object"),

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

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,43 @@ package org.domaframework.doma.intellij.extension.psi
1717

1818
import com.intellij.psi.PsiClassType
1919
import com.intellij.psi.PsiParameter
20+
import org.domaframework.doma.intellij.common.util.DomaClassName
2021

2122
val PsiParameter.isFunctionClazz: Boolean
22-
get() =
23-
(this.typeElement?.type as? PsiClassType)
24-
?.resolve()
25-
?.qualifiedName
26-
?.contains("java.util.function") == true
23+
get() {
24+
val functionType = DomaClassName.JAVA_FUNCTION
25+
val superCollection: PsiClassType? = getSuperClassType(functionType)
26+
return functionType.isTargetClassNameStartsWith(superCollection?.canonicalText ?: "")
27+
}
28+
29+
val PsiParameter.isBiFunctionClazz: Boolean
30+
get() {
31+
val functionType = DomaClassName.BI_FUNCTION
32+
val superCollection: PsiClassType? = getSuperClassType(functionType)
33+
return functionType.isTargetClassNameStartsWith(superCollection?.canonicalText ?: "")
34+
}
2735

2836
val PsiParameter.isSelectOption: Boolean
2937
get() =
3038
(this.typeElement?.type as? PsiClassType)
3139
?.resolve()
32-
?.qualifiedName == "org.seasar.doma.jdbc.SelectOptions"
40+
?.qualifiedName == DomaClassName.SELECT_OPTIONS.className
3341

3442
val PsiParameter.isCollector: Boolean
35-
get() =
36-
(this.typeElement?.type as? PsiClassType)
37-
?.resolve()
38-
?.qualifiedName == "java.util.stream.Collector"
43+
get() {
44+
val collectorType = DomaClassName.JAVA_COLLECTOR
45+
val superCollection: PsiClassType? = getSuperClassType(collectorType)
46+
return collectorType.isTargetClassNameStartsWith(superCollection?.canonicalText ?: "")
47+
}
48+
49+
fun PsiParameter.getSuperClassType(superClassType: DomaClassName): PsiClassType? {
50+
val clazzType = this.typeElement?.type as? PsiClassType
51+
var superCollection: PsiClassType? = clazzType
52+
while (superCollection != null &&
53+
!superClassType.isTargetClassNameStartsWith(superCollection.canonicalText)
54+
) {
55+
superCollection =
56+
superCollection.getSuperType(superClassType.className)
57+
}
58+
return superCollection
59+
}

src/main/kotlin/org/domaframework/doma/intellij/inspection/dao/visitor/UsedDaoMethodParamInspectionVisitor.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import org.domaframework.doma.intellij.common.dao.getDaoClass
2727
import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType
2828
import org.domaframework.doma.intellij.common.psi.PsiDaoMethod
2929
import org.domaframework.doma.intellij.extension.findFile
30+
import org.domaframework.doma.intellij.extension.psi.isBiFunctionClazz
3031
import org.domaframework.doma.intellij.extension.psi.isCollector
3132
import org.domaframework.doma.intellij.extension.psi.isFunctionClazz
3233
import org.domaframework.doma.intellij.extension.psi.isSelectOption
@@ -45,7 +46,7 @@ class UsedDaoMethodParamInspectionVisitor(
4546

4647
val methodParameters =
4748
method.methodParameters
48-
.filter { !it.isFunctionClazz && !it.isSelectOption && !(it.isCollector && psiDaoMethod.isSelectTypeCollect()) }
49+
.filter { !it.isFunctionClazz && !it.isBiFunctionClazz && !it.isSelectOption && !it.isCollector }
4950
val sqlFileManager =
5051
psiDaoMethod.sqlFile?.let {
5152
method.project.findFile(it)

src/test/kotlin/org/domaframework/doma/intellij/inspection/dao/DomaUseVariableTest.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ class DomaUseVariableTest : DomaSqlTest() {
3636
"$testDaoName/collectDoesCauseError.sql",
3737
"$testDaoName/noErrorWhenUsedInFunctionParameters.sql",
3838
"$testDaoName/duplicateForDirectiveDefinitionNames.sql",
39+
"$testDaoName/selectHogeFunction.sql",
40+
"$testDaoName/functionDoesNotCauseError.sql",
41+
"$testDaoName/selectHogeCollector.sql",
3942
)
43+
addOtherJavaFile("collector", "HogeCollector.java")
44+
addOtherJavaFile("function", "HogeFunction.java")
45+
addOtherJavaFile("function", "HogeBiFunction.java")
4046
myFixture.enableInspections(UsedDaoMethodParamInspection())
4147
}
4248

src/test/testData/src/main/java/doma/example/dao/DaoMethodVariableInspectionTestDao.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
import org.seasar.doma.jdbc.PreparedSql;
1818
import org.seasar.doma.jdbc.SelectOptions;
1919
import org.seasar.doma.SelectType;
20+
import java.util.stream.Stream;
21+
import java.util.function.Function;
2022
import java.util.stream.Collector;
23+
import doma.example.function.*;
24+
import doma.example.collector.*;
2125

2226
import java.util.List;
2327
import java.util.function.BiFunction;
@@ -38,20 +42,46 @@ interface DaoMethodVariableInspectionTestDao {
3842
@SqlProcessor
3943
<R> R biFunctionDoesNotCauseError(Integer id, BiFunction<Config, PreparedSql, R> handler);
4044

45+
@SqlProcessor
46+
@Sql("SELECT id, name FROM demo")
47+
<R> R biFunctionHogeFunction(HogeBiFunction handler);
48+
4149
@Select
42-
Project selectOptionDoesNotCauseError(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,String searchName,SelectOptions options);
50+
Project selectOptionDoesNotCauseError(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,
51+
String searchName,
52+
SelectOptions options);
53+
54+
@Select(strategy = SelectType.COLLECT)
55+
Project collectDoesNotCauseError(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,
56+
Integer id,
57+
Collector<Project, ?, Project> collector);
4358

4459
@Select(strategy = SelectType.COLLECT)
45-
Project collectDoesNotCauseError(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,Integer id,Collector<Project, ?, Project> collector);
60+
Project selectHogeCollector(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,
61+
Integer id,
62+
HogeCollector collector);
4663

4764
@Select
48-
Project collectDoesCauseError(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,String searchName,Collector<Project, ?, Project> <error descr="There are unused parameters in the SQL [collector]">collector</error>);
65+
Project collectDoesCauseError(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,
66+
String searchName,
67+
Collector<Project, ?, Project> collector);
68+
69+
@Select(strategy = SelectType.STREAM)
70+
String functionDoesNotCauseError(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,
71+
Integer id,
72+
Function<Stream<Employee>, String> function);
73+
74+
@Select(strategy = SelectType.STREAM)
75+
String selectHogeFunction(Employee <error descr="There are unused parameters in the SQL [employee]">employee</error>,
76+
Integer id,
77+
HogeFunction function);
4978

5079
@Select
5180
Project noErrorWhenUsedInFunctionParameters(Employee employee, Integer count);
5281

5382
@Select
54-
Employee duplicateForDirectiveDefinitionNames(Employee <error descr="An element name that is a duplicate of an element name defined in SQL is used">member</error>, Integer <error descr="There are unused parameters in the SQL [count]">count</error>,
83+
Employee duplicateForDirectiveDefinitionNames(Employee <error descr="An element name that is a duplicate of an element name defined in SQL is used">member</error>,
84+
Integer <error descr="There are unused parameters in the SQL [count]">count</error>,
5585
List<Employee> users,
5686
String searchName,
5787
Boolean inForm);

src/test/testData/src/main/java/doma/example/dao/inspection/returntype/SelectReturnTypeTestDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public interface SelectReturnTypeTestDao {
129129

130130
@Select(strategy = SelectType.COLLECT)
131131
@Sql("select * from emp where salary > /* salary */0")
132-
Pckt selectHogeCollect(BigDecimal salary, HogeCollector collector);
132+
Pckt <error descr="The return type must match RESULT of the \"java.util.stream.Collector\" type parameter">selectHogeCollect</error>(BigDecimal salary, HogeCollector collector);
133133

134134
@Select(strategy = SelectType.STREAM)
135135
@Sql("select * from emp where salary > /* salary */0")
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package doma.example.function;
2+
3+
import org.seasar.doma.jdbc.Config;
4+
import org.seasar.doma.jdbc.PreparedSql;
5+
6+
import java.io.ObjectInputFilter;
7+
import java.util.function.BiFunction;
8+
import java.util.function.Function;
9+
import java.util.stream.Stream;
10+
11+
public class HogeBiFunction implements BiFunction<Config, PreparedSql, String> {
12+
13+
@Override
14+
public String apply(Config config, PreparedSql preparedSql) {
15+
return "";
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
select
2+
p.project_id
3+
, p.project_name
4+
, p.project_number
5+
from project p
6+
where p.project_id = /* id */0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
select
2+
p.project_id
3+
, p.project_name
4+
, p.project_number
5+
from project p
6+
where p.project_id = /* id */0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
select
2+
p.project_id
3+
, p.project_name
4+
, p.project_number
5+
from project p
6+
where p.project_id = /* id */0

0 commit comments

Comments
 (0)