J2K: Remove unnecessary casts of non-nullable expression to nullable type after conversion
#KT-11543 Fixed
This commit is contained in:
@@ -21,6 +21,7 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
||||
import org.jetbrains.kotlin.idea.core.setVisibility
|
||||
import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection
|
||||
import org.jetbrains.kotlin.idea.intentions.*
|
||||
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import java.util.*
|
||||
|
||||
@@ -54,6 +56,7 @@ object J2KPostProcessingRegistrar {
|
||||
_processings.add(ConvertToStringTemplateProcessing())
|
||||
_processings.add(UsePropertyAccessSyntaxProcessing())
|
||||
_processings.add(RemoveRedundantSamAdaptersProcessing())
|
||||
_processings.add(RemoveRedundantCastToNullableProcessing())
|
||||
|
||||
registerIntentionBasedProcessing(ConvertToExpressionBodyIntention()) { it is KtPropertyAccessor }
|
||||
registerIntentionBasedProcessing(IfThenToSafeAccessIntention())
|
||||
@@ -219,4 +222,23 @@ object J2KPostProcessingRegistrar {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RemoveRedundantCastToNullableProcessing : J2kPostProcessing {
|
||||
override fun createAction(element: KtElement, diagnostics: Diagnostics): (() -> Unit)? {
|
||||
if (element !is KtBinaryExpressionWithTypeRHS) return null
|
||||
|
||||
val context = element.analyzeAndGetResult().bindingContext
|
||||
val leftType = context.getType(element.left) ?: return null
|
||||
val rightType = context.get(BindingContext.TYPE, element.right) ?: return null
|
||||
|
||||
if (!leftType.isMarkedNullable && rightType.isMarkedNullable) {
|
||||
return {
|
||||
val type = element.right?.typeElement as? KtNullableType
|
||||
type?.replace(type.innerType!!)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
public class Passenger {
|
||||
public static class PassParent {
|
||||
}
|
||||
|
||||
public static class PassChild extends PassParent {
|
||||
}
|
||||
|
||||
public PassParent provideNullable(int p) {
|
||||
return p > 0 ? new PassChild() : null;
|
||||
}
|
||||
|
||||
public void test1() {
|
||||
PassParent pass = provideNullable(1);
|
||||
assert pass != null;
|
||||
accept1((PassChild) pass);
|
||||
}
|
||||
|
||||
public void test2() {
|
||||
PassParent pass = provideNullable(1);
|
||||
if (1 == 2) {
|
||||
assert pass != null;
|
||||
accept2((PassChild) pass);
|
||||
}
|
||||
accept2((PassChild) pass);
|
||||
}
|
||||
|
||||
public void accept1(PassChild p) {
|
||||
}
|
||||
|
||||
public void accept2(PassChild p) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// ERROR: Type mismatch: inferred type is Passenger.PassChild? but Passenger.PassChild was expected
|
||||
// ERROR: Type mismatch: inferred type is Passenger.PassChild? but Passenger.PassChild was expected
|
||||
class Passenger {
|
||||
open class PassParent
|
||||
|
||||
class PassChild : PassParent()
|
||||
|
||||
fun provideNullable(p: Int): PassParent? {
|
||||
return if (p > 0) PassChild() else null
|
||||
}
|
||||
|
||||
fun test1() {
|
||||
val pass = provideNullable(1)!!
|
||||
accept1(pass as PassChild)
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
val pass = provideNullable(1)
|
||||
if (1 == 2) {
|
||||
assert(pass != null)
|
||||
accept2(pass as PassChild?)
|
||||
}
|
||||
accept2(pass as PassChild?)
|
||||
}
|
||||
|
||||
fun accept1(p: PassChild) {
|
||||
}
|
||||
|
||||
fun accept2(p: PassChild) {
|
||||
}
|
||||
}
|
||||
@@ -3505,6 +3505,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notNullCast.java")
|
||||
public void testNotNullCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/nullability/notNullCast.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullableField.java")
|
||||
public void testNullableField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/nullability/nullableField.java");
|
||||
|
||||
@@ -3505,6 +3505,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notNullCast.java")
|
||||
public void testNotNullCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/nullability/notNullCast.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullableField.java")
|
||||
public void testNullableField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/nullability/nullableField.java");
|
||||
|
||||
Reference in New Issue
Block a user