Fixed resolve for callable references

functions and properties have the same priority
This commit is contained in:
Svetlana Isakova
2014-12-22 14:05:17 +03:00
parent f0bb6c58fc
commit 62c8a6f79a
6 changed files with 83 additions and 57 deletions
@@ -119,10 +119,19 @@ public class CallResolver {
else { else {
callableDescriptorCollectors = CallableDescriptorCollectors.VARIABLES; callableDescriptorCollectors = CallableDescriptorCollectors.VARIABLES;
} }
TracingStrategy tracing = TracingStrategyImpl.create(nameExpression, context.call); return computeTasksAndResolveCall(
List<ResolutionTask<VariableDescriptor, VariableDescriptor>> prioritizedTasks = context, referencedName, nameExpression,
taskPrioritizer.<VariableDescriptor, VariableDescriptor>computePrioritizedTasks(context, referencedName, tracing, callableDescriptorCollectors); callableDescriptorCollectors, CallTransformer.VARIABLE_CALL_TRANSFORMER);
return doResolveCallOrGetCachedResults(context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, tracing); }
@NotNull
public OverloadResolutionResults<CallableDescriptor> resolveCallForMember(
@NotNull JetSimpleNameExpression nameExpression,
@NotNull BasicCallResolutionContext context
) {
return computeTasksAndResolveCall(
context, nameExpression.getReferencedNameAsName(), nameExpression,
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.MEMBER_CALL_TRANSFORMER);
} }
@NotNull @NotNull
@@ -132,21 +141,10 @@ public class CallResolver {
@NotNull JetReferenceExpression functionReference, @NotNull JetReferenceExpression functionReference,
@NotNull Name name @NotNull Name name
) { ) {
return resolveCallWithGivenName( BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED);
BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED), return computeTasksAndResolveCall(
functionReference, callResolutionContext, name, functionReference,
name CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER);
);
}
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
@NotNull BasicCallResolutionContext context,
@NotNull JetReferenceExpression functionReference,
@NotNull Name name
) {
TracingStrategy tracing = TracingStrategyImpl.create(functionReference, context.call);
return resolveCallWithGivenName(context, name, tracing, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
} }
@NotNull @NotNull
@@ -154,19 +152,33 @@ public class CallResolver {
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
return resolveCallWithGivenName(context, Name.identifier("invoke"), tracing, CallableDescriptorCollectors.FUNCTIONS); return computeTasksAndResolveCall(
context, Name.identifier("invoke"), tracing,
CallableDescriptorCollectors.FUNCTIONS, CallTransformer.FUNCTION_CALL_TRANSFORMER);
} }
@NotNull @NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName( private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksAndResolveCall(
@NotNull BasicCallResolutionContext context,
@NotNull Name name,
@NotNull JetReferenceExpression referenceExpression,
@NotNull CallableDescriptorCollectors<D> collectors,
@NotNull CallTransformer<D, F> callTransformer
) {
TracingStrategy tracing = TracingStrategyImpl.create(referenceExpression, context.call);
return computeTasksAndResolveCall(context, name, tracing, collectors, callTransformer);
}
@NotNull
private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksAndResolveCall(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull Name name, @NotNull Name name,
@NotNull TracingStrategy tracing, @NotNull TracingStrategy tracing,
@NotNull CallableDescriptorCollectors<CallableDescriptor> collectors @NotNull CallableDescriptorCollectors<D> collectors,
@NotNull CallTransformer<D, F> callTransformer
) { ) {
List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks = List<ResolutionTask<D, F>> tasks = taskPrioritizer.<D, F>computePrioritizedTasks(context, name, tracing, collectors);
taskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasks(context, name, tracing, collectors); return doResolveCallOrGetCachedResults(context, tasks, callTransformer, tracing);
return doResolveCallOrGetCachedResults(context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing);
} }
@NotNull @NotNull
@@ -91,7 +91,9 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
} }
public static CallTransformer<VariableDescriptor, VariableDescriptor> PROPERTY_CALL_TRANSFORMER = new CallTransformer<VariableDescriptor, VariableDescriptor>(); public static CallTransformer<CallableDescriptor, CallableDescriptor> MEMBER_CALL_TRANSFORMER = new CallTransformer<CallableDescriptor, CallableDescriptor>();
public static CallTransformer<VariableDescriptor, VariableDescriptor> VARIABLE_CALL_TRANSFORMER = new CallTransformer<VariableDescriptor, VariableDescriptor>();
public static CallTransformer<CallableDescriptor, FunctionDescriptor> FUNCTION_CALL_TRANSFORMER = new CallTransformer<CallableDescriptor, FunctionDescriptor>() { public static CallTransformer<CallableDescriptor, FunctionDescriptor> FUNCTION_CALL_TRANSFORMER = new CallTransformer<CallableDescriptor, FunctionDescriptor>() {
@NotNull @NotNull
@@ -639,41 +639,22 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@NotNull boolean[] result @NotNull boolean[] result
) { ) {
Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance()); Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance());
TemporaryTraceAndCache temporaryTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as function",
TemporaryTraceAndCache funTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as function",
reference); reference);
ResolvedCall<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver()
.getResolvedCallForFunction(call, reference, context.replaceTraceAndCache(funTrace).replaceExpectedType(NO_EXPECTED_TYPE),
CheckValueArgumentsMode.DISABLED, result);
if (result[0]) {
funTrace.commit();
if (function instanceof VariableAsFunctionResolvedCall) { BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet")); context.replaceTraceAndCache(temporaryTrace).replaceExpectedType(NO_EXPECTED_TYPE), call, CheckValueArgumentsMode.DISABLED);
return null; OverloadResolutionResults<CallableDescriptor> results =
} components.expressionTypingServices.getCallResolver().resolveCallForMember(reference, callResolutionContext);
if (!results.isNothing()) {
return function != null ? function.getResultingDescriptor() : null; temporaryTrace.commit();
} result[0] = true;
ResolvedCall<CallableDescriptor> callable =
TemporaryTraceAndCache varTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as variable", OverloadResolutionResultsUtil.getResultingCall(results, context.contextDependency);
reference); if (callable != null) {
OverloadResolutionResults<VariableDescriptor> variableResults = return callable.getResultingDescriptor();
components.expressionTypingServices.getCallResolver().resolveSimpleProperty(
BasicCallResolutionContext.create(context.replaceTraceAndCache(varTrace).replaceExpectedType(NO_EXPECTED_TYPE),
call, CheckValueArgumentsMode.DISABLED)
);
if (!variableResults.isNothing()) {
ResolvedCall<VariableDescriptor> variable =
OverloadResolutionResultsUtil.getResultingCall(variableResults, context.contextDependency);
varTrace.commit();
if (variable != null) {
result[0] = true;
return variable.getResultingDescriptor();
} }
} }
return null; return null;
} }
@@ -0,0 +1,13 @@
// !CHECK_TYPE
import kotlin.reflect.KMemberProperty
class C {
val baz: Int = 12
}
fun Int.baz() {}
fun test() {
C::baz checkType { it : _<KMemberProperty<C, Int>>}
}
@@ -0,0 +1,12 @@
package
internal fun test(): kotlin.Unit
internal fun kotlin.Int.baz(): kotlin.Unit
internal final class C {
public constructor C()
internal final val baz: kotlin.Int = 12
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
}
@@ -544,6 +544,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
doTest(fileName); doTest(fileName);
} }
@TestMetadata("samePriorityForFunctionsAndProperties.kt")
public void testSamePriorityForFunctionsAndProperties() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/samePriorityForFunctionsAndProperties.kt");
doTest(fileName);
}
@TestMetadata("topLevelFromTopLevel.kt") @TestMetadata("topLevelFromTopLevel.kt")
public void testTopLevelFromTopLevel() throws Exception { public void testTopLevelFromTopLevel() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/topLevelFromTopLevel.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference/property/topLevelFromTopLevel.kt");