KT-3563 Compiler requiring java.io.File, and it's unclear why

#KT-3563 fixed
This commit is contained in:
Svetlana Isakova
2013-06-13 20:27:31 +04:00
parent 3cf133bff7
commit 342e9ebe7a
11 changed files with 156 additions and 42 deletions
@@ -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 {