diff --git a/ChangeLog.md b/ChangeLog.md index 1540f4b4047..8892401b392 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -172,6 +172,7 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-13207`](https://youtrack.jetbrains.com/issue/KT-13207) Exception on safe delete from intention in 2016.2 - [`KT-12887`](https://youtrack.jetbrains.com/issue/KT-12887) "Extend selection" should select call's invoked expression - [`KT-6520`](https://youtrack.jetbrains.com/issue/KT-6520) Introduce 'maino' and 'psvmo' templates for generating main in object +- [`KT-13455`](https://youtrack.jetbrains.com/issue/KT-13455) Override/Implement: Make return type non-nullable (platform collection case) when overriding Java method - Fix exception when choose Gradle configurer after project is synced - Allow configuring Kotlin in Gradle module without Kotlin sources - Show all Kotlin annotations when browsing hierarchy of "java.lang.Annotation" diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt index ea9f85c3498..7606cff43a6 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt @@ -34,12 +34,18 @@ import org.jetbrains.kotlin.types.typeUtil.* import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.addToStdlib.singletonList -fun KotlinType.approximateFlexibleTypes(preferNotNull: Boolean = false): KotlinType { +fun KotlinType.approximateFlexibleTypes( + preferNotNull: Boolean = false, + preferStarForRaw: Boolean = false +): KotlinType { if (isDynamic()) return this - return approximateNonDynamicFlexibleTypes(preferNotNull) + return approximateNonDynamicFlexibleTypes(preferNotNull, preferStarForRaw) } -private fun KotlinType.approximateNonDynamicFlexibleTypes(preferNotNull: Boolean = false): SimpleType { +private fun KotlinType.approximateNonDynamicFlexibleTypes( + preferNotNull: Boolean = false, + preferStarForRaw: Boolean = false +): SimpleType { if (isFlexible()) { val flexible = asFlexibleType() val lowerClass = flexible.lowerBound.constructor.declarationDescriptor as? ClassDescriptor? @@ -51,6 +57,8 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes(preferNotNull: Boolean var approximation = if (isCollection) (if (isAnnotatedReadOnly()) flexible.upperBound else flexible.lowerBound).makeNullableAsSpecified(!preferNotNull) + else + if (this is RawType && preferStarForRaw) flexible.upperBound.makeNullableAsSpecified(!preferNotNull) else if (preferNotNull) flexible.lowerBound else flexible.upperBound diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt index 76039e4bf40..d4187dcc0df 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt @@ -31,13 +31,11 @@ import org.jetbrains.kotlin.idea.core.util.DescriptorMemberChooserObject import org.jetbrains.kotlin.idea.j2k.IdeaDocCommentConverter import org.jetbrains.kotlin.idea.kdoc.KDocElementFactory import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.findDocComment.findDocComment import org.jetbrains.kotlin.renderer.* import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.isFlexible -import org.jetbrains.kotlin.types.typeUtil.makeNotNullable interface OverrideMemberChooserObject : ClassMember { enum class BodyType { @@ -161,10 +159,7 @@ private fun generateConstructorParameter(project: Project, descriptor: PropertyD private fun generateFunction(project: Project, descriptor: FunctionDescriptor, bodyType: OverrideMemberChooserObject.BodyType): KtNamedFunction { val newDescriptor = object : FunctionDescriptor by descriptor { override fun getModality() = Modality.OPEN - override fun getReturnType(): KotlinType? { - val originalType = descriptor.returnType ?: return null - return if (originalType.isFlexible()) originalType.makeNotNullable() else originalType - } + override fun getReturnType() = descriptor.returnType?.approximateFlexibleTypes(preferNotNull = true, preferStarForRaw = true) override fun getOverriddenDescriptors() = listOf(descriptor) override fun accept(visitor: DeclarationDescriptorVisitor, data: D) = visitor.visitFunctionDescriptor(this, data) } diff --git a/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/A.java b/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/A.java new file mode 100644 index 00000000000..d1f0d20d7a4 --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/A.java @@ -0,0 +1,7 @@ +package foo; + +import java.util.List; + +public interface A { + List foo(); +} diff --git a/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/Impl.kt b/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/Impl.kt new file mode 100644 index 00000000000..cb7bb6ac6af --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/Impl.kt @@ -0,0 +1,5 @@ +import foo.A + +class B : A { + +} diff --git a/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/Impl.kt.after b/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/Impl.kt.after new file mode 100644 index 00000000000..a67733048d0 --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/platformCollectionTypes/foo/Impl.kt.after @@ -0,0 +1,7 @@ +import foo.A + +class B : A { + override fun foo(): MutableList { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt index 6af91aece20..ef6e046b6f3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt @@ -248,6 +248,10 @@ class OverrideImplementTest : AbstractOverrideImplementTest() { doOverrideDirectoryTest("foo") } + fun testPlatformCollectionTypes() { + doOverrideDirectoryTest("foo") + } + fun testNullableJavaType() { doOverrideDirectoryTest("foo") }