From f98b354bc1a0c169c890af2603cf2d1f7401f242 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 20 Nov 2015 15:58:49 +0300 Subject: [PATCH] KT-10005 Java to Kotlin: do not convert type cast to cast to nullable if it should not be null #KT-10005 Fixed --- .../jetbrains/kotlin/j2k/ExpressionConverter.kt | 16 ++++++++++++++-- .../typeCastExpression/beforeDot.java | 6 ++++++ .../typeCastExpression/beforeDot.kt | 6 ++++++ ...ToKotlinConverterForWebDemoTestGenerated.java | 6 ++++++ ...ToKotlinConverterSingleFileTestGenerated.java | 6 ++++++ 5 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 j2k/testData/fileOrElement/typeCastExpression/beforeDot.java create mode 100644 j2k/testData/fileOrElement/typeCastExpression/beforeDot.kt diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt index b7238ed2ac0..e4103b2433d 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt @@ -480,12 +480,24 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter { result = MethodCallExpression.buildNotNull(operandConverted, typeConversion) } else { - val typeConverted = typeConverter.convertType(castType.getType(), - if (operandConverted.isNullable) Nullability.Nullable else Nullability.NotNull) + val nullability = if (operandConverted.isNullable && !expression.isQualifier()) + Nullability.Nullable + else + Nullability.NotNull + val typeConverted = typeConverter.convertType(castType.type, nullability) result = TypeCastExpression(typeConverted, operandConverted) } } + private fun PsiExpression.isQualifier(): Boolean { + val parent = parent + when (parent) { + is PsiParenthesizedExpression -> return parent.isQualifier() + is PsiReferenceExpression -> return this == parent.qualifierExpression + else -> return false + } + } + override fun visitPolyadicExpression(expression: PsiPolyadicExpression) { val args = expression.getOperands().map { codeConverter.convertExpression(it, expression.getType()) } result = PolyadicExpression(args, getOperatorString(expression.getOperationTokenType())) diff --git a/j2k/testData/fileOrElement/typeCastExpression/beforeDot.java b/j2k/testData/fileOrElement/typeCastExpression/beforeDot.java new file mode 100644 index 00000000000..62f6074a81e --- /dev/null +++ b/j2k/testData/fileOrElement/typeCastExpression/beforeDot.java @@ -0,0 +1,6 @@ +public class A { + void foo(Object o) { + if (o == null) return; + int length = ((String) o).length(); + } +} \ No newline at end of file diff --git a/j2k/testData/fileOrElement/typeCastExpression/beforeDot.kt b/j2k/testData/fileOrElement/typeCastExpression/beforeDot.kt new file mode 100644 index 00000000000..32f542ddd3a --- /dev/null +++ b/j2k/testData/fileOrElement/typeCastExpression/beforeDot.kt @@ -0,0 +1,6 @@ +class A { + internal fun foo(o: Any?) { + if (o == null) return + val length = (o as String).length + } +} \ No newline at end of file diff --git a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java index 065da559f37..d587d284d7e 100644 --- a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java +++ b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java @@ -4318,6 +4318,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/typeCastExpression"), Pattern.compile("^(.+)\\.java$"), true); } + @TestMetadata("beforeDot.java") + public void testBeforeDot() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/typeCastExpression/beforeDot.java"); + doTest(fileName); + } + @TestMetadata("castNullable.java") public void testCastNullable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/typeCastExpression/castNullable.java"); diff --git a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java index 32c5191b721..0ee00c4c297 100644 --- a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java +++ b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java @@ -4318,6 +4318,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/typeCastExpression"), Pattern.compile("^(.+)\\.java$"), true); } + @TestMetadata("beforeDot.java") + public void testBeforeDot() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/typeCastExpression/beforeDot.java"); + doTest(fileName); + } + @TestMetadata("castNullable.java") public void testCastNullable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/typeCastExpression/castNullable.java");