Add quickfix for UnsafeCastFromDynamicInspection #KT-20915 Fixed
This commit is contained in:
committed by
Alexey Sedunov
parent
f709a382ae
commit
113e9f496e
@@ -5,14 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.inspections
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.codeInspection.*
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.expressionVisitor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
|
||||
@@ -24,8 +25,26 @@ class UnsafeCastFromDynamicInspection : AbstractKotlinInspection() {
|
||||
val actualType = expression.getType(context) ?: return
|
||||
|
||||
if (actualType.isDynamic() && !expectedType.isDynamic() && !TypeUtils.noExpectedType(expectedType)) {
|
||||
holder.registerProblem(expression, "Implicit (unsafe) cast from dynamic to $expectedType")
|
||||
holder.registerProblem(
|
||||
expression,
|
||||
"Implicit (unsafe) cast from dynamic to $expectedType",
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
CastExplicitlyFix(expectedType))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private class CastExplicitlyFix(private val type: KotlinType) : LocalQuickFix {
|
||||
override fun getName() = "Cast explicitly"
|
||||
|
||||
override fun getFamilyName() = name
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val expression = descriptor.psiElement as? KtExpression ?: return
|
||||
val typeName = type.constructor.declarationDescriptor?.name ?: return
|
||||
val pattern = if (type.isMarkedNullable) "$0 as? $1" else "$0 as $1"
|
||||
val newExpression = KtPsiFactory(expression).createExpressionByPattern(pattern, expression, typeName)
|
||||
expression.replace(newExpression)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.inspections.UnsafeCastFromDynamicInspection
|
||||
@@ -0,0 +1,6 @@
|
||||
// JS
|
||||
fun test() {
|
||||
val d: dynamic = Any()
|
||||
var i: Int = 0
|
||||
i = <caret>d + d
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// JS
|
||||
fun test() {
|
||||
val d: dynamic = Any()
|
||||
var i: Int = 0
|
||||
i = (d + d) as Int
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// JS
|
||||
fun test() {
|
||||
val d: dynamic = Any()
|
||||
var s: String? = null
|
||||
s = <caret>d
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// JS
|
||||
fun test() {
|
||||
val d: dynamic = Any()
|
||||
var s: String? = null
|
||||
s = d as? String
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// JS
|
||||
fun test() {
|
||||
val d: dynamic = Any()
|
||||
var s: String = ""
|
||||
s = <caret>d
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// JS
|
||||
fun test() {
|
||||
val d: dynamic = Any()
|
||||
var s: String = ""
|
||||
s = d as String
|
||||
}
|
||||
+27
@@ -4081,6 +4081,33 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/unsafeCastFromDynamic")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UnsafeCastFromDynamic extends AbstractLocalInspectionTest {
|
||||
public void testAllFilesPresentInUnsafeCastFromDynamic() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/unsafeCastFromDynamic"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("binaryExpression.kt")
|
||||
public void testBinaryExpression() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/unsafeCastFromDynamic/binaryExpression.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullable.kt")
|
||||
public void testNullable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/unsafeCastFromDynamic/nullable.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/unsafeCastFromDynamic/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/unusedReceiverParameter")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user