Wrong trace in call resolver fixed

This commit is contained in:
Andrey Breslav
2011-09-06 15:54:46 +04:00
parent d6336d9ca5
commit 67925fcda4
4 changed files with 32 additions and 25 deletions
@@ -22,6 +22,7 @@ public class AnnotationResolver {
private final BindingTrace trace; private final BindingTrace trace;
public AnnotationResolver(JetSemanticServices semanticServices, BindingTrace trace) { public AnnotationResolver(JetSemanticServices semanticServices, BindingTrace trace) {
this.trace = trace; this.trace = trace;
} }
@@ -27,16 +27,12 @@ import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
*/ */
public class CallResolver { public class CallResolver {
private final TypeResolver typeResolver;
private final JetTypeInferrer typeInferrer; private final JetTypeInferrer typeInferrer;
private final JetSemanticServices semanticServices; private final JetSemanticServices semanticServices;
private final ClassDescriptorResolver classDescriptorResolver;
private final OverloadingConflictResolver overloadingConflictResolver; private final OverloadingConflictResolver overloadingConflictResolver;
public CallResolver(JetSemanticServices semanticServices, BindingTrace trace, JetTypeInferrer typeInferrer) { public CallResolver(JetSemanticServices semanticServices, JetTypeInferrer typeInferrer) {
this.typeInferrer = typeInferrer; this.typeInferrer = typeInferrer;
this.typeResolver = new TypeResolver(semanticServices, trace, true);
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
this.semanticServices = semanticServices; this.semanticServices = semanticServices;
this.overloadingConflictResolver = new OverloadingConflictResolver(semanticServices); this.overloadingConflictResolver = new OverloadingConflictResolver(semanticServices);
} }
@@ -114,7 +110,7 @@ public class CallResolver {
} }
JetTypeReference typeReference = expression.getTypeReference(); JetTypeReference typeReference = expression.getTypeReference();
assert typeReference != null; assert typeReference != null;
JetType constructedType = typeResolver.resolveType(scope, typeReference); JetType constructedType = new TypeResolver(semanticServices, trace, true).resolveType(scope, typeReference);
DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor(); DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof ClassDescriptor) { if (declarationDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
@@ -360,7 +356,7 @@ public class CallResolver {
} }
} }
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate); checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, temporaryTrace);
Map<TypeConstructor, TypeProjection> substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments); Map<TypeConstructor, TypeProjection> substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
D substitutedFunctionDescriptor = (D) candidate.substitute(TypeSubstitutor.create(substitutionContext)); D substitutedFunctionDescriptor = (D) candidate.substitute(TypeSubstitutor.create(substitutionContext));
@@ -544,7 +540,7 @@ public class CallResolver {
return result; return result;
} }
public void checkGenericBoundsInAFunctionCall(List<JetTypeProjection> jetTypeArguments, List<JetType> typeArguments, CallableDescriptor functionDescriptor) { public void checkGenericBoundsInAFunctionCall(List<JetTypeProjection> jetTypeArguments, List<JetType> typeArguments, CallableDescriptor functionDescriptor, BindingTrace trace) {
Map<TypeConstructor, TypeProjection> context = Maps.newHashMap(); Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters(); List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
@@ -559,7 +555,7 @@ public class CallResolver {
JetType typeArgument = typeArguments.get(i); JetType typeArgument = typeArguments.get(i);
JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference(); JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
assert typeReference != null; assert typeReference != null;
classDescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor); semanticServices.getClassDescriptorResolver(trace).checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor);
} }
} }
@@ -155,12 +155,15 @@ public class JetTypeInferrer {
private final JetSemanticServices semanticServices; private final JetSemanticServices semanticServices;
private final JetFlowInformationProvider flowInformationProvider; private final JetFlowInformationProvider flowInformationProvider;
private final CallResolver callResolver;
private final Map<JetPattern, DataFlowInfo> patternsToDataFlowInfo = Maps.newHashMap(); private final Map<JetPattern, DataFlowInfo> patternsToDataFlowInfo = Maps.newHashMap();
private final Map<JetPattern, List<VariableDescriptor>> patternsToBoundVariableLists = Maps.newHashMap(); private final Map<JetPattern, List<VariableDescriptor>> patternsToBoundVariableLists = Maps.newHashMap();
public JetTypeInferrer(@NotNull JetFlowInformationProvider flowInformationProvider, @NotNull JetSemanticServices semanticServices) { public JetTypeInferrer(@NotNull JetFlowInformationProvider flowInformationProvider, @NotNull JetSemanticServices semanticServices) {
this.semanticServices = semanticServices; this.semanticServices = semanticServices;
this.flowInformationProvider = flowInformationProvider; this.flowInformationProvider = flowInformationProvider;
this.callResolver = new CallResolver(semanticServices, this);
} }
public Services getServices(@NotNull BindingTrace trace) { public Services getServices(@NotNull BindingTrace trace) {
@@ -170,7 +173,6 @@ public class JetTypeInferrer {
public class Services { public class Services {
private final BindingTrace trace; private final BindingTrace trace;
private final CompileTimeConstantResolver compileTimeConstantResolver; private final CompileTimeConstantResolver compileTimeConstantResolver;
private final CallResolver callResolver;
private final TypeInferrerVisitor typeInferrerVisitor; private final TypeInferrerVisitor typeInferrerVisitor;
private final TypeInferrerVisitorWithNamespaces typeInferrerVisitorWithNamespaces; private final TypeInferrerVisitorWithNamespaces typeInferrerVisitorWithNamespaces;
@@ -180,7 +182,6 @@ public class JetTypeInferrer {
this.compileTimeConstantResolver = new CompileTimeConstantResolver(semanticServices, trace); this.compileTimeConstantResolver = new CompileTimeConstantResolver(semanticServices, trace);
this.typeInferrerVisitor = new TypeInferrerVisitor(); this.typeInferrerVisitor = new TypeInferrerVisitor();
this.typeInferrerVisitorWithNamespaces = new TypeInferrerVisitorWithNamespaces(); this.typeInferrerVisitorWithNamespaces = new TypeInferrerVisitorWithNamespaces();
this.callResolver = new CallResolver(semanticServices, trace, JetTypeInferrer.this);
} }
public TypeInferrerVisitorWithWritableScope newTypeInferrerVisitorWithWritableScope(WritableScope scope) { public TypeInferrerVisitorWithWritableScope newTypeInferrerVisitorWithWritableScope(WritableScope scope) {
@@ -1830,7 +1831,7 @@ public class JetTypeInferrer {
@Nullable @Nullable
private JetType checkIterableConvention(@NotNull JetType type, @NotNull JetExpression loopRange, TypeInferenceContext context) { private JetType checkIterableConvention(@NotNull JetType type, @NotNull JetExpression loopRange, TypeInferenceContext context) {
ASTNode reportErrorsOn = loopRange.getNode(); ASTNode reportErrorsOn = loopRange.getNode();
OverloadResolutionResult<FunctionDescriptor> iteratorResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, type, "iterator", Collections.<JetType>emptyList()); OverloadResolutionResult<FunctionDescriptor> iteratorResolutionResult = callResolver.resolveExactSignature(context.scope, type, "iterator", Collections.<JetType>emptyList());
if (iteratorResolutionResult.isSuccess()) { if (iteratorResolutionResult.isSuccess()) {
FunctionDescriptor iteratorFunction = iteratorResolutionResult.getDescriptor(); FunctionDescriptor iteratorFunction = iteratorResolutionResult.getDescriptor();
@@ -1852,7 +1853,7 @@ public class JetTypeInferrer {
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange, hasNextFunctionSupported ? hasNextFunction : hasNextProperty); context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange, hasNextFunctionSupported ? hasNextFunction : hasNextProperty);
} }
OverloadResolutionResult<FunctionDescriptor> nextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.<JetType>emptyList()); OverloadResolutionResult<FunctionDescriptor> nextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.<JetType>emptyList());
if (nextResolutionResult.isAmbiguity()) { if (nextResolutionResult.isAmbiguity()) {
context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression"); context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression");
} else if (nextResolutionResult.isNothing()) { } else if (nextResolutionResult.isNothing()) {
@@ -1879,7 +1880,7 @@ public class JetTypeInferrer {
@Nullable @Nullable
private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, TypeInferenceContext context) { private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, TypeInferenceContext context) {
OverloadResolutionResult<FunctionDescriptor> hasNextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.<JetType>emptyList()); OverloadResolutionResult<FunctionDescriptor> hasNextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.<JetType>emptyList());
if (hasNextResolutionResult.isAmbiguity()) { if (hasNextResolutionResult.isAmbiguity()) {
context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression"); context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression");
} else if (hasNextResolutionResult.isNothing()) { } else if (hasNextResolutionResult.isNothing()) {
@@ -2080,13 +2081,13 @@ public class JetTypeInferrer {
@Nullable @Nullable
private JetType getSelectorReturnType(@Nullable JetType receiverType, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) { private JetType getSelectorReturnType(@Nullable JetType receiverType, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
if (selectorExpression instanceof JetCallExpression) { if (selectorExpression instanceof JetCallExpression) {
return context.services.callResolver.resolveCall(context.trace, context.scope, receiverType, (JetCallExpression) selectorExpression, context.expectedType); return callResolver.resolveCall(context.trace, context.scope, receiverType, (JetCallExpression) selectorExpression, context.expectedType);
} }
else if (selectorExpression instanceof JetSimpleNameExpression) { else if (selectorExpression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression; JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression;
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
VariableDescriptor variableDescriptor = context.services.callResolver.resolveSimpleProperty(temporaryTrace, context.scope, receiverType, nameExpression, context.expectedType); VariableDescriptor variableDescriptor = callResolver.resolveSimpleProperty(temporaryTrace, context.scope, receiverType, nameExpression, context.expectedType);
if (variableDescriptor != null) { if (variableDescriptor != null) {
temporaryTrace.commit(); temporaryTrace.commit();
return context.services.checkEnrichedType(variableDescriptor.getOutType(), nameExpression, context); return context.services.checkEnrichedType(variableDescriptor.getOutType(), nameExpression, context);
@@ -2117,7 +2118,7 @@ public class JetTypeInferrer {
@Override @Override
public JetType visitCallExpression(JetCallExpression expression, TypeInferenceContext context) { public JetType visitCallExpression(JetCallExpression expression, TypeInferenceContext context) {
JetType expressionType = context.services.callResolver.resolveCall(context.trace, context.scope, null, expression, context.expectedType); JetType expressionType = callResolver.resolveCall(context.trace, context.scope, null, expression, context.expectedType);
return context.services.checkType(expressionType, expression, context); return context.services.checkType(expressionType, expression, context);
} }
@@ -2153,7 +2154,7 @@ public class JetTypeInferrer {
JetType receiverType = getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope)); JetType receiverType = getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
if (receiverType == null) return null; if (receiverType == null) return null;
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName( FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace, context.trace,
context.scope, context.scope,
CallMaker.makeCall(expression), CallMaker.makeCall(expression),
@@ -2228,7 +2229,7 @@ public class JetTypeInferrer {
String name = "equals"; String name = "equals";
if (right != null) { if (right != null) {
JetType leftType = safeGetType(left, context.replaceScope(context.scope)); JetType leftType = safeGetType(left, context.replaceScope(context.scope));
OverloadResolutionResult<FunctionDescriptor> resolutionResult = context.services.callResolver.resolveExactSignature( OverloadResolutionResult<FunctionDescriptor> resolutionResult = callResolver.resolveExactSignature(
context.scope, leftType, "equals", context.scope, leftType, "equals",
Collections.singletonList(JetStandardClasses.getNullableAnyType())); Collections.singletonList(JetStandardClasses.getNullableAnyType()));
if (resolutionResult.isSuccess()) { if (resolutionResult.isSuccess()) {
@@ -2303,7 +2304,7 @@ public class JetTypeInferrer {
private void checkInExpression(JetSimpleNameExpression operationSign, JetExpression left, JetExpression right, TypeInferenceContext context) { private void checkInExpression(JetSimpleNameExpression operationSign, JetExpression left, JetExpression right, TypeInferenceContext context) {
String name = "contains"; String name = "contains";
JetType receiverType = context.services.safeGetType(context.scope, right, NO_EXPECTED_TYPE); JetType receiverType = context.services.safeGetType(context.scope, right, NO_EXPECTED_TYPE);
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName( FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace, context.trace,
context.scope, context.scope,
CallMaker.makeCall(operationSign, Collections.singletonList(left)), CallMaker.makeCall(operationSign, Collections.singletonList(left)),
@@ -2371,7 +2372,7 @@ public class JetTypeInferrer {
JetType receiverType = getType(arrayExpression, context.replaceScope(context.scope)); JetType receiverType = getType(arrayExpression, context.replaceScope(context.scope));
if (receiverType != null) { if (receiverType != null) {
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName( FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace, context.trace,
context.scope, context.scope,
CallMaker.makeCall(expression, expression.getIndexExpressions()), CallMaker.makeCall(expression, expression.getIndexExpressions()),
@@ -2389,7 +2390,7 @@ public class JetTypeInferrer {
@Nullable @Nullable
protected JetType getTypeForBinaryCall(JetScope scope, String name, TypeInferenceContext context, JetBinaryExpression binaryExpression) { protected JetType getTypeForBinaryCall(JetScope scope, String name, TypeInferenceContext context, JetBinaryExpression binaryExpression) {
JetType leftType = getType(binaryExpression.getLeft(), context.replaceScope(scope)); JetType leftType = getType(binaryExpression.getLeft(), context.replaceScope(scope));
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName( FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace, context.trace,
scope, scope,
CallMaker.makeCall(binaryExpression), CallMaker.makeCall(binaryExpression),
@@ -2635,12 +2636,12 @@ public class JetTypeInferrer {
// //
Call call = CallMaker.makeCall(arrayAccessExpression, rightHandSide); Call call = CallMaker.makeCall(arrayAccessExpression, rightHandSide);
// // TODO : nasty hack: effort is duplicated // // TODO : nasty hack: effort is duplicated
// context.services.callResolver.resolveCallWithGivenName( // callResolver.resolveCallWithGivenName(
// scope, // scope,
// call, // call,
// arrayAccessExpression, // arrayAccessExpression,
// "set", arrayAccessExpression.getArrayExpression(), NO_EXPECTED_TYPE); // "set", arrayAccessExpression.getArrayExpression(), NO_EXPECTED_TYPE);
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName( FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
context.trace, context.trace,
scope, scope,
call, call,
@@ -0,0 +1,9 @@
open class Foo {}
open class Bar {}
fun <T : Bar, T1> foo(x : Int) {}
fun <T1, T : Foo> foo(x : Long) {}
fun f(): Unit {
foo<<error>Int</error>, Int>(1)
}