提交 df1595e4 编写于 作者: M Mikhail Zarechenskiy

Fix SAM conversions for derived classes

 #KT-39535 Fixed
 #KT-37149 Fixed
上级 ee6d432c
......@@ -13661,6 +13661,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
}
@TestMetadata("conversionForDerivedGenericClass.kt")
public void testConversionForDerivedGenericClass() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionForDerivedGenericClass.kt");
}
@TestMetadata("conversionsWithNestedGenerics.kt")
public void testConversionsWithNestedGenerics() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionsWithNestedGenerics.kt");
}
@TestMetadata("enhancedSamConstructor.kt")
public void testEnhancedSamConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
......@@ -64,19 +64,22 @@ object SamTypeConversions : ParameterTypeConversion {
val callComponents = candidate.callComponents
val originalExpectedType = argument.getExpectedType(parameter.original, callComponents.languageVersionSettings)
val convertedTypeByOriginal =
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
originalExpectedType,
callComponents.samConversionOracle
) ?: return null
val convertedTypeByCandidate =
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
expectedParameterType,
callComponents.samConversionOracle
)
) ?: return null
assert(expectedParameterType.constructor == originalExpectedType.constructor && convertedTypeByCandidate != null) {
val convertedTypeByOriginal =
if (expectedParameterType.constructor == originalExpectedType.constructor)
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
originalExpectedType,
callComponents.samConversionOracle
)
else
convertedTypeByCandidate
assert(convertedTypeByCandidate.constructor == convertedTypeByOriginal?.constructor) {
"If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" +
"originalExpectType: $originalExpectedType, candidateExpectType: $expectedParameterType\n" +
"functionTypeByOriginal: $convertedTypeByOriginal, functionTypeByCandidate: $convertedTypeByCandidate"
......@@ -84,7 +87,7 @@ object SamTypeConversions : ParameterTypeConversion {
candidate.resolvedCall.registerArgumentWithSamConversion(
argument,
SamConversionDescription(convertedTypeByOriginal, convertedTypeByCandidate!!)
SamConversionDescription(convertedTypeByOriginal!!, convertedTypeByCandidate)
)
if (needCompatibilityResolveForSAM(candidate, expectedParameterType)) {
......
// FILE: A.java
public interface A<T> {
void f(T arg);
}
// FILE: B.java
public interface B extends A<Runnable> {}
// FILE: C.java
public class C<K> {
public void f(K k) {}
public static <R> void g(R r) {}
}
// FILE: test.kt
fun test(a: A<Runnable>, b: B, c: C<Runnable>) {
a.f { }
b.f { }
c.f { }
C<Runnable>().f { }
C.g<Runnable> { }
}
\ No newline at end of file
// FILE: A.java
public interface A<T> {
void f(T arg);
}
// FILE: B.java
public interface B extends A<Runnable> {}
// FILE: C.java
public class C<K> {
public void f(K k) {}
public static <R> void g(R r) {}
}
// FILE: test.kt
fun test(a: A<Runnable>, b: B, c: C<Runnable>) {
a.f { }
b.f { }
c.f { }
C<Runnable>().f { }
C.g<Runnable> <!TYPE_MISMATCH, TYPE_MISMATCH!>{ }<!>
}
\ No newline at end of file
package
public fun test(/*0*/ a: A<java.lang.Runnable>, /*1*/ b: B, /*2*/ c: C<java.lang.Runnable>): kotlin.Unit
public interface A</*0*/ T : kotlin.Any!> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun f(/*0*/ arg: T!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B : A<java.lang.Runnable!> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun f(/*0*/ arg: java.lang.Runnable!): 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 C</*0*/ K : kotlin.Any!> {
public constructor C</*0*/ K : kotlin.Any!>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open fun f(/*0*/ k: K!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public open fun </*0*/ R : kotlin.Any!> g(/*0*/ r: R!): kotlin.Unit
}
// FIR_IDENTICAL
// FILE: Listener.java
public interface Listener<T> {
void on(T self);
}
// FILE: Base.java
public class Base<S, T extends Listener<S>> {
public void addListener(T listener) {}
}
// FILE: Derived.java
public class Derived extends Base<Derived, Listener<Derived>> {}
// FILE: test.kt
fun test(w: Derived) {
w.addListener { _ -> call() }
}
fun call() {}
\ No newline at end of file
package
public fun call(): kotlin.Unit
public fun test(/*0*/ w: Derived): kotlin.Unit
public open class Base</*0*/ S : kotlin.Any!, /*1*/ T : Listener<S!>!> {
public constructor Base</*0*/ S : kotlin.Any!, /*1*/ T : Listener<S!>!>()
public open fun addListener(/*0*/ listener: T!): kotlin.Unit
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 open class Derived : Base<Derived!, Listener<Derived!>!> {
public constructor Derived()
public open override /*1*/ /*fake_override*/ fun addListener(/*0*/ listener: Listener<Derived!>!): kotlin.Unit
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 Listener</*0*/ T : kotlin.Any!> {
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 abstract fun on(/*0*/ self: T!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
// !LANGUAGE: +NewInference
// FILE: J.java
public interface J<T> {
public void foo(T r1, T r2);
}
// FILE: Runnable.java
public interface Runnable {
void run();
}
// FILE: 1.kt
fun test(j: J<Runnable>, r: Runnable) {
j.foo(r, r)
j.foo(r, {})
j.foo({}, r)
j.foo({}, {})
}
\ No newline at end of file
// FIR_IDENTICAL
// !LANGUAGE: +NewInference
// FILE: J.java
public interface J<T> {
......@@ -12,7 +13,7 @@ public interface Runnable {
// FILE: 1.kt
fun test(j: J<Runnable>, r: Runnable) {
j.foo(r, r)
j.foo(r, <!TYPE_MISMATCH!>{}<!>)
j.foo(<!TYPE_MISMATCH!>{}<!>, r)
j.foo(<!TYPE_MISMATCH!>{}<!>, <!TYPE_MISMATCH!>{}<!>)
j.foo(r, {})
j.foo({}, r)
j.foo({}, {})
}
\ No newline at end of file
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions
// FILE: Runnable.java
public interface Runnable {
void run();
}
// FILE: 1.kt
interface K<T> {
fun foo(t1: T, t2: T)
}
fun test(k: K<Runnable>, r: Runnable) {
k.foo(r, r)
k.foo(r, {})
k.foo({}, r)
k.foo({}, {})
}
\ No newline at end of file
// FIR_IDENTICAL
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions
// FILE: Runnable.java
public interface Runnable {
......@@ -11,7 +12,7 @@ interface K<T> {
fun test(k: K<Runnable>, r: Runnable) {
k.foo(r, r)
k.foo(r, <!TYPE_MISMATCH!>{}<!>)
k.foo(<!TYPE_MISMATCH!>{}<!>, r)
k.foo(<!TYPE_MISMATCH!>{}<!>, <!TYPE_MISMATCH!>{}<!>)
k.foo(r, {})
k.foo({}, r)
k.foo({}, {})
}
\ No newline at end of file
......@@ -13668,6 +13668,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
}
@TestMetadata("conversionForDerivedGenericClass.kt")
public void testConversionForDerivedGenericClass() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionForDerivedGenericClass.kt");
}
@TestMetadata("conversionsWithNestedGenerics.kt")
public void testConversionsWithNestedGenerics() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionsWithNestedGenerics.kt");
}
@TestMetadata("enhancedSamConstructor.kt")
public void testEnhancedSamConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
......@@ -13663,6 +13663,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/j+k/sam/compatibilityResolveToOuterScopeForKotlinFunctions.kt");
}
@TestMetadata("conversionForDerivedGenericClass.kt")
public void testConversionForDerivedGenericClass() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionForDerivedGenericClass.kt");
}
@TestMetadata("conversionsWithNestedGenerics.kt")
public void testConversionsWithNestedGenerics() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/conversionsWithNestedGenerics.kt");
}
@TestMetadata("enhancedSamConstructor.kt")
public void testEnhancedSamConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt");
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册