Ignore type parameters in value arguments while comparing SAM adapters
#KT-8388 Fixed
This commit is contained in:
+13
-5
@@ -50,19 +50,27 @@ public class SamAdapterOverridabilityCondition implements ExternalOverridability
|
||||
|
||||
for (ValueParameterDescriptor param1 : parameters1) {
|
||||
ValueParameterDescriptor param2 = parameters2.get(param1.getIndex());
|
||||
if (!equalClasses(param2.getType(), param1.getType())) {
|
||||
if (differentClasses(param2.getType(), param1.getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean equalClasses(@NotNull JetType type1, @NotNull JetType type2) {
|
||||
private static boolean differentClasses(@NotNull JetType type1, @NotNull JetType type2) {
|
||||
DeclarationDescriptor declarationDescriptor1 = type1.getConstructor().getDeclarationDescriptor();
|
||||
if (declarationDescriptor1 == null) return false; // No class, classes are not equal
|
||||
if (declarationDescriptor1 == null) return true; // No class, classes are not equal
|
||||
DeclarationDescriptor declarationDescriptor2 = type2.getConstructor().getDeclarationDescriptor();
|
||||
if (declarationDescriptor2 == null) return false; // Class of type1 is not null
|
||||
return declarationDescriptor1.getOriginal().equals(declarationDescriptor2.getOriginal());
|
||||
if (declarationDescriptor2 == null) return true; // Class of type1 is not null
|
||||
|
||||
if (declarationDescriptor1 instanceof TypeParameterDescriptor && declarationDescriptor2 instanceof TypeParameterDescriptor) {
|
||||
// if type of value parameter is some generic parameter then their equality was checked by OverridingUtil before calling ExternalOverridabilityCondition
|
||||
// Note that it's true unless we generate sam adapter for type parameter with SAM interface as upper bound:
|
||||
// <K extends Runnable >void foo(K runnable) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
return !declarationDescriptor1.getOriginal().equals(declarationDescriptor2.getOriginal());
|
||||
}
|
||||
|
||||
// if function is or overrides declaration, returns null; otherwise, return original of sam adapter with substituted type parameters
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// FILE: MyFunc.java
|
||||
public interface MyFunc<K, V> {
|
||||
V apply(K String);
|
||||
}
|
||||
|
||||
// FILE: ConcMap.java
|
||||
public interface ConcMap<K, V> {
|
||||
V computeIfAbsent(K key, MyFunc<? super K,? extends V> mappingFunction);
|
||||
}
|
||||
|
||||
// FILE: ConcHashMap.java
|
||||
public class ConcHashMap<K, V> implements ConcMap<K, V> {
|
||||
@Override
|
||||
V computeIfAbsent(K key, MyFunc<? super K,? extends V> mappingFunction) { }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
public fun concurrentMap() {
|
||||
val map = ConcHashMap<String, String>()
|
||||
map.computeIfAbsent("") { "" } // here
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package
|
||||
|
||||
public /*synthesized*/ fun </*0*/ K, /*1*/ V> ConcMap(/*0*/ function: (K!, MyFunc<in K!, out V!>!) -> V!): ConcMap<K, V>
|
||||
public /*synthesized*/ fun </*0*/ K, /*1*/ V> MyFunc(/*0*/ function: (K!) -> V!): MyFunc<K, V>
|
||||
public fun concurrentMap(): kotlin.Unit
|
||||
|
||||
public open class ConcHashMap</*0*/ K, /*1*/ V> : ConcMap<K!, V!> {
|
||||
public constructor ConcHashMap</*0*/ K, /*1*/ V>()
|
||||
java.lang.Override() public/*package*/ final override /*1*/ /*synthesized*/ fun computeIfAbsent(/*0*/ key: K!, /*1*/ mappingFunction: ((K!) -> V!)!): V!
|
||||
java.lang.Override() public/*package*/ open override /*1*/ fun computeIfAbsent(/*0*/ key: K!, /*1*/ mappingFunction: MyFunc<in K!, out V!>!): V!
|
||||
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 interface ConcMap</*0*/ K, /*1*/ V> {
|
||||
public final /*synthesized*/ fun computeIfAbsent(/*0*/ key: K!, /*1*/ mappingFunction: ((K!) -> V!)!): V!
|
||||
public abstract fun computeIfAbsent(/*0*/ key: K!, /*1*/ mappingFunction: MyFunc<in K!, out V!>!): V!
|
||||
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 interface MyFunc</*0*/ K, /*1*/ V> {
|
||||
public abstract fun apply(/*0*/ String: K!): V!
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// FILE: MyFunc.java
|
||||
|
||||
public interface MyFunc {
|
||||
String apply(String x);
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
public interface A<K> {
|
||||
K foo(K key, MyFunc f);
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
public class B<E> implements A<E> {
|
||||
@Override
|
||||
public E foo(E key, MyFunc f) {return null;}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main() {
|
||||
B<String>().foo("") { "" }
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package
|
||||
|
||||
public /*synthesized*/ fun </*0*/ K> A(/*0*/ function: (K!, MyFunc!) -> K!): A<K>
|
||||
public /*synthesized*/ fun MyFunc(/*0*/ function: (kotlin.String!) -> kotlin.String!): MyFunc
|
||||
internal fun main(): kotlin.Unit
|
||||
|
||||
public interface A</*0*/ K> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final /*synthesized*/ fun foo(/*0*/ key: K!, /*1*/ f: ((kotlin.String!) -> kotlin.String!)!): K!
|
||||
public abstract fun foo(/*0*/ key: K!, /*1*/ f: MyFunc!): K!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class B</*0*/ E> : A<E!> {
|
||||
public constructor B</*0*/ E>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
java.lang.Override() public final override /*1*/ /*synthesized*/ fun foo(/*0*/ key: E!, /*1*/ f: ((kotlin.String!) -> kotlin.String!)!): E!
|
||||
java.lang.Override() public open override /*1*/ fun foo(/*0*/ key: E!, /*1*/ f: MyFunc!): E!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface MyFunc {
|
||||
public abstract fun apply(/*0*/ x: kotlin.String!): 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
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package test;
|
||||
|
||||
class NoSamForTypeParameter<K extends Runnable> {
|
||||
void foo(K runnable1, Runnable runnable2) {}
|
||||
}
|
||||
|
||||
class NoSamForTypeParameterDerived1 extends NoSamForTypeParameter<Runnable> {
|
||||
@Override
|
||||
void foo(Runnable runnable1, Runnable runnable2) {}
|
||||
}
|
||||
|
||||
class NoSamForTypeParameterDerived2<E extends Runnable> extends NoSamForTypeParameter<E> {
|
||||
void foo(E runnable1, Runnable runnable2) {}
|
||||
}
|
||||
|
||||
class NoSamForTypeParameterDerived3 extends NoSamForTypeParameterDerived1 {
|
||||
@Override
|
||||
void foo(Runnable runnable1, Runnable runnable2) {}
|
||||
}
|
||||
|
||||
class NoSamForTypeParameterDerived4 extends NoSamForTypeParameterDerived2<Runnable> {
|
||||
@Override
|
||||
void foo(Runnable runnable1, Runnable runnable2) {}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package test
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameter</*0*/ K : java.lang.Runnable!> {
|
||||
public/*package*/ constructor NoSamForTypeParameter</*0*/ K : java.lang.Runnable!>()
|
||||
public/*package*/ final /*synthesized*/ fun foo(/*0*/ p0: K!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open fun foo(/*0*/ p0: K!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived1 : test.NoSamForTypeParameter<java.lang.Runnable!> {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived1()
|
||||
public/*package*/ final /*synthesized*/ fun foo(/*0*/ p0: (() -> kotlin.Unit)!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ final override /*1*/ /*fake_override*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived2</*0*/ E : java.lang.Runnable!> : test.NoSamForTypeParameter<E!> {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived2</*0*/ E : java.lang.Runnable!>()
|
||||
public/*package*/ final override /*1*/ /*synthesized*/ fun foo(/*0*/ p0: E!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun foo(/*0*/ p0: E!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived3 : test.NoSamForTypeParameterDerived1 {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived3()
|
||||
public/*package*/ final override /*1*/ /*synthesized*/ fun foo(/*0*/ p0: (() -> kotlin.Unit)!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ final override /*1*/ /*fake_override*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived4 : test.NoSamForTypeParameterDerived2<java.lang.Runnable!> {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived4()
|
||||
public/*package*/ final /*synthesized*/ fun foo(/*0*/ p0: (() -> kotlin.Unit)!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ final override /*1*/ /*fake_override*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package test;
|
||||
|
||||
class NoSamForTypeParameter {
|
||||
<K extends Runnable> void foo(K runnable1, Runnable runnable2) {}
|
||||
}
|
||||
|
||||
class NoSamForTypeParameterDerived1 extends NoSamForTypeParameter {
|
||||
@Override
|
||||
void foo(Runnable runnable1, Runnable runnable2) {}
|
||||
}
|
||||
|
||||
class NoSamForTypeParameterDerived2 extends NoSamForTypeParameter {
|
||||
@Override
|
||||
<K extends Runnable> void foo(K runnable1, Runnable runnable2) {}
|
||||
}
|
||||
|
||||
class NoSamForTypeParameterDerived3 extends NoSamForTypeParameterDerived1 {
|
||||
@Override
|
||||
void foo(Runnable runnable1, Runnable runnable2) {}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package test
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameter {
|
||||
public/*package*/ constructor NoSamForTypeParameter()
|
||||
public/*package*/ final /*synthesized*/ fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived1 : test.NoSamForTypeParameter {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived1()
|
||||
public/*package*/ final /*synthesized*/ fun foo(/*0*/ p0: (() -> kotlin.Unit)!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ final override /*1*/ /*fake_override*/ fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived2 : test.NoSamForTypeParameter {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived2()
|
||||
public/*package*/ final override /*1*/ /*synthesized*/ fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived3 : test.NoSamForTypeParameterDerived1 {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived3()
|
||||
public/*package*/ final override /*1*/ /*synthesized*/ fun foo(/*0*/ p0: (() -> kotlin.Unit)!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ final override /*1*/ /*fake_override*/ fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: (() -> kotlin.Unit)!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
@@ -7956,6 +7956,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("computeIfAbsentConcurrent.kt")
|
||||
public void testComputeIfAbsentConcurrent() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/computeIfAbsentConcurrent.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GenericsInSupertypes.kt")
|
||||
public void testGenericsInSupertypes() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/GenericsInSupertypes.kt");
|
||||
@@ -8100,6 +8106,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("overrideWithSamAndTypeParameter.kt")
|
||||
public void testOverrideWithSamAndTypeParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/overrideWithSamAndTypeParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("packagePrivateClassStaticMember.kt")
|
||||
public void testPackagePrivateClassStaticMember() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/packagePrivateClassStaticMember.kt");
|
||||
|
||||
@@ -1580,6 +1580,18 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NoSamForClassTypeParameter.java")
|
||||
public void testNoSamForClassTypeParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/sam/adapters/NoSamForClassTypeParameter.java");
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NoSamForMethodTypeParameter.java")
|
||||
public void testNoSamForMethodTypeParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/sam/adapters/NoSamForMethodTypeParameter.java");
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NonTrivialFunctionType.java")
|
||||
public void testNonTrivialFunctionType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/sam/adapters/NonTrivialFunctionType.java");
|
||||
|
||||
Reference in New Issue
Block a user