Refine 'isMoreSpecific' calculation
Choose member with better visibility, it's needed for proper calculation of types intersection member scope #KT-10481 Fixed
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
|||||||
|
open class A {
|
||||||
|
open var value: Int = 4
|
||||||
|
protected set
|
||||||
|
}
|
||||||
|
|
||||||
|
class MutableA : A() {
|
||||||
|
override var value: Int = 4
|
||||||
|
public set
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(myA: A) {
|
||||||
|
if (myA is MutableA) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>myA<!>.value = 5
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ myA: A): kotlin.Unit
|
||||||
|
|
||||||
|
public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public open var value: kotlin.Int
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class MutableA : A {
|
||||||
|
public constructor MutableA()
|
||||||
|
public open override /*1*/ var value: kotlin.Int
|
||||||
|
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
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
abstract class A {
|
||||||
|
abstract protected fun foo(): String
|
||||||
|
abstract protected val bar: String
|
||||||
|
}
|
||||||
|
|
||||||
|
interface B {
|
||||||
|
fun foo(): String
|
||||||
|
val bar: String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(x: A) {
|
||||||
|
if (x is B) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.foo()
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.bar
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ x: A): kotlin.Unit
|
||||||
|
|
||||||
|
public abstract class A {
|
||||||
|
public constructor A()
|
||||||
|
protected abstract val bar: kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
protected abstract fun foo(): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B {
|
||||||
|
public abstract val bar: kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun foo(): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -16538,6 +16538,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("moreSpecificSetter.kt")
|
||||||
|
public void testMoreSpecificSetter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/intersectionScope/moreSpecificSetter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("moreSpecificVisibility.kt")
|
||||||
|
public void testMoreSpecificVisibility() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/intersectionScope/moreSpecificVisibility.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mostSpecific.kt")
|
@TestMetadata("mostSpecific.kt")
|
||||||
public void testMostSpecific() throws Exception {
|
public void testMostSpecific() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/intersectionScope/mostSpecific.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/intersectionScope/mostSpecific.kt");
|
||||||
|
|||||||
@@ -338,6 +338,8 @@ public class OverridingUtil {
|
|||||||
assert aReturnType != null : "Return type of " + a + " is null";
|
assert aReturnType != null : "Return type of " + a + " is null";
|
||||||
assert bReturnType != null : "Return type of " + b + " is null";
|
assert bReturnType != null : "Return type of " + b + " is null";
|
||||||
|
|
||||||
|
if (!isVisibilityMoreSpecific(a, b)) return false;
|
||||||
|
|
||||||
if (a instanceof SimpleFunctionDescriptor) {
|
if (a instanceof SimpleFunctionDescriptor) {
|
||||||
assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();
|
assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();
|
||||||
|
|
||||||
@@ -348,6 +350,9 @@ public class OverridingUtil {
|
|||||||
|
|
||||||
PropertyDescriptor pa = (PropertyDescriptor) a;
|
PropertyDescriptor pa = (PropertyDescriptor) a;
|
||||||
PropertyDescriptor pb = (PropertyDescriptor) b;
|
PropertyDescriptor pb = (PropertyDescriptor) b;
|
||||||
|
|
||||||
|
if (!isAccessorMoreSpecific(pa.getSetter(), pb.getSetter())) return false;
|
||||||
|
|
||||||
if (pa.isVar() && pb.isVar()) {
|
if (pa.isVar() && pb.isVar()) {
|
||||||
return DEFAULT.createTypeChecker(a.getTypeParameters(), b.getTypeParameters()).equalTypes(aReturnType, bReturnType);
|
return DEFAULT.createTypeChecker(a.getTypeParameters(), b.getTypeParameters()).equalTypes(aReturnType, bReturnType);
|
||||||
}
|
}
|
||||||
@@ -359,6 +364,19 @@ public class OverridingUtil {
|
|||||||
throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
|
throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isVisibilityMoreSpecific(
|
||||||
|
@NotNull DeclarationDescriptorWithVisibility a,
|
||||||
|
@NotNull DeclarationDescriptorWithVisibility b
|
||||||
|
) {
|
||||||
|
Integer result = Visibilities.compare(a.getVisibility(), b.getVisibility());
|
||||||
|
return result == null || result >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isAccessorMoreSpecific(@Nullable PropertyAccessorDescriptor a, @Nullable PropertyAccessorDescriptor b) {
|
||||||
|
if (a == null || b == null) return true;
|
||||||
|
return isVisibilityMoreSpecific(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isMoreSpecificThenAllOf(@NotNull CallableDescriptor candidate, @NotNull Collection<CallableDescriptor> descriptors) {
|
private static boolean isMoreSpecificThenAllOf(@NotNull CallableDescriptor candidate, @NotNull Collection<CallableDescriptor> descriptors) {
|
||||||
// NB subtyping relation in Kotlin is not transitive in presence of flexible types:
|
// NB subtyping relation in Kotlin is not transitive in presence of flexible types:
|
||||||
// String? <: String! <: String, but not String? <: String
|
// String? <: String! <: String, but not String? <: String
|
||||||
|
|||||||
Reference in New Issue
Block a user