K1: add deprecation warning for property/field pair with different types
#KT-57905 Fixed
This commit is contained in:
committed by
Space Team
parent
2100f08655
commit
41e551e321
+12
@@ -11838,6 +11838,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType2.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType2() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
||||||
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
||||||
|
|||||||
+12
@@ -11838,6 +11838,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType2.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType2() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
||||||
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
||||||
|
|||||||
+12
@@ -11838,6 +11838,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType2.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType2() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
||||||
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
||||||
|
|||||||
+12
@@ -11844,6 +11844,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType2.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType2() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
||||||
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
||||||
|
|||||||
+9
-2
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptorWithoutName
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||||
@@ -42,8 +43,13 @@ object JvmPropertyVsFieldAmbiguityCallChecker : CallChecker {
|
|||||||
val hasLateInit = basePropertyDescriptor.selfOrBaseForFakeOverride { it.isLateInit }
|
val hasLateInit = basePropertyDescriptor.selfOrBaseForFakeOverride { it.isLateInit }
|
||||||
val hasCustomGetter = basePropertyDescriptor.selfOrBaseForFakeOverride { it.getter?.isDefault == false }
|
val hasCustomGetter = basePropertyDescriptor.selfOrBaseForFakeOverride { it.getter?.isDefault == false }
|
||||||
val hasCustomSetter = basePropertyDescriptor.selfOrBaseForFakeOverride { it.setter?.isDefault == false }
|
val hasCustomSetter = basePropertyDescriptor.selfOrBaseForFakeOverride { it.setter?.isDefault == false }
|
||||||
|
|
||||||
|
val jvmDescriptorForField = resultingDescriptor.computeJvmDescriptorWithoutName()
|
||||||
|
val jvmDescriptorForProperty = alternativePropertyDescriptor.computeJvmDescriptorWithoutName()
|
||||||
|
|
||||||
if (!hasLateInit && !hasCustomGetter && !hasCustomSetter &&
|
if (!hasLateInit && !hasCustomGetter && !hasCustomSetter &&
|
||||||
basePropertyDescriptor.modality == Modality.FINAL
|
basePropertyDescriptor.modality == Modality.FINAL &&
|
||||||
|
jvmDescriptorForField == jvmDescriptorForProperty
|
||||||
) return@forEach
|
) return@forEach
|
||||||
if (fieldClassDescriptor != null && propertyClassDescriptor != null &&
|
if (fieldClassDescriptor != null && propertyClassDescriptor != null &&
|
||||||
DescriptorUtils.isSubclass(fieldClassDescriptor, propertyClassDescriptor)
|
DescriptorUtils.isSubclass(fieldClassDescriptor, propertyClassDescriptor)
|
||||||
@@ -58,7 +64,8 @@ object JvmPropertyVsFieldAmbiguityCallChecker : CallChecker {
|
|||||||
val factory = when {
|
val factory = when {
|
||||||
hasCustomGetter -> ErrorsJvm.BASE_CLASS_FIELD_SHADOWS_DERIVED_CLASS_PROPERTY
|
hasCustomGetter -> ErrorsJvm.BASE_CLASS_FIELD_SHADOWS_DERIVED_CLASS_PROPERTY
|
||||||
hasLateInit || hasCustomSetter -> ErrorsJvm.BACKING_FIELD_ACCESSED_DUE_TO_PROPERTY_FIELD_CONFLICT
|
hasLateInit || hasCustomSetter -> ErrorsJvm.BACKING_FIELD_ACCESSED_DUE_TO_PROPERTY_FIELD_CONFLICT
|
||||||
else -> ErrorsJvm.BASE_CLASS_FIELD_MAY_SHADOW_DERIVED_CLASS_PROPERTY
|
basePropertyDescriptor.modality != Modality.FINAL -> ErrorsJvm.BASE_CLASS_FIELD_MAY_SHADOW_DERIVED_CLASS_PROPERTY
|
||||||
|
else -> ErrorsJvm.BASE_CLASS_FIELD_WITH_DIFFERENT_SIGNATURE_THAN_DERIVED_CLASS_PROPERTY
|
||||||
}
|
}
|
||||||
context.trace.report(
|
context.trace.report(
|
||||||
factory.on(
|
factory.on(
|
||||||
|
|||||||
+6
@@ -250,6 +250,12 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
|||||||
"This behavior will be changed soon in favor of the property. " +
|
"This behavior will be changed soon in favor of the property. " +
|
||||||
"Please use explicit cast to {0} if you wish to preserve current behavior. " +
|
"Please use explicit cast to {0} if you wish to preserve current behavior. " +
|
||||||
"See https://youtrack.jetbrains.com/issue/KT-55017 for details", STRING, STRING);
|
"See https://youtrack.jetbrains.com/issue/KT-55017 for details", STRING, STRING);
|
||||||
|
|
||||||
|
MAP.put(BASE_CLASS_FIELD_WITH_DIFFERENT_SIGNATURE_THAN_DERIVED_CLASS_PROPERTY,
|
||||||
|
"Now field from base class {0} shadows the property with different type from derived class {1}. " +
|
||||||
|
"This behavior will be changed soon in favor of the property. " +
|
||||||
|
"Please use explicit cast to {0} if you wish to preserve current behavior. " +
|
||||||
|
"See https://youtrack.jetbrains.com/issue/KT-55017 for details", STRING, STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -214,6 +214,8 @@ public interface ErrorsJvm {
|
|||||||
|
|
||||||
DiagnosticFactory2<PsiElement, String, String> BACKING_FIELD_ACCESSED_DUE_TO_PROPERTY_FIELD_CONFLICT = DiagnosticFactory2.create(WARNING);
|
DiagnosticFactory2<PsiElement, String, String> BACKING_FIELD_ACCESSED_DUE_TO_PROPERTY_FIELD_CONFLICT = DiagnosticFactory2.create(WARNING);
|
||||||
|
|
||||||
|
DiagnosticFactory2<PsiElement, String, String> BASE_CLASS_FIELD_WITH_DIFFERENT_SIGNATURE_THAN_DERIVED_CLASS_PROPERTY = DiagnosticFactory2.create(WARNING);
|
||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
Object _initializer = new Object() {
|
Object _initializer = new Object() {
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// ISSUE: KT-57905
|
||||||
|
|
||||||
|
// FILE: Base.java
|
||||||
|
public class Base {
|
||||||
|
String value = null;
|
||||||
|
String extension = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Main.kt
|
||||||
|
class Derived: Base() {
|
||||||
|
val value: Int = 42
|
||||||
|
val something: String = <!INITIALIZER_TYPE_MISMATCH!>value<!>
|
||||||
|
|
||||||
|
val String.extension: Int get() = 42
|
||||||
|
fun String.foo() {
|
||||||
|
// K1 & K2 work in the same way here (resolve to an extension property)
|
||||||
|
val something: String = <!INITIALIZER_TYPE_MISMATCH!>extension<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// ISSUE: KT-57905
|
||||||
|
|
||||||
|
// FILE: Base.java
|
||||||
|
public class Base {
|
||||||
|
String value = null;
|
||||||
|
String extension = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Main.kt
|
||||||
|
class Derived: Base() {
|
||||||
|
val value: Int = 42
|
||||||
|
val something: String = <!BASE_CLASS_FIELD_WITH_DIFFERENT_SIGNATURE_THAN_DERIVED_CLASS_PROPERTY!>value<!>
|
||||||
|
|
||||||
|
val String.extension: Int get() = 42
|
||||||
|
fun String.foo() {
|
||||||
|
// K1 & K2 work in the same way here (resolve to an extension property)
|
||||||
|
val something: String = <!TYPE_MISMATCH!>extension<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// ISSUE: KT-57905
|
||||||
|
|
||||||
|
// FILE: BasicSliderUI.java
|
||||||
|
public class BasicSliderUI {
|
||||||
|
Rectangle thumbRect = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Main.kt
|
||||||
|
|
||||||
|
class Rectangle
|
||||||
|
|
||||||
|
class TimelineSliderUI: BasicSliderUI() {
|
||||||
|
// K1: ok
|
||||||
|
// K2: INITIALIZER_TYPE_MISMATCH (actual kotlin/Function0<kotlin/Function0<Rectangle>>, expected kotlin/Function0<Rectangle>)
|
||||||
|
val thumbRect: () -> Rectangle = <!INITIALIZER_TYPE_MISMATCH!>{ thumbRect }<!>
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// ISSUE: KT-57905
|
||||||
|
|
||||||
|
// FILE: BasicSliderUI.java
|
||||||
|
public class BasicSliderUI {
|
||||||
|
Rectangle thumbRect = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Main.kt
|
||||||
|
|
||||||
|
class Rectangle
|
||||||
|
|
||||||
|
class TimelineSliderUI: BasicSliderUI() {
|
||||||
|
// K1: ok
|
||||||
|
// K2: INITIALIZER_TYPE_MISMATCH (actual kotlin/Function0<kotlin/Function0<Rectangle>>, expected kotlin/Function0<Rectangle>)
|
||||||
|
val thumbRect: () -> Rectangle = { <!BASE_CLASS_FIELD_WITH_DIFFERENT_SIGNATURE_THAN_DERIVED_CLASS_PROPERTY!>thumbRect<!> }
|
||||||
|
}
|
||||||
Generated
+12
@@ -11844,6 +11844,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
runTest("compiler/testData/diagnostics/tests/fieldRename/derivedClassPropertyShadowsBaseClassField13.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("javaFieldKotlinPropertyDifferentType2.kt")
|
||||||
|
public void testJavaFieldKotlinPropertyDifferentType2() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/fieldRename/javaFieldKotlinPropertyDifferentType2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
@TestMetadata("javaFieldKotlinPropertyJavaFieldInPackagePrivate.kt")
|
||||||
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
public void testJavaFieldKotlinPropertyJavaFieldInPackagePrivate() throws Exception {
|
||||||
|
|||||||
@@ -44,6 +44,22 @@ fun FunctionDescriptor.computeJvmDescriptor(withReturnType: Boolean = true, with
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PropertyDescriptor.computeJvmDescriptorWithoutName() = buildString {
|
||||||
|
append("(")
|
||||||
|
|
||||||
|
extensionReceiverParameter?.let {
|
||||||
|
appendErasedType(it.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
append(")")
|
||||||
|
|
||||||
|
if (hasVoidReturnType(this@computeJvmDescriptorWithoutName)) {
|
||||||
|
append("V")
|
||||||
|
} else {
|
||||||
|
appendErasedType(returnType!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Boxing is only necessary for 'remove(E): Boolean' of a MutableCollection<Int> implementation
|
// Boxing is only necessary for 'remove(E): Boolean' of a MutableCollection<Int> implementation
|
||||||
// Otherwise this method might clash with 'remove(I): E' defined in the java.util.List JDK interface (mapped to kotlin 'removeAt')
|
// Otherwise this method might clash with 'remove(I): E' defined in the java.util.List JDK interface (mapped to kotlin 'removeAt')
|
||||||
fun forceSingleValueParameterBoxing(f: CallableDescriptor): Boolean {
|
fun forceSingleValueParameterBoxing(f: CallableDescriptor): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user