diff --git a/src/main/kotlin/org/domaframework/doma/intellij/common/psi/PsiDaoMethod.kt b/src/main/kotlin/org/domaframework/doma/intellij/common/psi/PsiDaoMethod.kt index e674feac..74e6ee70 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/common/psi/PsiDaoMethod.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/common/psi/PsiDaoMethod.kt @@ -103,11 +103,6 @@ class PsiDaoMethod( private fun getSqlAnnotation(): PsiAnnotation? = DomaAnnotationType.Sql.getPsiAnnotation(psiMethod) - fun isSelectTypeCollect(): Boolean { - val selectAnnotation = DomaAnnotationType.Select.getPsiAnnotation(psiMethod) ?: return false - return daoType.isSelectTypeCollect(selectAnnotation) - } - fun useSqlAnnotation(): Boolean = getSqlAnnotation() != null private fun setSqlFilePath() { diff --git a/src/main/kotlin/org/domaframework/doma/intellij/common/util/DomaClassName.kt b/src/main/kotlin/org/domaframework/doma/intellij/common/util/DomaClassName.kt index 4ed14489..cad6023c 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/common/util/DomaClassName.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/common/util/DomaClassName.kt @@ -38,6 +38,7 @@ enum class DomaClassName( VOID("java.lang.Void"), RETURNING("org.seasar.doma.Returning"), REFERENCE("org.seasar.doma.jdbc.Reference"), + SELECT_OPTIONS("org.seasar.doma.jdbc.SelectOptions"), STRING("java.lang.String"), OBJECT("java.lang.Object"), diff --git a/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/DomaAnnotationType.kt b/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/DomaAnnotationType.kt index 3363fbbb..b58e30dc 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/DomaAnnotationType.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/DomaAnnotationType.kt @@ -18,9 +18,6 @@ package org.domaframework.doma.intellij.extension.psi import com.intellij.codeInsight.AnnotationUtil import com.intellij.psi.PsiAnnotation import com.intellij.psi.PsiModifierListOwner -import com.intellij.psi.PsiNameValuePair -import com.intellij.psi.PsiReferenceExpression -import com.intellij.psi.util.PsiTreeUtil enum class DomaAnnotationType( val fqdn: String, @@ -74,19 +71,4 @@ enum class DomaAnnotationType( } else { false } - - fun isSelectTypeCollect(element: PsiAnnotation): Boolean { - val strategyPair = - PsiTreeUtil - .getChildrenOfTypeAsList(element.parameterList, PsiNameValuePair::class.java) - .firstOrNull { - it.text.startsWith("strategy") - } ?: return false - - return PsiTreeUtil - .getChildOfType( - strategyPair, - PsiReferenceExpression::class.java, - )?.text == "SelectType.COLLECT" - } } diff --git a/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/PsiParameterExtension.kt b/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/PsiParameterExtension.kt index db2ba96d..3b2ab6a6 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/PsiParameterExtension.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/extension/psi/PsiParameterExtension.kt @@ -17,22 +17,29 @@ package org.domaframework.doma.intellij.extension.psi import com.intellij.psi.PsiClassType import com.intellij.psi.PsiParameter +import org.domaframework.doma.intellij.common.util.DomaClassName -val PsiParameter.isFunctionClazz: Boolean - get() = - (this.typeElement?.type as? PsiClassType) - ?.resolve() - ?.qualifiedName - ?.contains("java.util.function") == true +private val ignoreUsageCheckType = + listOf( + DomaClassName.JAVA_FUNCTION, + DomaClassName.BI_FUNCTION, + DomaClassName.SELECT_OPTIONS, + DomaClassName.JAVA_COLLECTOR, + ) -val PsiParameter.isSelectOption: Boolean - get() = - (this.typeElement?.type as? PsiClassType) - ?.resolve() - ?.qualifiedName == "org.seasar.doma.jdbc.SelectOptions" +fun PsiParameter.isIgnoreUsageCheck(): Boolean = + ignoreUsageCheckType.any { type -> + getSuperClassType(type) != null + } -val PsiParameter.isCollector: Boolean - get() = - (this.typeElement?.type as? PsiClassType) - ?.resolve() - ?.qualifiedName == "java.util.stream.Collector" +fun PsiParameter.getSuperClassType(superClassType: DomaClassName): PsiClassType? { + val clazzType = this.typeElement?.type as? PsiClassType + var superCollection: PsiClassType? = clazzType + while (superCollection != null && + !superClassType.isTargetClassNameStartsWith(superCollection.canonicalText) + ) { + superCollection = + superCollection.getSuperType(superClassType.className) + } + return superCollection +} diff --git a/src/main/kotlin/org/domaframework/doma/intellij/inspection/dao/visitor/UsedDaoMethodParamInspectionVisitor.kt b/src/main/kotlin/org/domaframework/doma/intellij/inspection/dao/visitor/UsedDaoMethodParamInspectionVisitor.kt index aeda9c84..d5b3fe64 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/inspection/dao/visitor/UsedDaoMethodParamInspectionVisitor.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/inspection/dao/visitor/UsedDaoMethodParamInspectionVisitor.kt @@ -27,9 +27,7 @@ import org.domaframework.doma.intellij.common.dao.getDaoClass import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType import org.domaframework.doma.intellij.common.psi.PsiDaoMethod import org.domaframework.doma.intellij.extension.findFile -import org.domaframework.doma.intellij.extension.psi.isCollector -import org.domaframework.doma.intellij.extension.psi.isFunctionClazz -import org.domaframework.doma.intellij.extension.psi.isSelectOption +import org.domaframework.doma.intellij.extension.psi.isIgnoreUsageCheck import org.domaframework.doma.intellij.extension.psi.methodParameters class UsedDaoMethodParamInspectionVisitor( @@ -44,8 +42,7 @@ class UsedDaoMethodParamInspectionVisitor( if (!psiDaoMethod.useSqlAnnotation() && !psiDaoMethod.isUseSqlFileMethod()) return val methodParameters = - method.methodParameters - .filter { !it.isFunctionClazz && !it.isSelectOption && !(it.isCollector && psiDaoMethod.isSelectTypeCollect()) } + method.methodParameters.filter { !it.isIgnoreUsageCheck() } val sqlFileManager = psiDaoMethod.sqlFile?.let { method.project.findFile(it) diff --git a/src/test/kotlin/org/domaframework/doma/intellij/inspection/dao/DomaUseVariableTest.kt b/src/test/kotlin/org/domaframework/doma/intellij/inspection/dao/DomaUseVariableTest.kt index a98ecd28..d7fc499a 100644 --- a/src/test/kotlin/org/domaframework/doma/intellij/inspection/dao/DomaUseVariableTest.kt +++ b/src/test/kotlin/org/domaframework/doma/intellij/inspection/dao/DomaUseVariableTest.kt @@ -36,7 +36,14 @@ class DomaUseVariableTest : DomaSqlTest() { "$testDaoName/collectDoesCauseError.sql", "$testDaoName/noErrorWhenUsedInFunctionParameters.sql", "$testDaoName/duplicateForDirectiveDefinitionNames.sql", + "$testDaoName/selectHogeFunction.sql", + "$testDaoName/functionDoesNotCauseError.sql", + "$testDaoName/selectHogeCollector.sql", ) + addOtherJavaFile("collector", "HogeCollector.java") + addOtherJavaFile("function", "HogeFunction.java") + addOtherJavaFile("function", "HogeBiFunction.java") + addOtherJavaFile("option", "HogeSelectOptions.java") myFixture.enableInspections(UsedDaoMethodParamInspection()) } diff --git a/src/test/testData/src/main/java/doma/example/dao/DaoMethodVariableInspectionTestDao.java b/src/test/testData/src/main/java/doma/example/dao/DaoMethodVariableInspectionTestDao.java index aec91b45..3cbb759c 100644 --- a/src/test/testData/src/main/java/doma/example/dao/DaoMethodVariableInspectionTestDao.java +++ b/src/test/testData/src/main/java/doma/example/dao/DaoMethodVariableInspectionTestDao.java @@ -17,7 +17,12 @@ import org.seasar.doma.jdbc.PreparedSql; import org.seasar.doma.jdbc.SelectOptions; import org.seasar.doma.SelectType; +import java.util.stream.Stream; +import java.util.function.Function; import java.util.stream.Collector; +import doma.example.function.*; +import doma.example.collector.*; +import doma.example.option.*; import java.util.List; import java.util.function.BiFunction; @@ -38,20 +43,52 @@ interface DaoMethodVariableInspectionTestDao { @SqlProcessor R biFunctionDoesNotCauseError(Integer id, BiFunction handler); + @SqlProcessor + @Sql("SELECT id, name FROM demo") + R biFunctionHogeFunction(HogeBiFunction handler); + + @Select + Project selectOptionDoesNotCauseError(Employee employee, + String searchName, + SelectOptions options); + @Select - Project selectOptionDoesNotCauseError(Employee employee,String searchName,SelectOptions options); + @Sql("SELECT * FROM project WHERE name = /* searchName */'test'") + Project selectHogeOption(Employee employee, + String searchName, + HogeSelectOptions options); @Select(strategy = SelectType.COLLECT) - Project collectDoesNotCauseError(Employee employee,Integer id,Collector collector); + Project collectDoesNotCauseError(Employee employee, + Integer id, + Collector collector); + + @Select(strategy = SelectType.COLLECT) + Project selectHogeCollector(Employee employee, + Integer id, + HogeCollector collector); @Select - Project collectDoesCauseError(Employee employee,String searchName,Collector collector); + Project collectDoesCauseError(Employee employee, + String searchName, + Collector collector); + + @Select(strategy = SelectType.STREAM) + String functionDoesNotCauseError(Employee employee, + Integer id, + Function, String> function); + + @Select(strategy = SelectType.STREAM) + String selectHogeFunction(Employee employee, + Integer id, + HogeFunction function); @Select Project noErrorWhenUsedInFunctionParameters(Employee employee, Integer count); @Select - Employee duplicateForDirectiveDefinitionNames(Employee member, Integer count, + Employee duplicateForDirectiveDefinitionNames(Employee member, + Integer count, List users, String searchName, Boolean inForm); diff --git a/src/test/testData/src/main/java/doma/example/function/HogeBiFunction.java b/src/test/testData/src/main/java/doma/example/function/HogeBiFunction.java new file mode 100644 index 00000000..2184f718 --- /dev/null +++ b/src/test/testData/src/main/java/doma/example/function/HogeBiFunction.java @@ -0,0 +1,17 @@ +package doma.example.function; + +import org.seasar.doma.jdbc.Config; +import org.seasar.doma.jdbc.PreparedSql; + +import java.io.ObjectInputFilter; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; + +public class HogeBiFunction implements BiFunction { + + @Override + public String apply(Config config, PreparedSql preparedSql) { + return ""; + } +} \ No newline at end of file diff --git a/src/test/testData/src/main/java/doma/example/option/HogeSelectOptions.java b/src/test/testData/src/main/java/doma/example/option/HogeSelectOptions.java new file mode 100644 index 00000000..143064e9 --- /dev/null +++ b/src/test/testData/src/main/java/doma/example/option/HogeSelectOptions.java @@ -0,0 +1,6 @@ +package doma.example.option; + +import org.seasar.doma.jdbc.SelectOptions; + +public class HogeSelectOptions extends SelectOptions { +} \ No newline at end of file diff --git a/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/functionDoesNotCauseError.sql b/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/functionDoesNotCauseError.sql new file mode 100644 index 00000000..f3bc02b9 --- /dev/null +++ b/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/functionDoesNotCauseError.sql @@ -0,0 +1,6 @@ +select + p.project_id + , p.project_name + , p.project_number +from project p +where p.project_id = /* id */0 \ No newline at end of file diff --git a/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/selectHogeCollector.sql b/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/selectHogeCollector.sql new file mode 100644 index 00000000..f3bc02b9 --- /dev/null +++ b/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/selectHogeCollector.sql @@ -0,0 +1,6 @@ +select + p.project_id + , p.project_name + , p.project_number +from project p +where p.project_id = /* id */0 \ No newline at end of file diff --git a/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/selectHogeFunction.sql b/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/selectHogeFunction.sql new file mode 100644 index 00000000..f3bc02b9 --- /dev/null +++ b/src/test/testData/src/main/resources/META-INF/doma/example/dao/DaoMethodVariableInspectionTestDao/selectHogeFunction.sql @@ -0,0 +1,6 @@ +select + p.project_id + , p.project_name + , p.project_number +from project p +where p.project_id = /* id */0 \ No newline at end of file