From 94c5344fd12f29e32b24b29d4a09f8bc8d20dd16 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Fri, 23 Mar 2018 19:53:47 +0300 Subject: [PATCH] Check explicit type specification in "Might be const" inspection So #KT-23303 Fixed --- .../inspections/MayBeConstantInspection.kt | 16 ++++++---- .../mayBeConstant/ecplicitType.kt | 1 + .../mayBeConstant/ecplicitType.kt.after | 1 + .../mayBeConstant/ecplicitType2.kt | 1 + .../mayBeConstant/ecplicitType2.kt.after | 1 + .../mayBeConstant/ecplicitType3.kt | 1 + .../mayBeConstant/ecplicitType3.kt.after | 1 + .../mayBeConstant/ecplicitType4.kt | 2 ++ .../mayBeConstant/ecplicitType5.kt | 2 ++ .../LocalInspectionTestGenerated.java | 30 +++++++++++++++++++ 10 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt.after create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt.after create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt.after create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType4.kt create mode 100644 idea/testData/inspectionsLocal/mayBeConstant/ecplicitType5.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MayBeConstantInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MayBeConstantInspection.kt index 932c9690a19..6525360df55 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MayBeConstantInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MayBeConstantInspection.kt @@ -9,6 +9,7 @@ import com.intellij.codeInspection.IntentionWrapper import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.PsiElementVisitor +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.inspections.MayBeConstantInspection.Status.* @@ -44,10 +45,10 @@ class MayBeConstantInspection : AbstractKotlinInspection() { MIGHT_BE_CONST_ERRONEOUS, JVM_FIELD_MIGHT_BE_CONST_ERRONEOUS -> return@propertyVisitor MIGHT_BE_CONST, JVM_FIELD_MIGHT_BE_CONST -> { holder.registerProblem( - property.nameIdentifier ?: property, - if (status == JVM_FIELD_MIGHT_BE_CONST) "'const' might be used instead of '@JvmField'" else "Might be 'const'", - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, - IntentionWrapper(AddConstModifierFix(property), property.containingFile) + property.nameIdentifier ?: property, + if (status == JVM_FIELD_MIGHT_BE_CONST) "'const' might be used instead of '@JvmField'" else "Might be 'const'", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + IntentionWrapper(AddConstModifierFix(property), property.containingFile) ) } } @@ -57,7 +58,8 @@ class MayBeConstantInspection : AbstractKotlinInspection() { companion object { fun KtProperty.getStatus(): Status { if (isLocal || isVar || getter != null || - hasModifier(KtTokens.CONST_KEYWORD) || hasModifier(KtTokens.OVERRIDE_KEYWORD)) { + hasModifier(KtTokens.CONST_KEYWORD) || hasModifier(KtTokens.OVERRIDE_KEYWORD) + ) { return NONE } if (!isTopLevel && containingClassOrObject !is KtObjectDeclaration) return NONE @@ -66,13 +68,15 @@ class MayBeConstantInspection : AbstractKotlinInspection() { // For some reason constant evaluation does not work for property.analyze() val context = (initializer ?: this).analyze(BodyResolveMode.PARTIAL) val propertyDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, this] as? VariableDescriptor ?: return NONE + val type = propertyDescriptor.type + if (!KotlinBuiltIns.isPrimitiveType(type) && !KotlinBuiltIns.isString(type)) return NONE val withJvmField = propertyDescriptor.hasJvmFieldAnnotation() if (annotationEntries.isNotEmpty() && !withJvmField) return NONE return when { initializer != null -> { val compileTimeConstant = ConstantExpressionEvaluator.getConstant( - initializer, context + initializer, context ) ?: return NONE val erroneousConstant = compileTimeConstant.usesNonConstValAsConstant compileTimeConstant.toConstantValue(propertyDescriptor.type).takeIf { diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt new file mode 100644 index 00000000000..37987f518b9 --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt @@ -0,0 +1 @@ +val foo: Int = 0 \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt.after b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt.after new file mode 100644 index 00000000000..0a024eca703 --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt.after @@ -0,0 +1 @@ +const val foo: Int = 0 \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt new file mode 100644 index 00000000000..961ce76cba3 --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt @@ -0,0 +1 @@ +val foo: Boolean = true \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt.after b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt.after new file mode 100644 index 00000000000..c15acffbb4e --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt.after @@ -0,0 +1 @@ +const val foo: Boolean = true \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt new file mode 100644 index 00000000000..7066bacbe86 --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt @@ -0,0 +1 @@ +val foo: String = "" \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt.after b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt.after new file mode 100644 index 00000000000..6ff5e1bd7ec --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt.after @@ -0,0 +1 @@ +const val foo: String = "" \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType4.kt b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType4.kt new file mode 100644 index 00000000000..97624c5d0f8 --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType4.kt @@ -0,0 +1,2 @@ +// PROBLEM: none +val foo: Any = "" diff --git a/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType5.kt b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType5.kt new file mode 100644 index 00000000000..d4a229187cf --- /dev/null +++ b/idea/testData/inspectionsLocal/mayBeConstant/ecplicitType5.kt @@ -0,0 +1,2 @@ +// PROBLEM: none +val foo: Number = 0 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 9352c950b9f..41c7f680314 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -2358,6 +2358,36 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { doTest(fileName); } + @TestMetadata("ecplicitType.kt") + public void testEcplicitType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/mayBeConstant/ecplicitType.kt"); + doTest(fileName); + } + + @TestMetadata("ecplicitType2.kt") + public void testEcplicitType2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/mayBeConstant/ecplicitType2.kt"); + doTest(fileName); + } + + @TestMetadata("ecplicitType3.kt") + public void testEcplicitType3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/mayBeConstant/ecplicitType3.kt"); + doTest(fileName); + } + + @TestMetadata("ecplicitType4.kt") + public void testEcplicitType4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/mayBeConstant/ecplicitType4.kt"); + doTest(fileName); + } + + @TestMetadata("ecplicitType5.kt") + public void testEcplicitType5() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/mayBeConstant/ecplicitType5.kt"); + doTest(fileName); + } + @TestMetadata("enum.kt") public void testEnum() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/mayBeConstant/enum.kt");