Skip to content

Commit 1ae816d

Browse files
committed
Add support for Function subtype and Collector subtype in DAO method inspections
1 parent 712849b commit 1ae816d

File tree

6 files changed

+83
-18
lines changed

6 files changed

+83
-18
lines changed

src/main/kotlin/org/domaframework/doma/intellij/inspection/dao/processor/paramtype/SelectParamTypeCheckProcessor.kt

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,44 +83,59 @@ class SelectParamTypeCheckProcessor(
8383
}
8484

8585
private fun checkStream(holder: ProblemsHolder) {
86+
val stream = DomaClassName.JAVA_STREAM.className
8687
val result =
8788
ValidationMethodSelectStrategyParamResult(
8889
method.nameIdentifier,
8990
shortName,
9091
"STREAM",
9192
DomaClassName.JAVA_FUNCTION.getGenericParamCanonicalText(DomaClassName.JAVA_STREAM.className),
9293
)
94+
9395
val function = getMethodParamTargetType(DomaClassName.JAVA_FUNCTION.className)
9496
if (function == null) {
9597
result.highlightElement(holder)
9698
return
9799
}
98100

99-
val functionFirstParam = (function.type as? PsiClassType)?.parameters?.firstOrNull()
101+
val functionType = function.type
102+
103+
// Check if the first parameter of the function is a stream type
104+
val functionClass = project.getJavaClazz(functionType.canonicalText) ?: return
105+
var superCollection: PsiClassType? = functionType as PsiClassType?
106+
while (superCollection != null &&
107+
!DomaClassName.JAVA_FUNCTION.isTargetClassNameStartsWith(superCollection.canonicalText)
108+
) {
109+
superCollection =
110+
functionClass.superTypes
111+
.find { sp -> DomaClassName.JAVA_FUNCTION.isTargetClassNameStartsWith(sp.canonicalText) }
112+
}
113+
114+
val functionFirstParam = superCollection?.parameters?.firstOrNull()
100115
if (functionFirstParam == null ||
101116
!DomaClassName.JAVA_STREAM.isTargetClassNameStartsWith(functionFirstParam.canonicalText)
102117
) {
103118
result.highlightElement(holder)
104119
return
105120
}
106121

107-
// Check if the first parameter of the function is a stream type
108-
val streamTargetParam = (functionFirstParam as? PsiClassType)?.parameters?.firstOrNull()
109-
if (streamTargetParam == null) {
110-
generateTargetTypeResult("Unknown").highlightElement(holder)
122+
// Check if the first parameter of the stream is a valid type
123+
val streamParamClassType = functionFirstParam as? PsiClassType
124+
val strategyParamType = streamParamClassType?.parameters?.firstOrNull()
125+
if (strategyParamType == null) {
126+
generateTargetTypeResult("Unknown", stream).highlightElement(holder)
111127
return
112128
}
113129

114-
val streamTargetTypeCanonicalText = streamTargetParam.canonicalText
115-
if (DomaClassName.MAP.isTargetClassNameStartsWith(streamTargetTypeCanonicalText)) {
116-
if (!checkMapType(streamTargetTypeCanonicalText)) {
117-
generateTargetTypeResult(streamTargetTypeCanonicalText).highlightElement(holder)
130+
if (DomaClassName.MAP.isTargetClassNameStartsWith(stream)) {
131+
if (!checkMapType(stream)) {
132+
generateTargetTypeResult(stream, stream).highlightElement(holder)
118133
}
119134
return
120135
}
121136

122-
if (!checkParamType(streamTargetParam)) {
123-
generateTargetTypeResult(streamTargetTypeCanonicalText).highlightElement(holder)
137+
if (!checkParamType(strategyParamType)) {
138+
generateTargetTypeResult(stream, stream).highlightElement(holder)
124139
}
125140
}
126141

@@ -132,28 +147,40 @@ class SelectParamTypeCheckProcessor(
132147
"COLLECT",
133148
DomaClassName.JAVA_COLLECTOR.className,
134149
)
150+
val collector = DomaClassName.JAVA_COLLECTOR.className
135151
val collection = getMethodParamTargetType(DomaClassName.JAVA_COLLECTOR.className)
136152
if (collection == null) {
137153
result.highlightElement(holder)
138154
return
139155
}
140156

141-
val collectorTargetParam = (collection.type as? PsiClassType)?.parameters?.firstOrNull()
157+
val collectionType = collection.type
158+
val collectionClass = project.getJavaClazz(collectionType.canonicalText) ?: return
159+
var superCollection: PsiClassType? = collection.type as? PsiClassType
160+
while (superCollection != null &&
161+
!DomaClassName.JAVA_COLLECTOR.isTargetClassNameStartsWith(superCollection.canonicalText)
162+
) {
163+
superCollection =
164+
collectionClass.superTypes
165+
.find { sp -> DomaClassName.JAVA_COLLECTOR.isTargetClassNameStartsWith(sp.canonicalText) }
166+
}
167+
168+
val collectorTargetParam = superCollection?.parameters?.firstOrNull()
142169
if (collectorTargetParam == null) {
143-
generateTargetTypeResult("Unknown").highlightElement(holder)
170+
generateTargetTypeResult("Unknown", collector).highlightElement(holder)
144171
return
145172
}
146173

147174
val streamTargetTypeCanonicalText = collectorTargetParam.canonicalText
148175
if (DomaClassName.MAP.isTargetClassNameStartsWith(streamTargetTypeCanonicalText)) {
149176
if (!checkMapType(streamTargetTypeCanonicalText)) {
150-
generateTargetTypeResult(streamTargetTypeCanonicalText).highlightElement(holder)
177+
generateTargetTypeResult(streamTargetTypeCanonicalText, collector).highlightElement(holder)
151178
}
152179
return
153180
}
154181

155182
if (!checkParamType(collectorTargetParam)) {
156-
generateTargetTypeResult(streamTargetTypeCanonicalText).highlightElement(holder)
183+
generateTargetTypeResult(streamTargetTypeCanonicalText, collector).highlightElement(holder)
157184
}
158185
}
159186

@@ -167,11 +194,14 @@ class SelectParamTypeCheckProcessor(
167194
}
168195
}
169196

170-
fun generateTargetTypeResult(streamParamTypeName: String): ValidationMethodParamsSupportGenericParamResult =
197+
fun generateTargetTypeResult(
198+
paramTypeName: String,
199+
genericType: String,
200+
): ValidationMethodParamsSupportGenericParamResult =
171201
ValidationMethodParamsSupportGenericParamResult(
172202
method.nameIdentifier,
173203
shortName,
174-
streamParamTypeName,
175-
DomaClassName.JAVA_STREAM.className,
204+
paramTypeName,
205+
genericType,
176206
)
177207
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class AnnotationParamTypeCheckInspectionTest : DomaSqlTest() {
3939
myFixture.enableInspections(DaoMethodParamTypeInspection())
4040
addEntityJavaFile("Pckt.java")
4141
addEntityJavaFile("Packet.java")
42+
addOtherJavaFile("collector", "HogeCollector.java")
43+
addOtherJavaFile("function", "HogeFunction.java")
4244
testDaoNames.forEach { daoName ->
4345
addDaoJavaFile("$daoPackage/$daoName.java")
4446
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class AnnotationReturnTypeCheckInspectionTest : DomaSqlTest() {
4343
addEntityJavaFile("Pckt.java")
4444
addOtherJavaFile("domain", "Hiredate.java")
4545
addOtherJavaFile("collector", "HogeCollector.java")
46+
addOtherJavaFile("function", "HogeFunction.java")
4647
myFixture.enableInspections(DaoMethodReturnTypeInspection())
4748
}
4849

src/test/testData/src/main/java/doma/example/dao/inspection/paramtype/SelectParamTestDao.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import org.seasar.doma.*;
44
import org.seasar.doma.message.Message;
55
import doma.example.entity.*;
6+
import doma.example.collector.*;
7+
import doma.example.function.*;
68

79
import java.math.BigDecimal;
810
import java.util.Optional;
@@ -56,5 +58,13 @@ public interface SelectParamTestDao {
5658
@Select(strategy = SelectType.COLLECT)
5759
@Sql("select * from emp where salary > /* salary */0")
5860
Pckt selectCollectAccumulation(BigDecimal salary, Collector<Packet, BigDecimal, Pckt> collector);
61+
62+
@Select(strategy = SelectType.COLLECT)
63+
@Sql("select * from emp where salary > /* salary */0")
64+
Pckt selectHogeCollect(BigDecimal salary, HogeCollector collector);
65+
66+
@Select(strategy = SelectType.STREAM)
67+
@Sql("select * from emp where salary > /* salary */0")
68+
String selectHogeCollect(BigDecimal salary, HogeFunction function);
5969
}
6070

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import doma.example.entity.*;
1414
import doma.example.domain.*;
1515
import doma.example.collector.*;
16+
import doma.example.function.*;
1617

1718
@Dao
1819
public interface SelectReturnTypeTestDao {
@@ -126,5 +127,14 @@ public interface SelectReturnTypeTestDao {
126127
@Select(strategy = SelectType.COLLECT, mapKeyNaming = MapKeyNamingType.CAMEL_CASE)
127128
<R> R selectByIdAsMap(Integer id, Collector<Map<String, Object>, ?, R> collector);
128129

130+
@Select(strategy = SelectType.COLLECT)
131+
@Sql("select * from emp where salary > /* salary */0")
132+
Pckt selectHogeCollect(BigDecimal salary, HogeCollector collector);
133+
134+
@Select(strategy = SelectType.STREAM)
135+
@Sql("select * from emp where salary > /* salary */0")
136+
String selectHogeCollect(BigDecimal salary, HogeFunction function);
137+
138+
129139

130140
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package doma.example.function;
2+
3+
import java.util.function.Function;
4+
import java.util.stream.Stream;
5+
6+
public class HogeFunction implements Function<Stream<String>, String> {
7+
8+
@Override
9+
public String apply(Stream<String> t) {
10+
return null;
11+
}
12+
}

0 commit comments

Comments
 (0)