Refactor delegation call resolution
- Move resolution logic from BodyResolver to CallResolver - Call resolveConstructorDelegationCall explicitly without resolveFunctionCall - Drop dead condition and unused method
This commit is contained in:
@@ -168,21 +168,11 @@ public class BodyResolver {
|
|||||||
@NotNull JetSecondaryConstructor constructor,
|
@NotNull JetSecondaryConstructor constructor,
|
||||||
@NotNull ConstructorDescriptor descriptor
|
@NotNull ConstructorDescriptor descriptor
|
||||||
) {
|
) {
|
||||||
JetConstructorDelegationCall call = constructor.getDelegationCall();
|
OverloadResolutionResults<?> results = callResolver.resolveConstructorDelegationCall(
|
||||||
if (call == null || call.getCalleeExpression() == null) return null;
|
trace, scope, c.getOuterDataFlowInfo(),
|
||||||
JetType superClassType = DescriptorUtils.getSuperClassType(descriptor.getContainingDeclaration());
|
descriptor, constructor.getDelegationCall());
|
||||||
|
|
||||||
if (descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS && call.getCalleeExpression().isEmpty()) {
|
if (results != null && results.isSingleResult()) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
OverloadResolutionResults<?> results = callResolver.resolveFunctionCall(
|
|
||||||
trace, scope,
|
|
||||||
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
|
|
||||||
superClassType != null ? superClassType : NO_EXPECTED_TYPE,
|
|
||||||
c.getOuterDataFlowInfo(), false);
|
|
||||||
|
|
||||||
if (results.isSingleResult()) {
|
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = results.getResultingCall();
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = results.getResultingCall();
|
||||||
recordConstructorDelegationCall(trace, descriptor, resolvedCall);
|
recordConstructorDelegationCall(trace, descriptor, resolvedCall);
|
||||||
return resolvedCall.getDataFlowInfoForArguments().getResultInfo();
|
return resolvedCall.getDataFlowInfoForArguments().getResultInfo();
|
||||||
|
|||||||
@@ -238,9 +238,6 @@ public class CallResolver {
|
|||||||
if (calleeExpression instanceof JetConstructorCalleeExpression) {
|
if (calleeExpression instanceof JetConstructorCalleeExpression) {
|
||||||
return resolveCallForConstructor(context, (JetConstructorCalleeExpression) calleeExpression);
|
return resolveCallForConstructor(context, (JetConstructorCalleeExpression) calleeExpression);
|
||||||
}
|
}
|
||||||
else if (calleeExpression instanceof JetConstructorDelegationReferenceExpression) {
|
|
||||||
return resolveConstructorDelegationCall(context, (JetConstructorDelegationReferenceExpression) calleeExpression);
|
|
||||||
}
|
|
||||||
else if (calleeExpression == null) {
|
else if (calleeExpression == null) {
|
||||||
return checkArgumentTypesAndFail(context);
|
return checkArgumentTypesAndFail(context);
|
||||||
}
|
}
|
||||||
@@ -289,22 +286,58 @@ public class CallResolver {
|
|||||||
return computeTasksFromCandidatesAndResolvedCall(context, functionReference, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER);
|
return computeTasksFromCandidatesAndResolvedCall(context, functionReference, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public OverloadResolutionResults<FunctionDescriptor> resolveConstructorDelegationCall(
|
||||||
|
@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull DataFlowInfo dataFlowInfo,
|
||||||
|
@NotNull ConstructorDescriptor constructorDescriptor,
|
||||||
|
@Nullable JetConstructorDelegationCall call
|
||||||
|
) {
|
||||||
|
// Returns `null` when there is nothing to resolve in trivial cases like `null` call expression or
|
||||||
|
// when super call should be conventional enum constructor and super call should be empty
|
||||||
|
if (call == null) return null;
|
||||||
|
|
||||||
|
JetType superClassType = DescriptorUtils.getSuperClassType(constructorDescriptor.getContainingDeclaration());
|
||||||
|
|
||||||
|
BasicCallResolutionContext context = BasicCallResolutionContext.create(
|
||||||
|
trace, scope,
|
||||||
|
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
|
||||||
|
superClassType != null ? superClassType : NO_EXPECTED_TYPE,
|
||||||
|
dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED,
|
||||||
|
expressionTypingServices.getCallChecker(), expressionTypingServices.getAdditionalTypeChecker(), false);
|
||||||
|
|
||||||
|
if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
|
||||||
|
|
||||||
|
if (constructorDescriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS &&
|
||||||
|
call.getCalleeExpression().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolveConstructorDelegationCall(
|
||||||
|
context,
|
||||||
|
call.getCalleeExpression(),
|
||||||
|
constructorDescriptor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private OverloadResolutionResults<FunctionDescriptor> resolveConstructorDelegationCall(
|
private OverloadResolutionResults<FunctionDescriptor> resolveConstructorDelegationCall(
|
||||||
@NotNull BasicCallResolutionContext context,
|
@NotNull BasicCallResolutionContext context,
|
||||||
@NotNull JetConstructorDelegationReferenceExpression calleeExpression
|
@NotNull JetConstructorDelegationReferenceExpression calleeExpression,
|
||||||
|
@NotNull ConstructorDescriptor calleeConstructor
|
||||||
) {
|
) {
|
||||||
ClassDescriptor currentClassDescriptor = getClassDescriptorByConstructorContext(context);
|
ClassDescriptor currentClassDescriptor = calleeConstructor.getContainingDeclaration();
|
||||||
if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !calleeExpression.isThis()) {
|
|
||||||
|
boolean isThisCall = calleeExpression.isThis();
|
||||||
|
if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !isThisCall) {
|
||||||
context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on((JetConstructorDelegationCall) calleeExpression.getParent()));
|
context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on((JetConstructorDelegationCall) calleeExpression.getParent()));
|
||||||
return checkArgumentTypesAndFail(context);
|
return checkArgumentTypesAndFail(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassDescriptor delegateClassDescriptor = calleeExpression.isThis() ? currentClassDescriptor :
|
ClassDescriptor delegateClassDescriptor = isThisCall ? currentClassDescriptor :
|
||||||
DescriptorUtilPackage.getSuperClassOrAny(currentClassDescriptor);
|
DescriptorUtilPackage.getSuperClassOrAny(currentClassDescriptor);
|
||||||
Collection<ConstructorDescriptor> constructors = delegateClassDescriptor.getConstructors();
|
Collection<ConstructorDescriptor> constructors = delegateClassDescriptor.getConstructors();
|
||||||
|
|
||||||
if (!calleeExpression.isThis() && currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
if (!isThisCall && currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||||
context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(
|
context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(
|
||||||
(JetConstructorDelegationCall) calleeExpression.getParent()
|
(JetConstructorDelegationCall) calleeExpression.getParent()
|
||||||
));
|
));
|
||||||
@@ -330,16 +363,6 @@ public class CallResolver {
|
|||||||
return computeTasksFromCandidatesAndResolvedCall(context, calleeExpression, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER);
|
return computeTasksFromCandidatesAndResolvedCall(context, calleeExpression, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static ClassDescriptor getClassDescriptorByConstructorContext(@NotNull BasicCallResolutionContext context) {
|
|
||||||
DeclarationDescriptor containingDeclaration = context.scope.getContainingDeclaration();
|
|
||||||
if (containingDeclaration instanceof ConstructorDescriptor) {
|
|
||||||
containingDeclaration = containingDeclaration.getContainingDeclaration();
|
|
||||||
}
|
|
||||||
assert containingDeclaration != null : "Grandparent of delegation call should be a class descriptor";
|
|
||||||
return (ClassDescriptor) containingDeclaration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithKnownCandidate(
|
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithKnownCandidate(
|
||||||
@NotNull Call call,
|
@NotNull Call call,
|
||||||
@NotNull TracingStrategy tracing,
|
@NotNull TracingStrategy tracing,
|
||||||
|
|||||||
Reference in New Issue
Block a user