KT-3563 Compiler requiring java.io.File, and it's unclear why
#KT-3563 fixed
This commit is contained in:
@@ -36,10 +36,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.FilteringScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
@@ -47,6 +44,7 @@ import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.DONT_CARE;
|
||||
|
||||
public class DescriptorUtils {
|
||||
|
||||
|
||||
@@ -20,10 +20,7 @@ import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
import org.jetbrains.jet.lang.psi.CallKey;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
@@ -38,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
||||
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -153,4 +151,38 @@ public class CallResolverUtil {
|
||||
if (!(callElement instanceof JetExpression)) return null;
|
||||
return CallKey.create(context.call.getCallType(), (JetExpression) callElement);
|
||||
}
|
||||
|
||||
public static boolean checkArgumentCannotBeReceiver(
|
||||
@NotNull JetType receiverArgumentType,
|
||||
@NotNull CallableDescriptor descriptor
|
||||
) {
|
||||
JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType);
|
||||
|
||||
JetType erasedReceiverType = getErasedReceiverType(descriptor);
|
||||
if (erasedReceiverType == null) return true;
|
||||
|
||||
return !JetTypeChecker.INSTANCE.isSubtypeOf(effectiveReceiverArgumentType, erasedReceiverType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetType getErasedReceiverType(@NotNull CallableDescriptor descriptor) {
|
||||
ReceiverParameterDescriptor receiverDescriptor = descriptor.getReceiverParameter();
|
||||
ReceiverParameterDescriptor expectedThisObjectDescriptor = descriptor.getExpectedThisObject();
|
||||
JetType receiverType = receiverDescriptor != null ? receiverDescriptor.getType() :
|
||||
expectedThisObjectDescriptor != null ? expectedThisObjectDescriptor.getType() : null;
|
||||
if (receiverType == null) return null;
|
||||
|
||||
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
|
||||
if (typeParameter.getTypeConstructor().equals(receiverType.getConstructor())) {
|
||||
return typeParameter.getUpperBoundsAsType();
|
||||
}
|
||||
}
|
||||
List<TypeProjection> fakeTypeArguments = Lists.newArrayList();
|
||||
for (TypeProjection typeProjection : receiverType.getArguments()) {
|
||||
fakeTypeArguments.add(new TypeProjection(typeProjection.getProjectionKind(), DONT_CARE));
|
||||
}
|
||||
return new JetTypeImpl(
|
||||
receiverType.getAnnotations(), receiverType.getConstructor(), receiverType.isNullable(),
|
||||
fakeTypeArguments, receiverType.getMemberScope());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
|
||||
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
|
||||
import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
@@ -660,39 +661,43 @@ public class CandidateResolver {
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(
|
||||
CallCandidateResolutionContext<D> context, ResolvedCall<D> candidateCall, BindingTrace trace,
|
||||
ReceiverParameterDescriptor receiverParameter, ReceiverValue receiverArgument,
|
||||
boolean isExplicitReceiver, boolean implicitInvokeCheck) {
|
||||
@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;
|
||||
|
||||
BindingContext bindingContext = trace.getBindingContext();
|
||||
JetType receiverArgumentType = receiverArgument.getType();
|
||||
JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType);
|
||||
D candidateDescriptor = candidateCall.getCandidateDescriptor();
|
||||
if (!argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) {
|
||||
|
||||
ResolutionStatus result = SUCCESS;
|
||||
if (receiverParameter != null && receiverArgument.exists()) {
|
||||
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall();
|
||||
JetType receiverArgumentType = receiverArgument.getType();
|
||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext);
|
||||
if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) {
|
||||
|
||||
context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck);
|
||||
result = UNSAFE_CALL_ERROR;
|
||||
if (CallResolverUtil.checkArgumentCannotBeReceiver(effectiveReceiverArgumentType, candidateDescriptor)
|
||||
&& !(candidateDescriptor instanceof ExpressionAsFunctionDescriptor)) {
|
||||
return STRONG_ERROR;
|
||||
}
|
||||
else {
|
||||
JetType effectiveReceiverArgumentType = safeAccess
|
||||
? TypeUtils.makeNotNullable(receiverArgumentType)
|
||||
: receiverArgumentType;
|
||||
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(),
|
||||
candidateCall.getCandidateDescriptor().getTypeParameters()) &&
|
||||
!argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) {
|
||||
context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument);
|
||||
result = OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext);
|
||||
if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) {
|
||||
context.tracing.unnecessarySafeCall(trace, receiverArgumentType);
|
||||
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) {
|
||||
context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
BindingContext bindingContext = trace.getBindingContext();
|
||||
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall();
|
||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext);
|
||||
if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) {
|
||||
|
||||
context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck);
|
||||
return UNSAFE_CALL_ERROR;
|
||||
}
|
||||
DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext);
|
||||
if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) {
|
||||
context.tracing.unnecessarySafeCall(trace, receiverArgumentType);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
private static class ValueArgumentsCheckingResult {
|
||||
|
||||
Reference in New Issue
Block a user