diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 8d11767ff2f..16566c7aad3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.idea.MainFunctionDetector +import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion import org.jetbrains.kotlin.modules.TargetId @@ -34,6 +35,7 @@ import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver +import org.jetbrains.kotlin.resolve.deprecation.DeprecationSettings import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin @@ -143,7 +145,7 @@ class GenerationState private constructor( CompilerDeserializationConfiguration(configuration.languageVersionSettings) val deprecationProvider = - DeprecationResolver(LockBasedStorageManager.NO_LOCKS, configuration.languageVersionSettings, CoroutineCompatibilitySupport.ENABLED) + DeprecationResolver(LockBasedStorageManager.NO_LOCKS, configuration.languageVersionSettings, CoroutineCompatibilitySupport.ENABLED, JavaDeprecationSettings) init { val icComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index b336d070533..7640181690d 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -72,6 +72,8 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis( useInstance(InternalFlexibleTypeTransformer) useImpl() + + useInstance(JavaDeprecationSettings) } fun createContainerForLazyResolveWithJava( diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaDeprecationSettings.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaDeprecationSettings.kt new file mode 100644 index 00000000000..09cacaa550d --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaDeprecationSettings.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.load.java.components + +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.resolve.deprecation.DeprecationSettings + +object JavaDeprecationSettings : DeprecationSettings { + override fun propagatedToOverrides(deprecationAnnotation: AnnotationDescriptor): Boolean { + if (deprecationAnnotation is JavaDeprecatedAnnotationDescriptor) return false + return true + } +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt index ac8963b8455..72ff17c337b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.constants.KClassValue import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver +import org.jetbrains.kotlin.resolve.deprecation.DeprecationSettings import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe @@ -215,7 +216,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { // "-Xuse-experimental" arguments. However, it's not easy to do this. This should be solved in the future with the support of // module annotations. For now, we only check deprecations because this is needed to correctly retire unneeded compiler arguments. val deprecationResolver = - DeprecationResolver(LockBasedStorageManager("ExperimentalUsageChecker"), languageVersionSettings, CoroutineCompatibilitySupport.ENABLED) + DeprecationResolver(LockBasedStorageManager("ExperimentalUsageChecker"), languageVersionSettings, CoroutineCompatibilitySupport.ENABLED, DeprecationSettings.Default) // Returns true if fqName refers to a valid experimental API marker. fun checkAnnotation(fqName: String): Boolean { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt index a96570fc0da..9e91af04095 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt @@ -20,7 +20,11 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue.* import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.utils.addToStdlib.safeAs -internal data class DeprecatedByAnnotation(val annotation: AnnotationDescriptor, override val target: DeclarationDescriptor) : Deprecation { +internal data class DeprecatedByAnnotation( + val annotation: AnnotationDescriptor, + override val target: DeclarationDescriptor, + override val propagatesToOverrides: Boolean +) : Deprecation { override val deprecationLevel: DeprecationLevelValue get() = when (annotation.argumentValue("level")?.safeAs()?.enumEntryName?.asString()) { "WARNING" -> WARNING diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt index 9b17f22ea8e..b3c92b995fd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt @@ -36,7 +36,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs class DeprecationResolver( storageManager: StorageManager, private val languageVersionSettings: LanguageVersionSettings, - private val coroutineCompatibilitySupport: CoroutineCompatibilitySupport + private val coroutineCompatibilitySupport: CoroutineCompatibilitySupport, + private val deprecationSettings: DeprecationSettings ) { private val deprecations = storageManager.createMemoizedFunction { descriptor: DeclarationDescriptor -> val deprecations = descriptor.getOwnDeprecations() @@ -126,6 +127,28 @@ class DeprecationResolver( if (hasUndeprecatedOverridden || deprecations.isEmpty()) return null + // We might've filtered out not-propagating deprecations already in the initializer of `deprecationsByAnnotation` in the code above. + // But it would lead to treating Java overridden as not-deprecated at all that works controversially in case of mixed J/K override: + // interface J { + // @Deprecated + // void foo(); + // } + // + // interface K { + // @Deprecated("") + // fun foo(); + // } + // + // class K1 : K, J { + // // We'd probably better treating it as deprecated + // // Basically, it's just a corner case and we may change the behavior if it's too annoying + // override fun foo() {} + // } + // + // Also, we don't ignore non-propagating deprecations in case of fake overrides + // Because we don't want to depend on the choice of the base descriptor + if (root.kind.isReal && deprecations.none(Deprecation::propagatesToOverrides)) return null + return DeprecatedByOverridden(deprecations) } @@ -166,7 +189,11 @@ class DeprecationResolver( val annotation = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated) ?: annotations.findAnnotation(JAVA_DEPRECATED) if (annotation != null) { - val deprecatedByAnnotation = DeprecatedByAnnotation(annotation, this) + val deprecatedByAnnotation = + DeprecatedByAnnotation( + annotation, this, + deprecationSettings.propagatedToOverrides(annotation) + ) val deprecation = when { this is TypeAliasConstructorDescriptor -> DeprecatedTypealiasByAnnotation(typeAliasDescriptor, deprecatedByAnnotation) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt index fdf8c619ad5..fb7c2115131 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.deprecation import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.container.DefaultImplementation +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.resolve.annotations.argumentValue @@ -70,3 +71,12 @@ class CoroutineCompatibilitySupport private constructor(val enabled: Boolean) { val DISABLED = CoroutineCompatibilitySupport(false) } } + +@DefaultImplementation(DeprecationSettings.Default::class) +interface DeprecationSettings { + fun propagatedToOverrides(deprecationAnnotation: AnnotationDescriptor): Boolean + + object Default : DeprecationSettings { + override fun propagatedToOverrides(deprecationAnnotation: AnnotationDescriptor) = true + } +} diff --git a/compiler/testData/diagnostics/tests/deprecated/javaDeprecatedInheritance.kt b/compiler/testData/diagnostics/tests/deprecated/javaDeprecatedInheritance.kt index 88ad9036ccc..74d071751e8 100644 --- a/compiler/testData/diagnostics/tests/deprecated/javaDeprecatedInheritance.kt +++ b/compiler/testData/diagnostics/tests/deprecated/javaDeprecatedInheritance.kt @@ -40,7 +40,7 @@ public class C extends A { fun use(a: A, b: B, c: C) { a.f() - b.f() + b.f() c.f() A.D diff --git a/compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.kt b/compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.kt new file mode 100644 index 00000000000..38caa5c9085 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.kt @@ -0,0 +1,36 @@ +// FILE: J.java +public interface J { + @Deprecated + public void foo(); + + @Deprecated + public String bar(); + + @Deprecated + public CharSequence baz(); +} +// FILE: J2.java +public interface J2 extends J, K { +} + +// FILE: main.kt +interface K { + fun bar(): CharSequence + fun baz(): String +} + +interface A : J, K + +fun main(j: J, j2: J2, a: A) { + j.foo() + j2.foo() + a.foo() + + j.bar() + j2.bar() + a.bar() + + j.baz() + j2.baz() + a.baz() +} diff --git a/compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.txt b/compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.txt new file mode 100644 index 00000000000..523b2f6b40c --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.txt @@ -0,0 +1,38 @@ +package + +public fun main(/*0*/ j: J, /*1*/ j2: J2, /*2*/ a: A): kotlin.Unit + +public interface A : J, K { + @kotlin.Deprecated(message = "Deprecated in Java") public abstract override /*2*/ /*fake_override*/ fun bar(): kotlin.String! + public abstract override /*2*/ /*fake_override*/ fun baz(): kotlin.String + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Deprecated(message = "Deprecated in Java") public abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J { + @kotlin.Deprecated(message = "Deprecated in Java") public abstract fun bar(): kotlin.String! + @kotlin.Deprecated(message = "Deprecated in Java") public abstract fun baz(): kotlin.CharSequence! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Deprecated(message = "Deprecated in Java") public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J2 : J, K { + @kotlin.Deprecated(message = "Deprecated in Java") public abstract override /*2*/ /*fake_override*/ fun bar(): kotlin.String + public abstract override /*2*/ /*fake_override*/ fun baz(): kotlin.String + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Deprecated(message = "Deprecated in Java") public abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface K { + public abstract fun bar(): kotlin.CharSequence + public abstract fun baz(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + 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/deprecations/forMixedOverride.kt b/compiler/testData/diagnostics/tests/j+k/deprecations/forMixedOverride.kt new file mode 100644 index 00000000000..f809ed9f310 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/deprecations/forMixedOverride.kt @@ -0,0 +1,27 @@ +// FILE: J.java +public class J { + @Deprecated + public void foo() {} +} +// FILE: J2.java +public class J2 extends J implements WithDeprecation { + @Override + public void foo() {} +} + +// FILE: main.kt +interface WithDeprecation { + @Deprecated("") + fun foo() +} + +class A : J(), WithDeprecation { + override fun foo() {} +} + +fun main() { + J().foo() + + J2().foo() + A().foo() +} diff --git a/compiler/testData/diagnostics/tests/j+k/deprecations/forMixedOverride.txt b/compiler/testData/diagnostics/tests/j+k/deprecations/forMixedOverride.txt new file mode 100644 index 00000000000..b29d58912c0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/deprecations/forMixedOverride.txt @@ -0,0 +1,34 @@ +package + +public fun main(): kotlin.Unit + +public final class A : J, WithDeprecation { + public constructor A() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ fun foo(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class J { + public constructor J() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Deprecated(message = "Deprecated in Java") public open fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class J2 : J, WithDeprecation { + public constructor J2() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public open override /*2*/ fun foo(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface WithDeprecation { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Deprecated(message = "") public abstract fun foo(): 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/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt b/compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt new file mode 100644 index 00000000000..022ec34e230 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt @@ -0,0 +1,23 @@ +// FILE: J.java +public interface J { + @Deprecated + public void foo(); + +} +// FILE: J2.java +public interface J2 extends J { + @Override + public void foo(); +} + +// FILE: main.kt + +interface A : J { + override fun foo() +} + +fun main(j: J, j2: J2, a: A) { + j.foo() + j2.foo() + a.foo() +} diff --git a/compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.txt b/compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.txt new file mode 100644 index 00000000000..2bd1c37c325 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.txt @@ -0,0 +1,24 @@ +package + +public fun main(/*0*/ j: J, /*1*/ j2: J2, /*2*/ a: A): kotlin.Unit + +public interface A : J { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.Deprecated(message = "Deprecated in Java") public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J2 : J { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override public abstract override /*1*/ fun foo(): 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/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 3318bb74c98..fc6aaa1d243 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -11978,6 +11978,34 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/deprecations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Deprecations extends AbstractDiagnosticsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInDeprecations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/deprecations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("forFakeOverrides.kt") + public void testForFakeOverrides() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.kt"); + } + + @TestMetadata("forMixedOverride.kt") + public void testForMixedOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forMixedOverride.kt"); + } + + @TestMetadata("forOverrides.kt") + public void testForOverrides() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt"); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index c22d40a33de..6c2f2459178 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -11973,6 +11973,34 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing } } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/deprecations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Deprecations extends AbstractDiagnosticsUsingJavacTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInDeprecations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/deprecations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("forFakeOverrides.kt") + public void testForFakeOverrides() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forFakeOverrides.kt"); + } + + @TestMetadata("forMixedOverride.kt") + public void testForMixedOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forMixedOverride.kt"); + } + + @TestMetadata("forOverrides.kt") + public void testForOverrides() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt"); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/genericConstructor") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/deprecation/deprecation.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/deprecation/deprecation.kt index 35c7bbb1131..590a53c3b73 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/deprecation/deprecation.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/deprecation/deprecation.kt @@ -12,6 +12,7 @@ interface Deprecation { val deprecationLevel: DeprecationLevelValue val message: String? val target: DeclarationDescriptor + val propagatesToOverrides: Boolean get() = true } // values from kotlin.DeprecationLevel