K1: Report deprecation on synthetic properties for NOT_CONSIDERED JDK members
Currently, for other synthetic properties, deprecation from the original method is already being propagated to the relevant new synthetic property accessor. But what we need is also reporting warnings on synthetic properties accessors call-sites if original methods are considered deprecated as a result of deprecation propagation. KT-60659 Fixed ^KT-60769 Fixed
This commit is contained in:
committed by
Space Team
parent
eae97e4f76
commit
0694ee50a3
+12
@@ -20745,6 +20745,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/deprecations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("doNotMarkWriteIfGetterDeprecated.kt")
|
||||
public void testDoNotMarkWriteIfGetterDeprecated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/doNotMarkWriteIfGetterDeprecated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forFakeOverrides.kt")
|
||||
public void testForFakeOverrides() throws Exception {
|
||||
@@ -20762,6 +20768,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
public void testForOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forSyntheticPropertyOverrides.kt")
|
||||
public void testForSyntheticPropertyOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forSyntheticPropertyOverrides.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+12
@@ -20745,6 +20745,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/deprecations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("doNotMarkWriteIfGetterDeprecated.kt")
|
||||
public void testDoNotMarkWriteIfGetterDeprecated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/doNotMarkWriteIfGetterDeprecated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forFakeOverrides.kt")
|
||||
public void testForFakeOverrides() throws Exception {
|
||||
@@ -20762,6 +20768,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
public void testForOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forSyntheticPropertyOverrides.kt")
|
||||
public void testForSyntheticPropertyOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forSyntheticPropertyOverrides.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+12
@@ -20745,6 +20745,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/deprecations"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("doNotMarkWriteIfGetterDeprecated.kt")
|
||||
public void testDoNotMarkWriteIfGetterDeprecated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/doNotMarkWriteIfGetterDeprecated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forFakeOverrides.kt")
|
||||
public void testForFakeOverrides() throws Exception {
|
||||
@@ -20762,6 +20768,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
public void testForOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forSyntheticPropertyOverrides.kt")
|
||||
public void testForSyntheticPropertyOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forSyntheticPropertyOverrides.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+12
@@ -20751,6 +20751,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/deprecations"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("doNotMarkWriteIfGetterDeprecated.kt")
|
||||
public void testDoNotMarkWriteIfGetterDeprecated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/doNotMarkWriteIfGetterDeprecated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forFakeOverrides.kt")
|
||||
public void testForFakeOverrides() throws Exception {
|
||||
@@ -20768,6 +20774,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
public void testForOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forSyntheticPropertyOverrides.kt")
|
||||
public void testForSyntheticPropertyOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forSyntheticPropertyOverrides.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+42
-19
@@ -39,27 +39,50 @@ class DeprecationResolver(
|
||||
) {
|
||||
private val deprecations: MemoizedFunctionToNotNull<DeclarationDescriptor, DeprecationInfo> =
|
||||
storageManager.createMemoizedFunction { descriptor ->
|
||||
val deprecations = descriptor.getOwnDeprecations()
|
||||
when {
|
||||
deprecations.isNotEmpty() -> DeprecationInfo(deprecations, hasInheritedDeprecations = false)
|
||||
descriptor is CallableMemberDescriptor -> {
|
||||
val inheritedDeprecations = listOfNotNull(deprecationByOverridden(descriptor))
|
||||
when (inheritedDeprecations.isNotEmpty()) {
|
||||
true -> when (languageVersionSettings.supportsFeature(LanguageFeature.StopPropagatingDeprecationThroughOverrides)) {
|
||||
true -> DeprecationInfo(
|
||||
inheritedDeprecations.filter { it.forcePropagationToOverrides },
|
||||
hasInheritedDeprecations = true,
|
||||
inheritedDeprecations
|
||||
)
|
||||
false -> DeprecationInfo(inheritedDeprecations, hasInheritedDeprecations = true)
|
||||
}
|
||||
false -> DeprecationInfo.EMPTY
|
||||
}
|
||||
}
|
||||
else -> DeprecationInfo.EMPTY
|
||||
}
|
||||
computeDeprecation(descriptor)
|
||||
}
|
||||
|
||||
private fun computeDeprecation(descriptor: DeclarationDescriptor): DeprecationInfo {
|
||||
val deprecations = descriptor.getOwnDeprecations()
|
||||
return when {
|
||||
deprecations.isNotEmpty() -> DeprecationInfo(deprecations, hasInheritedDeprecations = false)
|
||||
descriptor is PropertyAccessorDescriptor && descriptor.correspondingProperty is SyntheticPropertyDescriptor -> {
|
||||
val syntheticProperty = descriptor.correspondingProperty as SyntheticPropertyDescriptor
|
||||
val originalMethod =
|
||||
if (descriptor is PropertyGetterDescriptor) syntheticProperty.getMethod else syntheticProperty.setMethod
|
||||
|
||||
@Suppress("FoldInitializerAndIfToElvis") // Wait until KTIJ-26450 is fixed
|
||||
if (originalMethod == null) return DeprecationInfo.EMPTY
|
||||
val originalMethodDeprecationInfo = deprecations(originalMethod)
|
||||
|
||||
// Limiting these new (they didn't exist before 1.9.10) deprecations only to WARNING and forcePropagationToOverrides
|
||||
// (i.e., for overrides of NOT_CONSIDERED JDK members)
|
||||
// is deliberate once we would like to reduce the scope of affected usages because otherwise
|
||||
// it might be a big unexpected breaking change for users who are enabled -Werror flag.
|
||||
val filteredDeprecations =
|
||||
originalMethodDeprecationInfo.deprecations.filter {
|
||||
it.deprecationLevel == DeprecationLevelValue.WARNING && it.forcePropagationToOverrides
|
||||
}
|
||||
return originalMethodDeprecationInfo.copy(deprecations = filteredDeprecations)
|
||||
}
|
||||
descriptor is CallableMemberDescriptor -> {
|
||||
val inheritedDeprecations = listOfNotNull(deprecationByOverridden(descriptor))
|
||||
when (inheritedDeprecations.isNotEmpty()) {
|
||||
true -> when (languageVersionSettings.supportsFeature(LanguageFeature.StopPropagatingDeprecationThroughOverrides)) {
|
||||
true -> DeprecationInfo(
|
||||
inheritedDeprecations.filter { it.forcePropagationToOverrides },
|
||||
hasInheritedDeprecations = true,
|
||||
inheritedDeprecations
|
||||
)
|
||||
false -> DeprecationInfo(inheritedDeprecations, hasInheritedDeprecations = true)
|
||||
}
|
||||
false -> DeprecationInfo.EMPTY
|
||||
}
|
||||
}
|
||||
else -> DeprecationInfo.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
private data class DeprecationInfo(
|
||||
val deprecations: List<DescriptorBasedDeprecationInfo>,
|
||||
val hasInheritedDeprecations: Boolean,
|
||||
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
// LANGUAGE: -StopPropagatingDeprecationThroughOverrides
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass {
|
||||
@Deprecated
|
||||
public String getFoo() { return ""; }
|
||||
public void setFoo(String x) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
open class KotlinClass : JavaClass() {
|
||||
@Deprecated("")
|
||||
override fun getFoo(): String {
|
||||
return super.<!DEPRECATION!>getFoo<!>()
|
||||
}
|
||||
|
||||
override fun setFoo(x: String?) {
|
||||
super.setFoo(x)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinSubClass : KotlinClass() {
|
||||
override fun <!OVERRIDE_DEPRECATION!>getFoo<!>(): String {
|
||||
return super.<!DEPRECATION!>getFoo<!>()
|
||||
}
|
||||
|
||||
override fun setFoo(x: String?) {
|
||||
super.setFoo(x)
|
||||
}
|
||||
}
|
||||
|
||||
fun main(j: JavaClass, k: KotlinClass, ks: KotlinSubClass) {
|
||||
j.<!DEPRECATION!>getFoo<!>()
|
||||
j.setFoo("")
|
||||
|
||||
j.<!DEPRECATION!>foo<!>
|
||||
j.foo = ""
|
||||
|
||||
k.<!DEPRECATION!>getFoo<!>()
|
||||
k.setFoo("")
|
||||
|
||||
k.<!DEPRECATION!>foo<!>
|
||||
k.foo = ""
|
||||
|
||||
ks.getFoo()
|
||||
ks.setFoo("")
|
||||
|
||||
ks.foo
|
||||
ks.foo = ""
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// LANGUAGE: -StopPropagatingDeprecationThroughOverrides
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass {
|
||||
@Deprecated
|
||||
public String getFoo() { return ""; }
|
||||
public void setFoo(String x) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
open class KotlinClass : JavaClass() {
|
||||
@Deprecated("")
|
||||
override fun getFoo(): String {
|
||||
return super.<!DEPRECATION!>getFoo<!>()
|
||||
}
|
||||
|
||||
override fun setFoo(x: String?) {
|
||||
super.setFoo(x)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinSubClass : KotlinClass() {
|
||||
override fun <!OVERRIDE_DEPRECATION!>getFoo<!>(): String {
|
||||
return super.<!DEPRECATION!>getFoo<!>()
|
||||
}
|
||||
|
||||
override fun setFoo(x: String?) {
|
||||
super.setFoo(x)
|
||||
}
|
||||
}
|
||||
|
||||
fun main(j: JavaClass, k: KotlinClass, ks: KotlinSubClass) {
|
||||
j.<!DEPRECATION!>getFoo<!>()
|
||||
j.setFoo("")
|
||||
|
||||
j.<!DEPRECATION!>foo<!>
|
||||
j.foo = ""
|
||||
|
||||
k.<!DEPRECATION!>getFoo<!>()
|
||||
k.setFoo("")
|
||||
|
||||
k.<!DEPRECATION!>foo<!>
|
||||
k.foo = ""
|
||||
|
||||
ks.<!DEPRECATION!>getFoo<!>()
|
||||
ks.setFoo("")
|
||||
|
||||
ks.foo
|
||||
ks.foo = ""
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// FIR_IDENTICAL
|
||||
// LANGUAGE: -StopPropagatingDeprecationThroughOverrides
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass {
|
||||
public String getFoo() { return ""; }
|
||||
public String getBar() { return ""; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
open class KotlinClass : JavaClass() {
|
||||
@Deprecated("sdas")
|
||||
override fun getFoo(): String {
|
||||
return super.getFoo()
|
||||
}
|
||||
|
||||
@Deprecated("dasd", level = DeprecationLevel.ERROR)
|
||||
override fun getBar(): String {
|
||||
return super.getBar()
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinSubClass : KotlinClass() {
|
||||
override fun <!OVERRIDE_DEPRECATION!>getFoo<!>(): String {
|
||||
return super.<!DEPRECATION!>getFoo<!>()
|
||||
}
|
||||
|
||||
override fun <!OVERRIDE_DEPRECATION!>getBar<!>(): String {
|
||||
return super.<!DEPRECATION_ERROR!>getBar<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun main(kotlinClass: KotlinClass, kotlinSubClass: KotlinSubClass) {
|
||||
kotlinClass.<!DEPRECATION!>foo<!>
|
||||
kotlinClass.<!DEPRECATION_ERROR!>bar<!>
|
||||
|
||||
kotlinSubClass.foo
|
||||
kotlinSubClass.bar
|
||||
}
|
||||
+4
-4
@@ -4,10 +4,10 @@ fun foo(ll: java.util.LinkedList<String>, al: ArrayList<String>, ad: ArrayDeque<
|
||||
ll.addFirst("")
|
||||
ll.addLast("")
|
||||
ll.<!DEPRECATION!>getFirst<!>()
|
||||
ll.first // synthetic property for getFirst()
|
||||
ll.<!DEPRECATION!>first<!> // synthetic property for getFirst()
|
||||
ll.first() // stdlib extension on List
|
||||
ll.<!DEPRECATION!>getLast<!>()
|
||||
ll.last
|
||||
ll.<!DEPRECATION!>last<!>
|
||||
ll.last()
|
||||
ll.<!DEBUG_INFO_CALL("fqName: java.util.LinkedList.removeFirst; typeCall: function")!>removeFirst()<!>
|
||||
ll.<!DEBUG_INFO_CALL("fqName: java.util.LinkedList.removeLast; typeCall: function")!>removeLast()<!>
|
||||
@@ -16,10 +16,10 @@ fun foo(ll: java.util.LinkedList<String>, al: ArrayList<String>, ad: ArrayDeque<
|
||||
al.addFirst("")
|
||||
al.addLast("")
|
||||
al.<!DEPRECATION!>getFirst<!>()
|
||||
al.first
|
||||
al.<!DEPRECATION!>first<!>
|
||||
al.first()
|
||||
al.<!DEPRECATION!>getLast<!>()
|
||||
al.last
|
||||
al.<!DEPRECATION!>last<!>
|
||||
al.last()
|
||||
al.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeFirst; typeCall: function")!>removeFirst()<!>
|
||||
al.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeLast; typeCall: function")!>removeLast()<!>
|
||||
|
||||
@@ -35,10 +35,10 @@ fun foo(x: MutableList<String>, y: ArrayList<String>, z: A<String>) {
|
||||
y.addFirst("")
|
||||
y.addLast("")
|
||||
y.<!DEPRECATION!>getFirst<!>()
|
||||
y.first
|
||||
y.<!DEPRECATION!>first<!>
|
||||
y.first()
|
||||
y.<!DEPRECATION!>getLast<!>()
|
||||
y.last
|
||||
y.<!DEPRECATION!>last<!>
|
||||
y.last()
|
||||
y.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeFirst; typeCall: function")!>removeFirst()<!>
|
||||
y.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeLast; typeCall: function")!>removeLast()<!>
|
||||
@@ -47,10 +47,10 @@ fun foo(x: MutableList<String>, y: ArrayList<String>, z: A<String>) {
|
||||
z.addFirst("")
|
||||
z.addLast("")
|
||||
z.<!DEPRECATION!>getFirst<!>()
|
||||
z.first
|
||||
z.<!DEPRECATION!>first<!>
|
||||
z.first()
|
||||
z.<!DEPRECATION!>getLast<!>()
|
||||
z.last
|
||||
z.<!DEPRECATION!>last<!>
|
||||
z.last()
|
||||
z.<!DEBUG_INFO_CALL("fqName: A.removeFirst; typeCall: function")!>removeFirst()<!>
|
||||
z.<!DEBUG_INFO_CALL("fqName: A.removeLast; typeCall: function")!>removeLast()<!>
|
||||
|
||||
Generated
+12
@@ -20751,6 +20751,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/deprecations"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("doNotMarkWriteIfGetterDeprecated.kt")
|
||||
public void testDoNotMarkWriteIfGetterDeprecated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/doNotMarkWriteIfGetterDeprecated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forFakeOverrides.kt")
|
||||
public void testForFakeOverrides() throws Exception {
|
||||
@@ -20768,6 +20774,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
public void testForOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forSyntheticPropertyOverrides.kt")
|
||||
public void testForSyntheticPropertyOverrides() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/deprecations/forSyntheticPropertyOverrides.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
Reference in New Issue
Block a user