Prioritized super constructor calls.

This commit is contained in:
Evgeny Gerashchenko
2013-06-26 21:04:11 +04:00
parent 2cb4c7edbb
commit f2458f62c2
5 changed files with 62 additions and 31 deletions
@@ -183,8 +183,6 @@ public class CallResolver {
if (calleeExpression instanceof JetConstructorCalleeExpression) {
assert !context.call.getExplicitReceiver().exists();
prioritizedTasks = Lists.newArrayList();
JetConstructorCalleeExpression expression = (JetConstructorCalleeExpression) calleeExpression;
functionReference = expression.getConstructorReferenceExpression();
if (functionReference == null) {
@@ -207,10 +205,8 @@ public class CallResolver {
return checkArgumentTypesAndFail(context);
}
Collection<ResolutionCandidate<CallableDescriptor>> candidates = TaskPrioritizer.<CallableDescriptor>convertWithImpliedThis(context.scope, Collections.<ReceiverValue>singletonList(NO_RECEIVER), constructors);
for (ResolutionCandidate<CallableDescriptor> candidate : candidates) {
candidate.setSafeCall(JetPsiUtil.isSafeCall(context.call));
}
prioritizedTasks.add(new ResolutionTask<CallableDescriptor, FunctionDescriptor>(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
prioritizedTasks = TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
context, functionReference, candidates);
}
else {
context.trace.report(NOT_A_CLASS.on(calleeExpression));
@@ -87,32 +87,8 @@ public class TaskPrioritizer {
else {
scope = context.scope;
}
ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>> visibleStrategy = new ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>>() {
@Override
public int getPriority(ResolutionCandidate<D> call) {
return (isVisible(call) ? 2 : 0) + (isSynthesized(call) ? 0 : 1);
}
@Override
public int getMaxPriority() {
return 3;
}
private boolean isVisible(ResolutionCandidate<D> call) {
if (call == null) return false;
D candidateDescriptor = call.getDescriptor();
if (ErrorUtils.isError(candidateDescriptor)) return true;
return Visibilities.isVisible(candidateDescriptor, context.scope.getContainingDeclaration());
}
private boolean isSynthesized(ResolutionCandidate<D> call) {
D descriptor = call.getDescriptor();
return descriptor instanceof CallableMemberDescriptor &&
isOrOverridesSynthesized((CallableMemberDescriptor) descriptor);
}
};
ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>(functionReference, context, visibleStrategy);
ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>(functionReference, context, new MyPriorityProvider<D>(context));
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : callableDescriptorCollectors) {
doComputeTasks(scope, explicitReceiver, name, result, context, callableDescriptorCollector);
}
@@ -248,6 +224,48 @@ public class TaskPrioritizer {
return false;
}
public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasksFromCandidates(
@NotNull BasicCallResolutionContext context,
@NotNull JetReferenceExpression functionReference,
@NotNull Collection<ResolutionCandidate<D>> candidates
) {
ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>(functionReference, context, new MyPriorityProvider<D>(context));
result.addCandidates(candidates);
return result.getTasks();
}
private TaskPrioritizer() {
}
private static class MyPriorityProvider<D extends CallableDescriptor>
implements ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>> {
private final BasicCallResolutionContext context;
public MyPriorityProvider(BasicCallResolutionContext context) {
this.context = context;
}
@Override
public int getPriority(ResolutionCandidate<D> call) {
return (isVisible(call) ? 2 : 0) + (isSynthesized(call) ? 0 : 1);
}
@Override
public int getMaxPriority() {
return 3;
}
private boolean isVisible(ResolutionCandidate<D> call) {
if (call == null) return false;
D candidateDescriptor = call.getDescriptor();
if (ErrorUtils.isError(candidateDescriptor)) return true;
return Visibilities.isVisible(candidateDescriptor, context.scope.getContainingDeclaration());
}
private boolean isSynthesized(ResolutionCandidate<D> call) {
D descriptor = call.getDescriptor();
return descriptor instanceof CallableMemberDescriptor &&
isOrOverridesSynthesized((CallableMemberDescriptor) descriptor);
}
}
}
@@ -0,0 +1,5 @@
class JavaClass {
JavaClass(Runnable r) {
if (r != null) r.run();
}
}
@@ -0,0 +1,7 @@
class KotlinClass(): JavaClass(null) {
}
fun box(): String {
KotlinClass()
return "OK"
}
@@ -205,6 +205,11 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/simplest.kt");
}
@TestMetadata("superconstructor.kt")
public void testSuperconstructor() throws Exception {
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/superconstructor.kt");
}
@TestMetadata("typeParameterOfClass.kt")
public void testTypeParameterOfClass() throws Exception {
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfClass.kt");