Quick fix "add !!" for SMARTCAST_IMPOSSIBLE in certain situations
This commit is contained in:
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.util.isValidOperator
|
import org.jetbrains.kotlin.util.isValidOperator
|
||||||
|
|
||||||
@@ -106,6 +108,25 @@ class AddExclExclCallFix(val psiElement: PsiElement) : ExclExclCallFix() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object SmartCastImpossibleExclExclFixFactory: KotlinSingleIntentionActionFactory() {
|
||||||
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
|
if (diagnostic.factory !== Errors.SMARTCAST_IMPOSSIBLE) return null
|
||||||
|
val element = diagnostic.psiElement as? KtExpression ?: return null
|
||||||
|
|
||||||
|
val analyze = element.analyze(BodyResolveMode.PARTIAL)
|
||||||
|
val type = analyze.getType(element)
|
||||||
|
if (type == null || !TypeUtils.isNullableType(type)) return null
|
||||||
|
|
||||||
|
val diagnosticWithParameters = Errors.SMARTCAST_IMPOSSIBLE.cast(diagnostic)
|
||||||
|
val expectedType = diagnosticWithParameters.a
|
||||||
|
if (TypeUtils.isNullableType(expectedType)) return null
|
||||||
|
val nullableExpectedType = TypeUtils.makeNullable(expectedType)
|
||||||
|
if (!type.isSubtypeOf(nullableExpectedType)) return null
|
||||||
|
|
||||||
|
return AddExclExclCallFix(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object MissingIteratorExclExclFixFactory : KotlinSingleIntentionActionFactory() {
|
object MissingIteratorExclExclFixFactory : KotlinSingleIntentionActionFactory() {
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val element = diagnostic.psiElement
|
val element = diagnostic.psiElement
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
NULL_FOR_NONNULL_TYPE.registerFactory(factoryForTypeMismatchError)
|
NULL_FOR_NONNULL_TYPE.registerFactory(factoryForTypeMismatchError)
|
||||||
CONSTANT_EXPECTED_TYPE_MISMATCH.registerFactory(factoryForTypeMismatchError)
|
CONSTANT_EXPECTED_TYPE_MISMATCH.registerFactory(factoryForTypeMismatchError)
|
||||||
|
|
||||||
|
SMARTCAST_IMPOSSIBLE.registerFactory(SmartCastImpossibleExclExclFixFactory)
|
||||||
SMARTCAST_IMPOSSIBLE.registerFactory(CastExpressionFix.SmartCastImpossibleFactory)
|
SMARTCAST_IMPOSSIBLE.registerFactory(CastExpressionFix.SmartCastImpossibleFactory)
|
||||||
|
|
||||||
PLATFORM_CLASS_MAPPED_TO_KOTLIN.registerFactory(MapPlatformClassToKotlinFix)
|
PLATFORM_CLASS_MAPPED_TO_KOTLIN.registerFactory(MapPlatformClassToKotlinFix)
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// "Add non-null asserted (!!) call" "true"
|
||||||
|
// ACTION: Cast expression 'a' to 'Foo'
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
fun bar()
|
||||||
|
}
|
||||||
|
|
||||||
|
open class MyClass {
|
||||||
|
open val a: Foo? = null
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
if (a != null) {
|
||||||
|
<caret>a.bar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// "Add non-null asserted (!!) call" "true"
|
||||||
|
// ACTION: Cast expression 'a' to 'Foo'
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
fun bar()
|
||||||
|
}
|
||||||
|
|
||||||
|
open class MyClass {
|
||||||
|
open val a: Foo? = null
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
if (a != null) {
|
||||||
|
a!!.bar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -7662,6 +7662,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("addExclExclWhenSmartCastImpossible.kt")
|
||||||
|
public void testAddExclExclWhenSmartCastImpossible() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/addExclExclWhenSmartCastImpossible.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("addIntArrayOf.kt")
|
@TestMetadata("addIntArrayOf.kt")
|
||||||
public void testAddIntArrayOf() throws Exception {
|
public void testAddIntArrayOf() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/addIntArrayOf.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/addIntArrayOf.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user