Deduce receiver type of callable reference from LHS, not from descriptor

This commit is contained in:
Alexander Udalov
2015-10-15 13:05:55 +03:00
parent 2cf437c0e2
commit bf4a681589
6 changed files with 59 additions and 8 deletions
@@ -201,6 +201,7 @@ private fun bindPropertyReference(expression: JetCallableReferenceExpression, re
private fun createReflectionTypeForCallableDescriptor(
descriptor: CallableDescriptor,
lhsType: JetType?,
reflectionTypes: ReflectionTypes,
trace: BindingTrace?,
reportOn: JetExpression?
@@ -220,7 +221,10 @@ private fun createReflectionTypeForCallableDescriptor(
return null
}
val receiverType = extensionReceiver?.getType() ?: dispatchReceiver?.getType()
val receiverType =
if (extensionReceiver != null || dispatchReceiver != null)
lhsType ?: extensionReceiver?.type ?: dispatchReceiver?.type
else null
return when (descriptor) {
is FunctionDescriptor ->
@@ -242,16 +246,18 @@ public fun getReflectionTypeForCandidateDescriptor(
descriptor: CallableDescriptor,
reflectionTypes: ReflectionTypes
): JetType? =
createReflectionTypeForCallableDescriptor(descriptor, reflectionTypes, null, null)
createReflectionTypeForCallableDescriptor(descriptor, null, reflectionTypes, null, null)
public fun createReflectionTypeForResolvedCallableReference(
reference: JetCallableReferenceExpression,
lhsType: JetType?,
descriptor: CallableDescriptor,
context: ResolutionContext<*>,
reflectionTypes: ReflectionTypes
): JetType? {
val type = createReflectionTypeForCallableDescriptor(descriptor, reflectionTypes, context.trace, reference.getCallableReference())
?: return null
val type = createReflectionTypeForCallableDescriptor(
descriptor, lhsType, reflectionTypes, context.trace, reference.getCallableReference()
) ?: return null
when (descriptor) {
is FunctionDescriptor -> {
bindFunctionReference(reference, type, context)
@@ -265,6 +271,7 @@ public fun createReflectionTypeForResolvedCallableReference(
public fun getResolvedCallableReferenceShapeType(
reference: JetCallableReferenceExpression,
lhsType: JetType?,
overloadResolutionResults: OverloadResolutionResults<CallableDescriptor>?,
context: ResolutionContext<*>,
expectedTypeUnknown: Boolean,
@@ -275,9 +282,9 @@ public fun getResolvedCallableReferenceShapeType(
when {
overloadResolutionResults == null ->
null
overloadResolutionResults.isSingleResult() ->
overloadResolutionResults.isSingleResult ->
OverloadResolutionResultsUtil.getResultingCall(overloadResolutionResults, context.contextDependency)?.let { call ->
createReflectionTypeForCallableDescriptor(call.getResultingDescriptor(), reflectionTypes, context.trace, reference)
createReflectionTypeForCallableDescriptor(call.resultingDescriptor, lhsType, reflectionTypes, context.trace, reference)
}
expectedTypeUnknown /* && overload resolution was ambiguous */ ->
functionPlaceholders.createFunctionPlaceholderType(emptyList(), false)
@@ -250,7 +250,7 @@ public class ArgumentTypeResolver {
callableReferenceExpression, receiverType, context, ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS,
callResolver);
return CallableReferencesResolutionUtilsKt.getResolvedCallableReferenceShapeType(
callableReferenceExpression, overloadResolutionResults, context, expectedTypeIsUnknown,
callableReferenceExpression, receiverType, overloadResolutionResults, context, expectedTypeIsUnknown,
reflectionTypes, builtIns, functionPlaceholders);
}
@@ -700,7 +700,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
context.trace.report(CALLABLE_REFERENCE_TO_OBJECT_MEMBER.on(reference));
}
return CallableReferencesResolutionUtilsKt.createReflectionTypeForResolvedCallableReference(expression, descriptor, context, components.reflectionTypes);
return CallableReferencesResolutionUtilsKt.createReflectionTypeForResolvedCallableReference(
expression, lhsType, descriptor, context, components.reflectionTypes
);
}
@Override
@@ -0,0 +1,18 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_PARAMETER
import kotlin.reflect.*
interface A
interface B : A
fun A.foo() {}
fun take(f: (A) -> Unit) {}
fun take(f: () -> Unit) {}
fun test() {
B::foo checkType { _<KFunction1<B, Unit>>() }
<!NONE_APPLICABLE!>take<!>(B::foo)
}
@@ -0,0 +1,18 @@
package
public fun take(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public fun take(/*0*/ f: (A) -> kotlin.Unit): kotlin.Unit
public fun test(): kotlin.Unit
public fun A.foo(): kotlin.Unit
public interface A {
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 B : A {
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
}
@@ -1721,6 +1721,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("extensionToSupertype.kt")
public void testExtensionToSupertype() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.kt");
doTest(fileName);
}
@TestMetadata("fakeOverrideType.kt")
public void testFakeOverrideType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/fakeOverrideType.kt");