Minor. Convert CandidateResolver to kt
This commit is contained in:
@@ -14,314 +14,280 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls;
|
||||
package org.jetbrains.kotlin.resolve.calls
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TasksPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
import org.jetbrains.kotlin.types.expressions.JetTypeInfo;
|
||||
import com.google.common.collect.Lists
|
||||
import com.google.common.collect.Sets
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.*
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.*
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import org.jetbrains.kotlin.types.expressions.JetTypeInfo
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject
|
||||
import java.util.ArrayList
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER;
|
||||
import static org.jetbrains.kotlin.resolve.calls.CallTransformer.CallForImplicitInvoke;
|
||||
import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage.getEffectiveExpectedType;
|
||||
import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS;
|
||||
import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.*;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer.CallForImplicitInvoke
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.*
|
||||
import org.jetbrains.kotlin.types.TypeUtils.noExpectedType
|
||||
|
||||
public class CandidateResolver {
|
||||
@NotNull
|
||||
private ArgumentTypeResolver argumentTypeResolver;
|
||||
@NotNull
|
||||
private GenericCandidateResolver genericCandidateResolver;
|
||||
public class CandidateResolver(
|
||||
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||
private val genericCandidateResolver: GenericCandidateResolver
|
||||
){
|
||||
|
||||
@Inject
|
||||
public void setArgumentTypeResolver(@NotNull ArgumentTypeResolver argumentTypeResolver) {
|
||||
this.argumentTypeResolver = argumentTypeResolver;
|
||||
}
|
||||
public fun <D : CallableDescriptor, F : D> performResolutionForCandidateCall(
|
||||
context: CallCandidateResolutionContext<D>,
|
||||
task: ResolutionTask<D, F>) {
|
||||
|
||||
@Inject
|
||||
public void setGenericCandidateResolver(@NotNull GenericCandidateResolver genericCandidateResolver) {
|
||||
this.genericCandidateResolver = genericCandidateResolver;
|
||||
}
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
public <D extends CallableDescriptor, F extends D> void performResolutionForCandidateCall(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@NotNull ResolutionTask<D, F> task) {
|
||||
val candidateCall = context.candidateCall
|
||||
val candidate = candidateCall.getCandidateDescriptor()
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
|
||||
MutableResolvedCall<D> candidateCall = context.candidateCall;
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
|
||||
candidateCall.addStatus(checkReceiverTypeError(context));
|
||||
candidateCall.addStatus(checkReceiverTypeError(context))
|
||||
|
||||
if (ErrorUtils.isError(candidate)) {
|
||||
candidateCall.addStatus(SUCCESS);
|
||||
return;
|
||||
candidateCall.addStatus(SUCCESS)
|
||||
return
|
||||
}
|
||||
|
||||
if (!checkOuterClassMemberIsAccessible(context)) {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
return;
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ReceiverValue receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(), context.trace.getBindingContext());
|
||||
DeclarationDescriptorWithVisibility invisibleMember =
|
||||
Visibilities.findInvisibleMember(receiverValue, candidate, context.scope.getContainingDeclaration());
|
||||
val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(), context.trace.getBindingContext())
|
||||
val invisibleMember = Visibilities.findInvisibleMember(receiverValue, candidate, context.scope.getContainingDeclaration())
|
||||
if (invisibleMember != null) {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
context.tracing.invisibleMember(context.trace, invisibleMember);
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
context.tracing.invisibleMember(context.trace, invisibleMember)
|
||||
}
|
||||
|
||||
if (task.checkArguments == CheckValueArgumentsMode.ENABLED) {
|
||||
ValueArgumentsToParametersMapper.Status argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
|
||||
context.call, context.tracing, candidateCall, Sets.<ValueArgument>newLinkedHashSet()
|
||||
);
|
||||
val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
|
||||
context.call, context.tracing, candidateCall, Sets.newLinkedHashSet<ValueArgument>())
|
||||
if (!argumentMappingStatus.isSuccess()) {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
checkExtensionReceiver(context);
|
||||
checkExtensionReceiver(context)
|
||||
|
||||
if (!checkDispatchReceiver(context)) {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
}
|
||||
|
||||
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
|
||||
val jetTypeArguments = context.call.getTypeArguments()
|
||||
if (!jetTypeArguments.isEmpty()) {
|
||||
// Explicit type arguments passed
|
||||
|
||||
List<JetType> typeArguments = new ArrayList<JetType>();
|
||||
for (JetTypeProjection projection : jetTypeArguments) {
|
||||
val typeArguments = ArrayList<JetType>()
|
||||
for (projection in jetTypeArguments) {
|
||||
if (projection.getProjectionKind() != JetProjectionKind.NONE) {
|
||||
context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
|
||||
ModifiersChecker.checkIncompatibleVarianceModifiers(projection.getModifierList(), context.trace);
|
||||
context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection))
|
||||
ModifiersChecker.checkIncompatibleVarianceModifiers(projection.getModifierList(), context.trace)
|
||||
}
|
||||
JetType type = argumentTypeResolver.resolveTypeRefWithDefault(
|
||||
val type = argumentTypeResolver.resolveTypeRefWithDefault(
|
||||
projection.getTypeReference(), context.scope, context.trace,
|
||||
ErrorUtils.createErrorType("Star projection in a call")
|
||||
);
|
||||
ForceResolveUtil.forceResolveAllContents(type);
|
||||
typeArguments.add(type);
|
||||
ErrorUtils.createErrorType("Star projection in a call"))!!
|
||||
ForceResolveUtil.forceResolveAllContents(type)
|
||||
typeArguments.add(type)
|
||||
}
|
||||
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
|
||||
for (int index = jetTypeArguments.size(); index < expectedTypeArgumentCount; index++) {
|
||||
val expectedTypeArgumentCount = candidate.getTypeParameters().size()
|
||||
for (index in jetTypeArguments.size()..expectedTypeArgumentCount - 1) {
|
||||
typeArguments.add(ErrorUtils.createErrorType(
|
||||
"Explicit type argument expected for " + candidate.getTypeParameters().get(index).getName()));
|
||||
"Explicit type argument expected for " + candidate.getTypeParameters().get(index).getName()))
|
||||
}
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext =
|
||||
FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
|
||||
val substitutionContext = FunctionDescriptorUtil.createSubstitutionContext(candidate as FunctionDescriptor, typeArguments)
|
||||
val substitutor = TypeSubstitutor.create(substitutionContext)
|
||||
|
||||
if (expectedTypeArgumentCount != jetTypeArguments.size()) {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount)
|
||||
}
|
||||
else {
|
||||
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, substitutor, context.trace);
|
||||
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, substitutor, context.trace)
|
||||
}
|
||||
|
||||
candidateCall.setResultingSubstitutor(substitutor);
|
||||
candidateCall.setResultingSubstitutor(substitutor)
|
||||
}
|
||||
else if (candidateCall.getKnownTypeParametersSubstitutor() != null) {
|
||||
candidateCall.setResultingSubstitutor(candidateCall.getKnownTypeParametersSubstitutor());
|
||||
candidateCall.setResultingSubstitutor(candidateCall.getKnownTypeParametersSubstitutor()!!)
|
||||
}
|
||||
|
||||
if (jetTypeArguments.isEmpty() &&
|
||||
!candidate.getTypeParameters().isEmpty() &&
|
||||
candidateCall.getKnownTypeParametersSubstitutor() == null) {
|
||||
candidateCall.addStatus(genericCandidateResolver.inferTypeArguments(context));
|
||||
if (jetTypeArguments.isEmpty() && !candidate.getTypeParameters().isEmpty() && candidateCall.getKnownTypeParametersSubstitutor() == null) {
|
||||
candidateCall.addStatus(genericCandidateResolver.inferTypeArguments(context))
|
||||
}
|
||||
else {
|
||||
candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status);
|
||||
candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status)
|
||||
}
|
||||
|
||||
checkAbstractAndSuper(context);
|
||||
checkAbstractAndSuper(context)
|
||||
|
||||
checkNonExtensionCalledWithReceiver(context);
|
||||
checkNonExtensionCalledWithReceiver(context)
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> void checkExtensionReceiver(@NotNull CallCandidateResolutionContext<D> context) {
|
||||
MutableResolvedCall<D> candidateCall = context.candidateCall;
|
||||
ReceiverParameterDescriptor receiverParameter = candidateCall.getCandidateDescriptor().getExtensionReceiverParameter();
|
||||
ReceiverValue receiverArgument = candidateCall.getExtensionReceiver();
|
||||
if (receiverParameter != null &&!receiverArgument.exists()) {
|
||||
context.tracing.missingReceiver(candidateCall.getTrace(), receiverParameter);
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
private fun <D : CallableDescriptor> checkExtensionReceiver(context: CallCandidateResolutionContext<D>) {
|
||||
val candidateCall = context.candidateCall
|
||||
val receiverParameter = candidateCall.getCandidateDescriptor().getExtensionReceiverParameter()
|
||||
val receiverArgument = candidateCall.getExtensionReceiver()
|
||||
if (receiverParameter != null && !receiverArgument.exists()) {
|
||||
context.tracing.missingReceiver(candidateCall.getTrace(), receiverParameter)
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
}
|
||||
if (receiverParameter == null && receiverArgument.exists()) {
|
||||
context.tracing.noReceiverAllowed(candidateCall.getTrace());
|
||||
if (context.call.getCalleeExpression() instanceof JetSimpleNameExpression) {
|
||||
candidateCall.addStatus(RECEIVER_PRESENCE_ERROR);
|
||||
context.tracing.noReceiverAllowed(candidateCall.getTrace())
|
||||
if (context.call.getCalleeExpression() is JetSimpleNameExpression) {
|
||||
candidateCall.addStatus(RECEIVER_PRESENCE_ERROR)
|
||||
}
|
||||
else {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkDispatchReceiver(@NotNull CallCandidateResolutionContext<?> context) {
|
||||
MutableResolvedCall<? extends CallableDescriptor> candidateCall = context.candidateCall;
|
||||
CallableDescriptor candidateDescriptor = candidateCall.getCandidateDescriptor();
|
||||
ReceiverValue dispatchReceiver = candidateCall.getDispatchReceiver();
|
||||
private fun checkDispatchReceiver(context: CallCandidateResolutionContext<*>): Boolean {
|
||||
val candidateCall = context.candidateCall
|
||||
val candidateDescriptor = candidateCall.getCandidateDescriptor()
|
||||
val dispatchReceiver = candidateCall.getDispatchReceiver()
|
||||
if (dispatchReceiver.exists()) {
|
||||
ClassDescriptor nestedClass = null;
|
||||
if (candidateDescriptor instanceof ConstructorDescriptor
|
||||
&& DescriptorUtils.isStaticNestedClass(candidateDescriptor.getContainingDeclaration())) {
|
||||
nestedClass = (ClassDescriptor) candidateDescriptor.getContainingDeclaration();
|
||||
var nestedClass: ClassDescriptor? = null
|
||||
if (candidateDescriptor is ConstructorDescriptor && DescriptorUtils.isStaticNestedClass(candidateDescriptor.getContainingDeclaration())) {
|
||||
nestedClass = candidateDescriptor.getContainingDeclaration()
|
||||
}
|
||||
else if (candidateDescriptor instanceof FakeCallableDescriptorForObject) {
|
||||
nestedClass = ((FakeCallableDescriptorForObject) candidateDescriptor).getReferencedDescriptor();
|
||||
else if (candidateDescriptor is FakeCallableDescriptorForObject) {
|
||||
nestedClass = candidateDescriptor.getReferencedDescriptor()
|
||||
}
|
||||
if (nestedClass != null) {
|
||||
context.tracing.nestedClassAccessViaInstanceReference(context.trace, nestedClass, candidateCall.getExplicitReceiverKind());
|
||||
return false;
|
||||
context.tracing.nestedClassAccessViaInstanceReference(context.trace, nestedClass, candidateCall.getExplicitReceiverKind())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
assert (dispatchReceiver.exists() == (candidateCall.getResultingDescriptor().getDispatchReceiverParameter() != null))
|
||||
: "Shouldn't happen because of TaskPrioritizer: " + candidateDescriptor;
|
||||
assert((dispatchReceiver.exists() == (candidateCall.getResultingDescriptor().getDispatchReceiverParameter() != null))) { "Shouldn't happen because of TaskPrioritizer: $candidateDescriptor" }
|
||||
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
private boolean checkOuterClassMemberIsAccessible(@NotNull CallCandidateResolutionContext<?> context) {
|
||||
private fun checkOuterClassMemberIsAccessible(context: CallCandidateResolutionContext<*>): Boolean {
|
||||
// In "this@Outer.foo()" the error will be reported on "this@Outer" instead
|
||||
if (context.call.getExplicitReceiver().exists() || context.call.getDispatchReceiver().exists()) return true;
|
||||
if (context.call.getExplicitReceiver().exists() || context.call.getDispatchReceiver().exists()) return true
|
||||
|
||||
ClassDescriptor candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor());
|
||||
if (candidateThis == null || candidateThis.getKind().isSingleton()) return true;
|
||||
val candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor())
|
||||
if (candidateThis == null || candidateThis.getKind().isSingleton()) return true
|
||||
|
||||
return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis);
|
||||
return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis)
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> void checkAbstractAndSuper(@NotNull CallCandidateResolutionContext<D> context) {
|
||||
MutableResolvedCall<D> candidateCall = context.candidateCall;
|
||||
CallableDescriptor descriptor = candidateCall.getCandidateDescriptor();
|
||||
JetExpression expression = context.candidateCall.getCall().getCalleeExpression();
|
||||
private fun <D : CallableDescriptor> checkAbstractAndSuper(context: CallCandidateResolutionContext<D>) {
|
||||
val candidateCall = context.candidateCall
|
||||
val descriptor = candidateCall.getCandidateDescriptor()
|
||||
val expression = context.candidateCall.getCall().getCalleeExpression()
|
||||
|
||||
if (expression instanceof JetSimpleNameExpression) {
|
||||
if (expression is JetSimpleNameExpression) {
|
||||
// 'B' in 'class A: B()' is JetConstructorCalleeExpression
|
||||
if (descriptor instanceof ConstructorDescriptor) {
|
||||
Modality modality = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality();
|
||||
if (descriptor is ConstructorDescriptor) {
|
||||
val modality = descriptor.getContainingDeclaration().getModality()
|
||||
if (modality == Modality.ABSTRACT) {
|
||||
context.tracing.instantiationOfAbstractClass(context.trace);
|
||||
context.tracing.instantiationOfAbstractClass(context.trace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JetSuperExpression superDispatchReceiver = getReceiverSuper(candidateCall.getDispatchReceiver());
|
||||
val superDispatchReceiver = getReceiverSuper(candidateCall.getDispatchReceiver())
|
||||
if (superDispatchReceiver != null) {
|
||||
if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).getModality() == Modality.ABSTRACT) {
|
||||
context.tracing.abstractSuperCall(context.trace);
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
if (descriptor is MemberDescriptor && descriptor.getModality() == Modality.ABSTRACT) {
|
||||
context.tracing.abstractSuperCall(context.trace)
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
// 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
|
||||
// See TaskPrioritizer for more
|
||||
JetSuperExpression superExtensionReceiver = getReceiverSuper(candidateCall.getExtensionReceiver());
|
||||
val superExtensionReceiver = getReceiverSuper(candidateCall.getExtensionReceiver())
|
||||
if (superExtensionReceiver != null) {
|
||||
context.trace.report(SUPER_CANT_BE_EXTENSION_RECEIVER.on(superExtensionReceiver, superExtensionReceiver.getText()));
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
context.trace.report(SUPER_CANT_BE_EXTENSION_RECEIVER.on(superExtensionReceiver, superExtensionReceiver.getText()))
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNonExtensionCalledWithReceiver(@NotNull CallCandidateResolutionContext<?> context) {
|
||||
MutableResolvedCall<?> candidateCall = context.candidateCall;
|
||||
private fun checkNonExtensionCalledWithReceiver(context: CallCandidateResolutionContext<*>) {
|
||||
val candidateCall = context.candidateCall
|
||||
|
||||
if (TasksPackage.isSynthesizedInvoke(candidateCall.getCandidateDescriptor()) &&
|
||||
!KotlinBuiltIns.isExtensionFunctionType(candidateCall.getDispatchReceiver().getType())) {
|
||||
context.tracing.freeFunctionCalledAsExtension(context.trace);
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
if (isSynthesizedInvoke(candidateCall.getCandidateDescriptor()) && !KotlinBuiltIns.isExtensionFunctionType(candidateCall.getDispatchReceiver().getType())) {
|
||||
context.tracing.freeFunctionCalledAsExtension(context.trace)
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetSuperExpression getReceiverSuper(@NotNull ReceiverValue receiver) {
|
||||
if (receiver instanceof ExpressionReceiver) {
|
||||
ExpressionReceiver expressionReceiver = (ExpressionReceiver) receiver;
|
||||
JetExpression expression = expressionReceiver.getExpression();
|
||||
if (expression instanceof JetSuperExpression) {
|
||||
return (JetSuperExpression) expression;
|
||||
private fun getReceiverSuper(receiver: ReceiverValue): JetSuperExpression? {
|
||||
if (receiver is ExpressionReceiver) {
|
||||
val expression = receiver.getExpression()
|
||||
if (expression is JetSuperExpression) {
|
||||
return expression
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassDescriptor getDeclaringClass(@NotNull CallableDescriptor candidate) {
|
||||
ReceiverParameterDescriptor expectedThis = candidate.getDispatchReceiverParameter();
|
||||
if (expectedThis == null) return null;
|
||||
DeclarationDescriptor descriptor = expectedThis.getContainingDeclaration();
|
||||
return descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null;
|
||||
private fun getDeclaringClass(candidate: CallableDescriptor): ClassDescriptor? {
|
||||
val expectedThis = candidate.getDispatchReceiverParameter() ?: return null
|
||||
val descriptor = expectedThis.getContainingDeclaration()
|
||||
return if (descriptor is ClassDescriptor) descriptor else null
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkAllValueArguments(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@NotNull ResolveArgumentsMode resolveFunctionArgumentBodies) {
|
||||
return checkAllValueArguments(context, context.candidateCall.getTrace(), resolveFunctionArgumentBodies);
|
||||
private fun <D : CallableDescriptor> checkAllValueArguments(
|
||||
context: CallCandidateResolutionContext<D>,
|
||||
resolveFunctionArgumentBodies: ResolveArgumentsMode): ValueArgumentsCheckingResult {
|
||||
return checkAllValueArguments(context, context.candidateCall.getTrace(), resolveFunctionArgumentBodies)
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <D extends CallableDescriptor> ValueArgumentsCheckingResult checkAllValueArguments(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull ResolveArgumentsMode resolveFunctionArgumentBodies
|
||||
) {
|
||||
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(
|
||||
context, context.candidateCall, trace, resolveFunctionArgumentBodies);
|
||||
ResolutionStatus resultStatus = checkingResult.status;
|
||||
resultStatus = resultStatus.combine(checkReceivers(context, trace));
|
||||
public fun <D : CallableDescriptor> checkAllValueArguments(
|
||||
context: CallCandidateResolutionContext<D>,
|
||||
trace: BindingTrace,
|
||||
resolveFunctionArgumentBodies: ResolveArgumentsMode): ValueArgumentsCheckingResult {
|
||||
val checkingResult = checkValueArgumentTypes(
|
||||
context, context.candidateCall, trace, resolveFunctionArgumentBodies)
|
||||
var resultStatus = checkingResult.status
|
||||
resultStatus = resultStatus.combine(checkReceivers(context, trace))
|
||||
|
||||
return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
|
||||
return ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes)
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceivers(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
ResolutionStatus resultStatus = SUCCESS;
|
||||
ResolvedCall<D> candidateCall = context.candidateCall;
|
||||
private fun <D : CallableDescriptor> checkReceivers(
|
||||
context: CallCandidateResolutionContext<D>,
|
||||
trace: BindingTrace): ResolutionStatus {
|
||||
var resultStatus = SUCCESS
|
||||
val candidateCall = context.candidateCall
|
||||
|
||||
resultStatus = resultStatus.combine(checkReceiverTypeError(context));
|
||||
resultStatus = resultStatus.combine(checkReceiverTypeError(context))
|
||||
|
||||
// Comment about a very special case.
|
||||
// Call 'b.foo(1)' where class 'Foo' has an extension member 'fun B.invoke(Int)' should be checked two times for safe call (in 'checkReceiver'), because
|
||||
@@ -331,194 +297,175 @@ public class CandidateResolver {
|
||||
resultStatus = resultStatus.combine(checkReceiver(
|
||||
context, candidateCall, trace,
|
||||
candidateCall.getResultingDescriptor().getExtensionReceiverParameter(),
|
||||
candidateCall.getExtensionReceiver(), candidateCall.getExplicitReceiverKind().isExtensionReceiver(), false));
|
||||
candidateCall.getExtensionReceiver(), candidateCall.getExplicitReceiverKind().isExtensionReceiver(), false))
|
||||
|
||||
resultStatus = resultStatus.combine(checkReceiver(
|
||||
context, candidateCall, trace,
|
||||
candidateCall.getResultingDescriptor().getDispatchReceiverParameter(), candidateCall.getDispatchReceiver(),
|
||||
candidateCall.getExplicitReceiverKind().isDispatchReceiver(),
|
||||
// for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error
|
||||
context.call instanceof CallForImplicitInvoke));
|
||||
return resultStatus;
|
||||
context.call is CallForImplicitInvoke))
|
||||
return resultStatus
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor, C extends CallResolutionContext<C>> ValueArgumentsCheckingResult checkValueArgumentTypes(
|
||||
@NotNull CallResolutionContext<C> context,
|
||||
@NotNull MutableResolvedCall<D> candidateCall,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull ResolveArgumentsMode resolveFunctionArgumentBodies) {
|
||||
ResolutionStatus resultStatus = SUCCESS;
|
||||
List<JetType> argumentTypes = Lists.newArrayList();
|
||||
MutableDataFlowInfoForArguments infoForArguments = candidateCall.getDataFlowInfoForArguments();
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
|
||||
ValueParameterDescriptor parameterDescriptor = entry.getKey();
|
||||
ResolvedValueArgument resolvedArgument = entry.getValue();
|
||||
private fun <D : CallableDescriptor, C : CallResolutionContext<C>> checkValueArgumentTypes(
|
||||
context: CallResolutionContext<C>,
|
||||
candidateCall: MutableResolvedCall<D>,
|
||||
trace: BindingTrace,
|
||||
resolveFunctionArgumentBodies: ResolveArgumentsMode): ValueArgumentsCheckingResult {
|
||||
var resultStatus = SUCCESS
|
||||
val argumentTypes = Lists.newArrayList<JetType>()
|
||||
val infoForArguments = candidateCall.getDataFlowInfoForArguments()
|
||||
for (entry in candidateCall.getValueArguments().entrySet()) {
|
||||
val parameterDescriptor = entry.getKey()
|
||||
val resolvedArgument = entry.getValue()
|
||||
|
||||
|
||||
for (ValueArgument argument : resolvedArgument.getArguments()) {
|
||||
JetExpression expression = argument.getArgumentExpression();
|
||||
if (expression == null) continue;
|
||||
for (argument in resolvedArgument.getArguments()) {
|
||||
val expression = argument.getArgumentExpression() ?: continue
|
||||
|
||||
JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument);
|
||||
val expectedType = getEffectiveExpectedType(parameterDescriptor, argument)
|
||||
|
||||
CallResolutionContext<?> newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument))
|
||||
.replaceBindingTrace(trace).replaceExpectedType(expectedType);
|
||||
JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(
|
||||
expression, newContext, resolveFunctionArgumentBodies);
|
||||
JetType type = typeInfoForCall.getType();
|
||||
infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo());
|
||||
val newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument)).replaceBindingTrace(trace).replaceExpectedType(expectedType)
|
||||
val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(
|
||||
expression, newContext, resolveFunctionArgumentBodies)
|
||||
val type = typeInfoForCall.type
|
||||
infoForArguments.updateInfo(argument, typeInfoForCall.dataFlowInfo)
|
||||
|
||||
ArgumentMatchStatus matchStatus = ArgumentMatchStatus.SUCCESS;
|
||||
JetType resultingType = type;
|
||||
var matchStatus = ArgumentMatchStatus.SUCCESS
|
||||
var resultingType: JetType? = type
|
||||
if (type == null || (type.isError() && !ErrorUtils.isFunctionPlaceholder(type))) {
|
||||
matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE;
|
||||
matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE
|
||||
}
|
||||
else if (!noExpectedType(expectedType)) {
|
||||
if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) {
|
||||
JetType smartCast = smartCastValueArgumentTypeIfPossible(expression, newContext.expectedType, type, newContext);
|
||||
val smartCast = smartCastValueArgumentTypeIfPossible(expression, newContext.expectedType, type, newContext)
|
||||
if (smartCast == null) {
|
||||
resultStatus = OTHER_ERROR;
|
||||
matchStatus = ArgumentMatchStatus.TYPE_MISMATCH;
|
||||
resultStatus = OTHER_ERROR
|
||||
matchStatus = ArgumentMatchStatus.TYPE_MISMATCH
|
||||
}
|
||||
else {
|
||||
resultingType = smartCast;
|
||||
resultingType = smartCast
|
||||
}
|
||||
}
|
||||
else if (ErrorUtils.containsUninferredParameter(expectedType)) {
|
||||
matchStatus = ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES;
|
||||
matchStatus = ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES
|
||||
}
|
||||
}
|
||||
argumentTypes.add(resultingType);
|
||||
candidateCall.recordArgumentMatchStatus(argument, matchStatus);
|
||||
argumentTypes.add(resultingType)
|
||||
candidateCall.recordArgumentMatchStatus(argument, matchStatus)
|
||||
}
|
||||
}
|
||||
return new ValueArgumentsCheckingResult(resultStatus, argumentTypes);
|
||||
return ValueArgumentsCheckingResult(resultStatus, argumentTypes)
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType smartCastValueArgumentTypeIfPossible(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull JetType expectedType,
|
||||
@NotNull JetType actualType,
|
||||
@NotNull ResolutionContext<?> context
|
||||
) {
|
||||
ExpressionReceiver receiverToCast = new ExpressionReceiver(JetPsiUtil.safeDeparenthesize(expression, false), actualType);
|
||||
Collection<JetType> variants = SmartCastUtils.getSmartCastVariantsExcludingReceiver(context, receiverToCast);
|
||||
for (JetType possibleType : variants) {
|
||||
private fun smartCastValueArgumentTypeIfPossible(
|
||||
expression: JetExpression,
|
||||
expectedType: JetType,
|
||||
actualType: JetType,
|
||||
context: ResolutionContext<*>): JetType? {
|
||||
val receiverToCast = ExpressionReceiver(JetPsiUtil.safeDeparenthesize(expression, false), actualType)
|
||||
val variants = SmartCastUtils.getSmartCastVariantsExcludingReceiver(context, receiverToCast)
|
||||
for (possibleType in variants) {
|
||||
if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType)) {
|
||||
return possibleType;
|
||||
return possibleType
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiverTypeError(
|
||||
@NotNull CallCandidateResolutionContext<D> context
|
||||
) {
|
||||
MutableResolvedCall<D> candidateCall = context.candidateCall;
|
||||
D candidateDescriptor = candidateCall.getCandidateDescriptor();
|
||||
private fun <D : CallableDescriptor> checkReceiverTypeError(
|
||||
context: CallCandidateResolutionContext<D>): ResolutionStatus {
|
||||
val candidateCall = context.candidateCall
|
||||
val candidateDescriptor = candidateCall.getCandidateDescriptor()
|
||||
|
||||
ReceiverParameterDescriptor extensionReceiver = candidateDescriptor.getExtensionReceiverParameter();
|
||||
ReceiverParameterDescriptor dispatchReceiver = candidateDescriptor.getDispatchReceiverParameter();
|
||||
ResolutionStatus status = SUCCESS;
|
||||
val extensionReceiver = candidateDescriptor.getExtensionReceiverParameter()
|
||||
val dispatchReceiver = candidateDescriptor.getDispatchReceiverParameter()
|
||||
var status = SUCCESS
|
||||
// For the expressions like '42.(f)()' where f: String.() -> Unit we'd like to generate a type mismatch error on '1',
|
||||
// not to throw away the candidate, so the following check is skipped.
|
||||
if (!CallResolverUtilPackage.isInvokeCallOnExpressionWithBothReceivers(context.call)) {
|
||||
status = status.combine(checkReceiverTypeError(context, extensionReceiver, candidateCall.getExtensionReceiver()));
|
||||
if (!isInvokeCallOnExpressionWithBothReceivers(context.call)) {
|
||||
status = status.combine(checkReceiverTypeError(context, extensionReceiver, candidateCall.getExtensionReceiver()))
|
||||
}
|
||||
status = status.combine(checkReceiverTypeError(context, dispatchReceiver, candidateCall.getDispatchReceiver()));
|
||||
return status;
|
||||
status = status.combine(checkReceiverTypeError(context, dispatchReceiver, candidateCall.getDispatchReceiver()))
|
||||
return status
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiverTypeError(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@Nullable ReceiverParameterDescriptor receiverParameterDescriptor,
|
||||
@NotNull ReceiverValue receiverArgument
|
||||
) {
|
||||
if (receiverParameterDescriptor == null || !receiverArgument.exists()) return SUCCESS;
|
||||
private fun <D : CallableDescriptor> checkReceiverTypeError(
|
||||
context: CallCandidateResolutionContext<D>,
|
||||
receiverParameterDescriptor: ReceiverParameterDescriptor?,
|
||||
receiverArgument: ReceiverValue): ResolutionStatus {
|
||||
if (receiverParameterDescriptor == null || !receiverArgument.exists()) return SUCCESS
|
||||
|
||||
D candidateDescriptor = context.candidateCall.getCandidateDescriptor();
|
||||
val candidateDescriptor = context.candidateCall.getCandidateDescriptor()
|
||||
|
||||
JetType erasedReceiverType = CallResolverUtilPackage.getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor);
|
||||
val erasedReceiverType = getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor)
|
||||
|
||||
boolean isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability(receiverArgument, erasedReceiverType, context);
|
||||
val isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability(receiverArgument, erasedReceiverType, context)
|
||||
if (!isSubtypeBySmartCast) {
|
||||
return RECEIVER_TYPE_ERROR;
|
||||
return RECEIVER_TYPE_ERROR
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@NotNull ResolvedCall<D> candidateCall,
|
||||
@NotNull BindingTrace trace,
|
||||
@Nullable ReceiverParameterDescriptor receiverParameter,
|
||||
@NotNull ReceiverValue receiverArgument,
|
||||
boolean isExplicitReceiver,
|
||||
boolean implicitInvokeCheck
|
||||
) {
|
||||
if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS;
|
||||
D candidateDescriptor = candidateCall.getCandidateDescriptor();
|
||||
if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS;
|
||||
private fun <D : CallableDescriptor> checkReceiver(
|
||||
context: CallCandidateResolutionContext<D>,
|
||||
candidateCall: ResolvedCall<D>,
|
||||
trace: BindingTrace,
|
||||
receiverParameter: ReceiverParameterDescriptor?,
|
||||
receiverArgument: ReceiverValue,
|
||||
isExplicitReceiver: Boolean,
|
||||
implicitInvokeCheck: Boolean): ResolutionStatus {
|
||||
if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS
|
||||
val candidateDescriptor = candidateCall.getCandidateDescriptor()
|
||||
if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS
|
||||
|
||||
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && CallUtilPackage.isExplicitSafeCall(candidateCall.getCall());
|
||||
boolean isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability(
|
||||
receiverArgument, receiverParameter.getType(), context);
|
||||
val safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.getCall().isExplicitSafeCall()
|
||||
val isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability(
|
||||
receiverArgument, receiverParameter.getType(), context)
|
||||
if (!isSubtypeBySmartCast) {
|
||||
context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument);
|
||||
return OTHER_ERROR;
|
||||
context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument)
|
||||
return OTHER_ERROR
|
||||
}
|
||||
if (!SmartCastUtils.recordSmartCastIfNecessary(receiverArgument, receiverParameter.getType(), context, safeAccess)) {
|
||||
return OTHER_ERROR;
|
||||
return OTHER_ERROR
|
||||
}
|
||||
|
||||
JetType receiverArgumentType = receiverArgument.getType();
|
||||
val receiverArgumentType = receiverArgument.getType()
|
||||
|
||||
BindingContext bindingContext = trace.getBindingContext();
|
||||
val bindingContext = trace.getBindingContext()
|
||||
if (!safeAccess && !receiverParameter.getType().isMarkedNullable() && receiverArgumentType.isMarkedNullable()) {
|
||||
if (!SmartCastUtils.canBeSmartCast(receiverParameter, receiverArgument, context)) {
|
||||
context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck);
|
||||
return UNSAFE_CALL_ERROR;
|
||||
context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck)
|
||||
return UNSAFE_CALL_ERROR
|
||||
}
|
||||
}
|
||||
DataFlowValue receiverValue = DataFlowValueFactory.createDataFlowValue(receiverArgument, bindingContext, context.scope.getContainingDeclaration());
|
||||
val receiverValue = DataFlowValueFactory.createDataFlowValue(receiverArgument, bindingContext, context.scope.getContainingDeclaration())
|
||||
if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) {
|
||||
context.tracing.unnecessarySafeCall(trace, receiverArgumentType);
|
||||
context.tracing.unnecessarySafeCall(trace, receiverArgumentType)
|
||||
}
|
||||
|
||||
context.additionalTypeChecker.checkReceiver(receiverParameter, receiverArgument, safeAccess, context);
|
||||
context.additionalTypeChecker.checkReceiver(receiverParameter, receiverArgument, safeAccess, context)
|
||||
|
||||
return SUCCESS;
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
public class ValueArgumentsCheckingResult {
|
||||
@NotNull
|
||||
public final List<JetType> argumentTypes;
|
||||
@NotNull
|
||||
public final ResolutionStatus status;
|
||||
public inner class ValueArgumentsCheckingResult(public val status: ResolutionStatus, public val argumentTypes: List<JetType>)
|
||||
|
||||
private ValueArgumentsCheckingResult(@NotNull ResolutionStatus status, @NotNull List<JetType> argumentTypes) {
|
||||
this.status = status;
|
||||
this.argumentTypes = argumentTypes;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkGenericBoundsInAFunctionCall(
|
||||
@NotNull List<JetTypeProjection> jetTypeArguments,
|
||||
@NotNull List<JetType> typeArguments,
|
||||
@NotNull CallableDescriptor functionDescriptor,
|
||||
@NotNull TypeSubstitutor substitutor,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||
for (int i = 0; i < Math.min(typeParameters.size(), jetTypeArguments.size()); i++) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||
JetType typeArgument = typeArguments.get(i);
|
||||
JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
|
||||
private fun checkGenericBoundsInAFunctionCall(
|
||||
jetTypeArguments: List<JetTypeProjection>,
|
||||
typeArguments: List<JetType>,
|
||||
functionDescriptor: CallableDescriptor,
|
||||
substitutor: TypeSubstitutor,
|
||||
trace: BindingTrace) {
|
||||
val typeParameters = functionDescriptor.getTypeParameters()
|
||||
for (i in 0..Math.min(typeParameters.size(), jetTypeArguments.size()) - 1) {
|
||||
val typeParameterDescriptor = typeParameters.get(i)
|
||||
val typeArgument = typeArguments.get(i)
|
||||
val typeReference = jetTypeArguments.get(i).getTypeReference()
|
||||
if (typeReference != null) {
|
||||
DescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace);
|
||||
DescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user