diff --git a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.kt b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.kt index 205bc4f0ca3..52fc47305f0 100644 --- a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.kt +++ b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.kt @@ -19,6 +19,5 @@ public class Y extends X { fun main() { checkSubtype(Y().fooN()) - Y().barN(null); + Y().barN(null); } - diff --git a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.txt b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.txt index 04ca74d4447..8a73fb1f86b 100644 --- a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.txt +++ b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-SpecialTypes.txt @@ -20,9 +20,9 @@ public open class X { public open class Y : X { public constructor Y() - public/*package*/ open override /*1*/ /*fake_override*/ fun barN(/*0*/ org.jetbrains.annotations.NotNull() a: kotlin.String!): kotlin.Unit + public/*package*/ open override /*1*/ /*fake_override*/ fun barN(/*0*/ org.jetbrains.annotations.NotNull() a: kotlin.String): kotlin.Unit public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - org.jetbrains.annotations.NotNull() public/*package*/ open override /*1*/ /*fake_override*/ fun fooN(): kotlin.String! + org.jetbrains.annotations.NotNull() public/*package*/ open override /*1*/ /*fake_override*/ fun fooN(): kotlin.String public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.kt b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.kt index 1c9610d9195..2dc98dd7583 100644 --- a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.kt +++ b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.kt @@ -19,6 +19,5 @@ public class Y extends X { fun main() { checkSubtype(Y().fooN()) - Y().barN(null); + Y().barN(null); } - diff --git a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.txt b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.txt index 0363db8ebbb..af87cc89d5b 100644 --- a/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.txt +++ b/compiler/testData/diagnostics/tests/j+k/SupertypeArgumentsNullability-NotNull-UserTypes.txt @@ -20,9 +20,9 @@ public open class X { public open class Y : X { public constructor Y() - public/*package*/ open override /*1*/ /*fake_override*/ fun barN(/*0*/ org.jetbrains.annotations.NotNull() a: A!): kotlin.Unit + public/*package*/ open override /*1*/ /*fake_override*/ fun barN(/*0*/ org.jetbrains.annotations.NotNull() a: A): kotlin.Unit public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - org.jetbrains.annotations.NotNull() public/*package*/ open override /*1*/ /*fake_override*/ fun fooN(): A! + org.jetbrains.annotations.NotNull() public/*package*/ open override /*1*/ /*fake_override*/ fun fooN(): A public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/saveAnnotationAfterSubstitution.kt b/compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/saveAnnotationAfterSubstitution.kt new file mode 100644 index 00000000000..33bdd9ca0f1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/saveAnnotationAfterSubstitution.kt @@ -0,0 +1,47 @@ +// FILE: A.java + +import org.jetbrains.annotations.*; + +interface A { + void foo(@NotNull T x, @Nullable T y); +} + +// FILE: B1.java + +// contains fake_override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?) +interface B1 extends A {} + +// FILE: B2.java +import org.jetbrains.annotations.*; + +interface B2 extends A { + // Ok, consistent override + // override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?) + void foo(@NotNull String x, @Nullable String y); +} + +// FILE: B3.java +import org.jetbrains.annotations.*; + +interface B3 extends A { + // inconsistent override, second parameter type is platform + // TODO: first one should be platform too, but it's not because when substituting T -> String!, + // value parameter type becomes platform and it can be overridden with @NotNull String. + // Conceptual problem: we can use type parameter as T?, but there is no way to specify same semantics as in Java `@NotNull T`. + + // override /*1*/ fun foo(/*0*/ org.jetbrains.annotations.Nullable() x: kotlin.String?, /*1*/ org.jetbrains.annotations.NotNull() y: kotlin.String!): kotlin.Unit + void foo(@Nullable String x, @NotNull String y); +} + +// FILE: main.kt + +// fake_override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit +interface C1 : A + +// fake_override fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String?, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit +interface C2 : A + +interface C3 : B1 { + // inconsistent override + override fun foo(x: String?, y: String?); +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/saveAnnotationAfterSubstitution.txt b/compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/saveAnnotationAfterSubstitution.txt new file mode 100644 index 00000000000..a9a6a6124a4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/saveAnnotationAfterSubstitution.txt @@ -0,0 +1,56 @@ +package + +public/*package*/ /*synthesized*/ fun A(/*0*/ function: (T!, T!) -> kotlin.Unit): A +public/*package*/ /*synthesized*/ fun B1(/*0*/ function: (kotlin.String!, kotlin.String?) -> kotlin.Unit): B1 +public/*package*/ /*synthesized*/ fun B2(/*0*/ function: (kotlin.String!, kotlin.String!) -> kotlin.Unit): B2 +public/*package*/ /*synthesized*/ fun B3(/*0*/ function: (kotlin.String!, kotlin.String!) -> kotlin.Unit): B3 + +public/*package*/ interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: T, /*1*/ org.jetbrains.annotations.Nullable() y: T?): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ interface B1 : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ interface B2 : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ interface B3 : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ org.jetbrains.annotations.Nullable() x: kotlin.String?, /*1*/ org.jetbrains.annotations.NotNull() y: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal interface C1 : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal interface C2 : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String?, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal interface C3 : B1 { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: kotlin.String, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.String?): kotlin.Unit + internal abstract fun foo(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 39c8d2abb34..1fc9afd337e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -10463,6 +10463,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("saveAnnotationAfterSubstitution.kt") + public void testSaveAnnotationAfterSubstitution() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/saveAnnotationAfterSubstitution.kt"); + doTest(fileName); + } + @TestMetadata("supertypeDifferentParameterNullability.kt") public void testSupertypeDifferentParameterNullability() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/supertypeDifferentParameterNullability.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt index d6627b229fb..03a1cc364d5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt @@ -69,6 +69,8 @@ class FilteredAnnotations( class CompositeAnnotations( private val delegates: List ) : Annotations { + constructor(vararg delegates: Annotations): this(delegates.toList()) + override fun isEmpty() = delegates.all { it.isEmpty() } override fun findAnnotation(fqName: FqName) = delegates.asSequence().map { it.findAnnotation(fqName) }.filterNotNull().firstOrNull() diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index dad4ac43afb..55bcc9e499a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; +import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations; import org.jetbrains.kotlin.resolve.calls.inference.InferencePackage; import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope; import org.jetbrains.kotlin.types.typeUtil.TypeUtilPackage; @@ -221,6 +222,14 @@ public class TypeSubstitutor { substitutedType = TypeUtils.makeNullableIfNeeded(replacement.getType(), type.isMarkedNullable()); } + // substitutionType.annotations = replacement.annotations ++ type.annotations + if (!type.getAnnotations().isEmpty()) { + substitutedType = TypeUtilPackage.replaceAnnotations( + substitutedType, + new CompositeAnnotations(substitutedType.getAnnotations(), type.getAnnotations()) + ); + } + Variance resultingProjectionKind = varianceConflict == VarianceConflictType.NO_CONFLICT ? combine(originalProjectionKind, replacement.getProjectionKind()) : originalProjectionKind; diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt index 69655659bf0..fcd3e47d85e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt @@ -95,7 +95,7 @@ public class UnusedReceiverParameterInspection : AbstractKotlinInspection() { return JetBundle.message("unused.receiver.parameter.remove") } - override fun applyFix(project: Project, descriptor: ProblemDescriptor?) { + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { declaration.setReceiverTypeReference(null) } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt index 73670008380..4aa5f387255 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt @@ -112,7 +112,7 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() { override fun getFamilyName() = "Safe delete" - override fun applyFix(project: Project, descriptor: ProblemDescriptor?) { + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { if (!FileModificationService.getInstance().prepareFileForWrite(declaration.getContainingFile())) return SafeDeleteHandler.invoke(project, arrayOf(declaration), false) }