diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/array.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/array.kt index 42086763d95..2dce002aff8 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/array.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/array.kt @@ -24,11 +24,11 @@ fun test() { val platformJ = J.staticJ platformNN[0] - platformN[0] + platformN[0] platformJ[0] platformNN[0] = 1 - platformN[0] = 1 + platformN[0] = 1 platformJ[0] = 1 } diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/primitiveArray.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/primitiveArray.kt new file mode 100644 index 00000000000..84a3c69f789 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/primitiveArray.kt @@ -0,0 +1,34 @@ +// FILE: p/J.java +package p; + +import org.jetbrains.annotations.*; + +public class J { + @NotNull + public static int[] staticNN; + @Nullable + public static int[] staticN; + public static int[] staticJ; +} + +// FILE: k.kt + +import p.* + +fun test() { + // @NotNull platform type + val platformNN = J.staticNN + // @Nullable platform type + val platformN = J.staticN + // platform type with no annotation + val platformJ = J.staticJ + + platformNN[0] + platformN[0] + platformJ[0] + + platformNN[0] = 1 + platformN[0] = 1 + platformJ[0] = 1 +} + diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/primitiveArray.txt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/primitiveArray.txt new file mode 100644 index 00000000000..b8def46715c --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/primitiveArray.txt @@ -0,0 +1,3 @@ +package + +internal fun test(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 5133abe2e90..4eb1a34f535 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -8634,6 +8634,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("primitiveArray.kt") + public void testPrimitiveArray() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/primitiveArray.kt"); + doTest(fileName); + } + @TestMetadata("throw.kt") public void testThrow() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/throw.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/annotationUtils.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/annotationUtils.kt index da8054d45bf..7a2e27844dd 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/annotationUtils.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/annotationUtils.kt @@ -41,11 +41,9 @@ class LazyJavaAnnotations( return annotationDescriptors(jAnnotation) } - [suppress("UNCHECKED_CAST")] // any iterator can be cast to MutableIterator - override fun iterator(): MutableIterator - = annotationOwner.getAnnotations().stream().map { annotationDescriptors(it) }.filterNotNull().iterator() as MutableIterator + override fun iterator() = annotationOwner.getAnnotations().stream().map { annotationDescriptors(it) }.filterNotNull().iterator() - override fun isEmpty() = iterator().hasNext() + override fun isEmpty() = !iterator().hasNext() } fun LazyJavaResolverContext.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index 51bc4d349b1..f7e72290801 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.load.java.JvmAnnotationNames import kotlin.platform.platformStatic +import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations class LazyJavaTypeResolver( private val c: LazyJavaResolverContext, @@ -63,27 +64,29 @@ class LazyJavaTypeResolver( } public fun transformArrayType(arrayType: JavaArrayType, attr: JavaTypeAttributes, isVararg: Boolean = false): JetType { - val javaComponentType = arrayType.getComponentType() - if (javaComponentType is JavaPrimitiveType) { - val jetType = JavaToKotlinClassMap.INSTANCE.mapPrimitiveKotlinClass("[" + javaComponentType.getCanonicalText()) - if (jetType != null) { - return if (PLATFORM_TYPES && attr.allowFlexible) - FlexibleJavaClassifierTypeCapabilities.create(jetType, TypeUtils.makeNullable(jetType)) - else TypeUtils.makeNullableAsSpecified(jetType, !attr.isMarkedNotNull) + return run { (): JetType -> + val javaComponentType = arrayType.getComponentType() + if (javaComponentType is JavaPrimitiveType) { + val jetType = JavaToKotlinClassMap.INSTANCE.mapPrimitiveKotlinClass("[" + javaComponentType.getCanonicalText()) + if (jetType != null) { + return@run if (PLATFORM_TYPES && attr.allowFlexible) + FlexibleJavaClassifierTypeCapabilities.create(jetType, TypeUtils.makeNullable(jetType)) + else TypeUtils.makeNullableAsSpecified(jetType, !attr.isMarkedNotNull) + } } - } - val componentType = transformJavaType(javaComponentType, TYPE_ARGUMENT.toAttributes(attr.allowFlexible)) + val componentType = transformJavaType(javaComponentType, TYPE_ARGUMENT.toAttributes(attr.allowFlexible)) - if (PLATFORM_TYPES && attr.allowFlexible) { - return FlexibleJavaClassifierTypeCapabilities.create( - KotlinBuiltIns.getInstance().getArrayType(INVARIANT, componentType), - TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getArrayType(OUT_VARIANCE, componentType))) - } + if (PLATFORM_TYPES && attr.allowFlexible) { + return@run FlexibleJavaClassifierTypeCapabilities.create( + KotlinBuiltIns.getInstance().getArrayType(INVARIANT, componentType), + TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getArrayType(OUT_VARIANCE, componentType))) + } - val projectionKind = if (attr.howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT || isVararg) OUT_VARIANCE else INVARIANT - val result = KotlinBuiltIns.getInstance().getArrayType(projectionKind, componentType) - return TypeUtils.makeNullableAsSpecified(result, !attr.isMarkedNotNull) + val projectionKind = if (attr.howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT || isVararg) OUT_VARIANCE else INVARIANT + val result = KotlinBuiltIns.getInstance().getArrayType(projectionKind, componentType) + return@run TypeUtils.makeNullableAsSpecified(result, !attr.isMarkedNotNull) + }.replaceAnnotations(attr.annotations) } private class LazyStarProjection( diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index a72b02eec33..7ef2423f84a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -30,6 +30,8 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.types.TypeProjection import org.jetbrains.kotlin.types.TypeProjectionImpl +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.types.DelegatingType fun JetType.getContainedTypeParameters(): Collection { val declarationDescriptor = getConstructor().getDeclarationDescriptor() @@ -72,4 +74,13 @@ fun TypeProjection.substitute(doSubstitute: (JetType) -> JetType): TypeProjectio return if (isStarProjection()) this else TypeProjectionImpl(getProjectionKind(), doSubstitute(getType())) +} + +fun JetType.replaceAnnotations(newAnnotations: Annotations): JetType { + if (newAnnotations.isEmpty()) return this + return object : DelegatingType() { + override fun getDelegate() = this@replaceAnnotations + + override fun getAnnotations() = newAnnotations + } } \ No newline at end of file