diff --git a/idea/src/org/jetbrains/jet/lang/resolve/OverloadDomain.java b/idea/src/org/jetbrains/jet/lang/resolve/OverloadDomain.java deleted file mode 100644 index 5d193d64afb..00000000000 --- a/idea/src/org/jetbrains/jet/lang/resolve/OverloadDomain.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.jetbrains.jet.lang.resolve; - -/** - * @author abreslav - */ -//public interface OverloadDomain { -// -// OverloadDomain EMPTY = new OverloadDomain() { -// @NotNull -// @Override -// public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List typeArguments, @NotNull Map valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) { -// return OverloadResolutionResult.nameNotFound(); -// } -// -// @NotNull -// @Override -// public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) { -// return OverloadResolutionResult.nameNotFound(); -// } -// -// @Override -// public boolean isEmpty() { -// return true; -// } -// }; -// -// /** -// * @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code -// */ -// @NotNull -// OverloadResolutionResult getFunctionDescriptorForNamedArguments( -// @NotNull List typeArguments, -// @NotNull Map valueArgumentTypes, -// @Nullable JetType functionLiteralArgumentType); -// -// /** -// * @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code -// */ -// @NotNull -// OverloadResolutionResult getFunctionDescriptorForPositionedArguments( -// @NotNull List typeArguments, -// @NotNull List positionedValueArgumentTypes); -// -// /** -// * @return true if the domain is empty -// */ -// boolean isEmpty(); -//} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolutionResult.java b/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolutionResult.java deleted file mode 100644 index 191f6943a42..00000000000 --- a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolutionResult.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.jetbrains.jet.lang.resolve; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; - -import java.util.Collection; -import java.util.Collections; - -/** -* @author abreslav -*/ -public class OverloadResolutionResult { - public enum Code { - SUCCESS(true), - NAME_NOT_FOUND(false), - SINGLE_FUNCTION_ARGUMENT_MISMATCH(false), - AMBIGUITY(false); - - private final boolean success; - - Code(boolean success) { - this.success = success; - } - - boolean isSuccess() { - return success; - } - - } - - public static OverloadResolutionResult success(@NotNull FunctionDescriptor functionDescriptor) { - return new OverloadResolutionResult(Code.SUCCESS, Collections.singleton(functionDescriptor)); - } - - public static OverloadResolutionResult nameNotFound() { - return new OverloadResolutionResult(Code.NAME_NOT_FOUND, Collections.emptyList()); - } - public static OverloadResolutionResult singleFunctionArgumentMismatch(FunctionDescriptor functionDescriptor) { - return new OverloadResolutionResult(Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH, Collections.singleton(functionDescriptor)); - } - - public static OverloadResolutionResult ambiguity(Collection functionDescriptors) { - return new OverloadResolutionResult(Code.AMBIGUITY, functionDescriptors); - } - - private final Collection functionDescriptors; - - private final Code resultCode; - - public OverloadResolutionResult(@NotNull Code resultCode, @NotNull Collection functionDescriptors) { - this.functionDescriptors = functionDescriptors; - this.resultCode = resultCode; - - } - - @NotNull - public Collection getFunctionDescriptors() { - return functionDescriptors; - } - - @NotNull - public FunctionDescriptor getFunctionDescriptor() { - assert singleFunction(); - return functionDescriptors.iterator().next(); - } - - @NotNull - public Code getResultCode() { - return resultCode; - } - - public boolean isSuccess() { - return resultCode.isSuccess(); - } - - public boolean singleFunction() { - return isSuccess() || resultCode == Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH; - } - - public boolean isNothing() { - return resultCode == Code.NAME_NOT_FOUND; - } - - public boolean isAmbiguity() { - return resultCode == Code.AMBIGUITY; - } - - public OverloadResolutionResult newContents(@NotNull Collection functionDescriptors) { - return new OverloadResolutionResult(resultCode, functionDescriptors); - } -} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java deleted file mode 100644 index dfa5eab8c44..00000000000 --- a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.jetbrains.jet.lang.resolve; - -/** - * @author abreslav - */ -//public class OverloadResolver { -// -// private final JetTypeChecker typeChecker; -// -// public OverloadResolver(JetTypeChecker typeChecker) { -// this.typeChecker = typeChecker; -// } -// -// @NotNull -// public OverloadDomain getOverloadDomain(@Nullable JetType receiverType, @NotNull JetScope outerScope, @NotNull String name) { -// // TODO : extension lookup -// JetScope scope = receiverType == null ? outerScope : new ScopeWithReceiver(outerScope, receiverType, typeChecker); -// -// final FunctionGroup functionGroup = scope.getFunctionGroup(name); -// -// return getOverloadDomain(receiverType, functionGroup); -// } -// -// @NotNull -// public OverloadDomain getOverloadDomain(@Nullable final JetType receiverType, @NotNull final FunctionGroup functionGroup) { -// if (functionGroup.isEmpty()) { -// return OverloadDomain.EMPTY; -// } -// -// return new OverloadDomain() { -// @NotNull -// @Override -// public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull final List typeArguments, @NotNull List positionedValueArgumentTypes) { -// OverloadResolutionResult resolutionResult = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes); -// if (!resolutionResult.isAmbiguity() && !resolutionResult.isSuccess()) return resolutionResult; -// -// Collection possiblyApplicableFunctions = resolutionResult.getFunctionDescriptors(); -// -// if (possiblyApplicableFunctions.isEmpty()) { -// return OverloadResolutionResult.nameNotFound(); // TODO : it may be found, only the number of params did not match -// } -// -// List applicable = new ArrayList(); -// -// descLoop: -// for (FunctionDescriptor descriptor : possiblyApplicableFunctions) { -// // ASSERT: type arguments are figured out and substituted by this time!!! -// assert descriptor.getTypeParameters().isEmpty(); -// -// if (receiverType != null) { -// // ASSERT : either the receiver in not present or we are in a scope with no top-level functions -// JetType functionReceiverType = descriptor.getReceiverType(); -// if (functionReceiverType != null) { -// functionReceiverType = TypeUtils.makeNullable(functionReceiverType); // Too look things up in T for T?, and later check receiver's nullability -// if (!typeChecker.isSubtypeOf(receiverType, functionReceiverType)) { -// continue; -// } -// } -// } -// else if (descriptor.getReceiverType() != null) { -// continue; -// } -// -// List parameters = descriptor.getValueParameters(); -// if (parameters.size() >= positionedValueArgumentTypes.size()) { -// // possibly, some default values -// // possibly, nothing passed to a vararg -// // possibly, a single value passed to a vararg -// // possibly an array/list/etc passed as a whole vararg -// for (int i = 0, positionedValueArgumentTypesSize = positionedValueArgumentTypes.size(); i < positionedValueArgumentTypesSize; i++) { -// JetType argumentType = positionedValueArgumentTypes.get(i); -// JetType parameterType = parameters.get(i).getOutType(); -// // TODO : handle vararg cases here -// if (!typeChecker.isConvertibleTo(argumentType, parameterType)) { -// continue descLoop; -// } -// } -// } else { -// // vararg -// int nonVarargs = parameters.size() - 1; -// for (int i = 0; i < nonVarargs; i++) { -// JetType argumentType = positionedValueArgumentTypes.get(i); -// JetType parameterType = parameters.get(i).getOutType(); -// if (!typeChecker.isConvertibleTo(argumentType, parameterType)) { -// continue descLoop; -// } -// } -// JetType varArgType = parameters.get(nonVarargs).getOutType(); -// for (int i = nonVarargs, args = positionedValueArgumentTypes.size(); i < args; i++) { -// JetType argumentType = positionedValueArgumentTypes.get(i); -// if (!typeChecker.isConvertibleTo(argumentType, varArgType)) { -// continue descLoop; -// } -// } -// } -// applicable.add(descriptor); -// } -// -// if (applicable.size() == 0) { -// if (resolutionResult.singleFunction()) { -// return OverloadResolutionResult.singleFunctionArgumentMismatch(resolutionResult.getFunctionDescriptor()); -// } -// return OverloadResolutionResult.nameNotFound(); -// } else if (applicable.size() == 1) { -// return OverloadResolutionResult.success(applicable.get(0)); -// } else { -// // TODO : varargs -// -// List maximallySpecific = new ArrayList(); -// meLoop: -// for (FunctionDescriptor me : applicable) { -// for (FunctionDescriptor other : applicable) { -// if (other == me) continue; -// if (!moreSpecific(me, other) || moreSpecific(other, me)) continue meLoop; -// } -// maximallySpecific.add(me); -// } -// if (maximallySpecific.isEmpty()) { -// return OverloadResolutionResult.ambiguity(applicable); -// } -// if (maximallySpecific.size() == 1) { -// return OverloadResolutionResult.success(maximallySpecific.get(0)); -// } -// throw new UnsupportedOperationException(); -// } -// } -// -// @Override -// public boolean isEmpty() { -// return functionGroup.isEmpty(); -// } -// -// @NotNull -// @Override -// public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List typeArguments, @NotNull Map valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) { -// throw new UnsupportedOperationException(); // TODO -// } -// }; -// } -// -// private boolean moreSpecific(FunctionDescriptor f, FunctionDescriptor g) { -// List fParams = f.getValueParameters(); -// List gParams = g.getValueParameters(); -// -// int fSize = fParams.size(); -// if (fSize != gParams.size()) return false; -// for (int i = 0; i < fSize; i++) { -// JetType fParamType = fParams.get(i).getOutType(); -// JetType gParamType = gParams.get(i).getOutType(); -// -// // TODO : maybe isSubtypeOf is sufficient? -// if (!typeChecker.isConvertibleTo(fParamType, gParamType)) { -// return false; -// } -// } -// return true; -// } -// -//} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java b/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java deleted file mode 100644 index 3648e075c74..00000000000 --- a/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java +++ /dev/null @@ -1,74 +0,0 @@ -//package org.jetbrains.jet.lang.resolve; -// -//import org.jetbrains.annotations.NotNull; -//import org.jetbrains.jet.lang.descriptors.*; -//import org.jetbrains.jet.lang.types.JetType; -//import org.jetbrains.jet.lang.types.JetTypeChecker; -// -///** -// * @author abreslav -// */ -//public class ScopeWithReceiver extends JetScopeImpl { -// -// private final JetType receiverType; -// private final JetScope outerScope; -// private final JetTypeChecker typeChecker; -// -// public ScopeWithReceiver(@NotNull JetScope outerScope, @NotNull JetType receiverType, @NotNull JetTypeChecker typeChecker) { -// this.outerScope = outerScope; -// this.receiverType = receiverType; -// this.typeChecker = typeChecker; -// } -// -// @NotNull -// @Override -// public FunctionGroup getFunctionGroup(@NotNull String name) { -// WritableFunctionGroup result = new WritableFunctionGroup(name); -// -// result.addAllFunctions(receiverType.getMemberScope().getFunctionGroup(name)); -// result.addAllFunctions(outerScope.getFunctionGroup(name)); -// -// return result; -// } -// -// @Override -// public ClassifierDescriptor getClassifier(@NotNull String name) { -// return receiverType.getMemberScope().getClassifier(name); -// } -// -// @Override -// public VariableDescriptor getVariable(@NotNull String name) { -// VariableDescriptor variable = receiverType.getMemberScope().getVariable(name); -// if (variable != null) { -// return variable; -// } -// variable = outerScope.getVariable(name); -// if (variable instanceof PropertyDescriptor) { -// PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variable; -// JetType receiverType = propertyDescriptor.getReceiverType(); -// // TODO : in case of type arguments, substitute the receiver type first -// if (receiverType != null -// && typeChecker.isSubtypeOf(receiverType, receiverType)) { -// return variable; -// } -// } -// return null; -// } -// -// @Override -// public NamespaceDescriptor getNamespace(@NotNull String name) { -// return receiverType.getMemberScope().getNamespace(name); -// } -// -// @NotNull -// @Override -// public JetType getThisType() { -// return receiverType; -// } -// -// @NotNull -// @Override -// public DeclarationDescriptor getContainingDeclaration() { -// return outerScope.getContainingDeclaration(); -// } -//} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index ae9f7a0508c..ca71c36983e 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -236,7 +236,7 @@ public class CallResolver { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @Nullable - private > Descriptor performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull Task task, @NotNull TracingStrategy tracing) { + private Descriptor performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task, @NotNull TracingStrategy tracing) { Map successfulCandidates = Maps.newLinkedHashMap(); Set failedCandidates = Sets.newLinkedHashSet(); Set dirtyCandidates = Sets.newLinkedHashSet(); @@ -404,170 +404,6 @@ public class CallResolver { }; } - @Nullable - private FunctionDescriptor oldPerformResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task, @NotNull TracingStrategy tracing) { - Map successfulCandidates = Maps.newLinkedHashMap(); - Set failedCandidates = Sets.newLinkedHashSet(); - Set dirtyCandidates = Sets.newLinkedHashSet(); - Map solutions = Maps.newHashMap(); - Map traces = Maps.newHashMap(); - - for (FunctionDescriptor candidate : task.getCandidates()) { - TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace); - traces.put(candidate, temporaryTrace); - JetTypeInferrer.Services temporaryServices = typeInferrer.getServices(temporaryTrace); - - tracing.bindReference(temporaryTrace, candidate); - - if (ErrorUtils.isError(candidate)) { - successfulCandidates.put(candidate, candidate); - continue; - } - - Flag dirty = new Flag(false); - - Map argumentsToParameters = Maps.newHashMap(); - boolean error = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(task, tracing, candidate, temporaryTrace, argumentsToParameters); - - if (error) { - failedCandidates.add(candidate); - continue; - } - - if (task.getTypeArguments().isEmpty()) { - if (candidate.getTypeParameters().isEmpty()) { - if (checkValueArgumentTypes(scope, temporaryServices, argumentsToParameters, dirty, Functions.identity()) - && checkReceiver(task, tracing, candidate, temporaryTrace)) { - successfulCandidates.put(candidate, candidate); - } - else { - failedCandidates.add(candidate); - } - } - else { - // Type argument inference - - ConstraintSystem constraintSystem = new ConstraintSystem(); - for (TypeParameterDescriptor typeParameterDescriptor : candidate.getTypeParameters()) { - constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO - } - - for (Map.Entry entry : argumentsToParameters.entrySet()) { - ValueArgument valueArgument = entry.getKey(); - ValueParameterDescriptor valueParameterDescriptor = entry.getValue(); - - JetExpression expression = valueArgument.getArgumentExpression(); - // TODO : more attempts, with different expected types - JetType type = temporaryServices.getType(scope, expression, NO_EXPECTED_TYPE); - if (type != null) { - constraintSystem.addSubtypingConstraint(type, valueParameterDescriptor.getOutType()); - } - else { - dirty.setValue(true); - } - } - - checkReceiverAbsence(task, tracing, candidate, temporaryTrace); - // Error is already reported if something is missing - JetType receiverType = task.getReceiverType(); - JetType candidateReceiverType = candidate.getReceiverType(); - if (receiverType != null && candidateReceiverType != null) { - constraintSystem.addSubtypingConstraint(receiverType, candidateReceiverType); - } - - if (expectedType != NO_EXPECTED_TYPE) { - constraintSystem.addSubtypingConstraint(candidate.getReturnType(), expectedType); - } - - ConstraintSystem.Solution solution = constraintSystem.solve(); - solutions.put(candidate, solution); - if (solution.isSuccessful()) { - FunctionDescriptor substitute = candidate.substitute(solution.getSubstitutor()); - assert substitute != null; - successfulCandidates.put(candidate, substitute); - } - else { - tracing.reportOverallResolutionError(temporaryTrace, "Type inference failed"); - failedCandidates.add(candidate); - } - } - } - else { - // Explicit type arguments passed - - final List jetTypeArguments = task.getTypeArguments(); - - for (JetTypeProjection typeArgument : jetTypeArguments) { - if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) { - temporaryTrace.getErrorHandler().genericError(typeArgument.getNode(), "Projections are not allowed on type parameters for methods"); // TODO : better positioning - } - } - - if (candidate.getTypeParameters().size() == jetTypeArguments.size()) { - List typeArguments = new ArrayList(); - for (JetTypeProjection projection : jetTypeArguments) { - // TODO : check that there's no projection - JetTypeReference typeReference = projection.getTypeReference(); - if (typeReference != null) { - typeArguments.add(new TypeResolver(semanticServices, temporaryTrace, true).resolveType(scope, typeReference)); - } - } - - checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate); - - FunctionDescriptor substitutedFunctionDescriptor = FunctionDescriptorUtil.substituteFunctionDescriptor(typeArguments, candidate); - - assert substitutedFunctionDescriptor != null; - final Map parameterMap = Maps.newHashMap(); - for (ValueParameterDescriptor valueParameterDescriptor : substitutedFunctionDescriptor.getValueParameters()) { - parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor); - } - - Function mapFunction = new Function() { - @Override - public ValueParameterDescriptor apply(ValueParameterDescriptor input) { - return parameterMap.get(input.getOriginal()); - } - }; - if (checkValueArgumentTypes(scope, temporaryServices, argumentsToParameters, dirty, mapFunction) - && checkReceiver(task, tracing, substitutedFunctionDescriptor, temporaryTrace)) { - successfulCandidates.put(candidate, substitutedFunctionDescriptor); - } - else { - failedCandidates.add(candidate); - } - } - else { - failedCandidates.add(candidate); - tracing.reportWrongTypeArguments(temporaryTrace, "Number of type arguments does not match " + DescriptorRenderer.TEXT.render(candidate)); - } - } - - if (dirty.getValue()) { - dirtyCandidates.add(candidate); - } - } - - FunctionDescriptor functionDescriptor = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates, dirtyCandidates, traces); - if (functionDescriptor == null) { - for (ValueArgument valueArgument : task.getValueArguments()) { - JetExpression argumentExpression = valueArgument.getArgumentExpression(); - if (argumentExpression != null) { - typeInferrer.getServices(trace).getType(scope, argumentExpression, NO_EXPECTED_TYPE); - } - } - - for (JetExpression expression : task.getFunctionLiteralArguments()) { - typeInferrer.getServices(trace).getType(scope, expression, NO_EXPECTED_TYPE); - } - - for (JetTypeProjection typeProjection : task.getTypeArguments()) { - new TypeResolver(semanticServices, trace, true).resolveType(scope, typeProjection.getTypeReference()); - } - } - return functionDescriptor; - } - private boolean checkReceiver(ResolutionTask task, TracingStrategy tracing, Descriptor candidate, TemporaryBindingTrace temporaryTrace) { if (!checkReceiverAbsence(task, tracing, candidate, temporaryTrace)) return false; JetType receiverType = task.getReceiverType(); @@ -704,7 +540,7 @@ public class CallResolver { } @NotNull - public OverloadResolutionResult resolveExactSignature(@NotNull JetScope scope, @Nullable JetType receiverType, @NotNull String name, @NotNull List parameterTypes) { + public OverloadResolutionResult resolveExactSignature(@NotNull JetScope scope, @Nullable JetType receiverType, @NotNull String name, @NotNull List parameterTypes) { List result = findCandidatesByExactSignature(scope, receiverType, name, parameterTypes); return listToOverloadResolutionResult(result); } @@ -748,7 +584,7 @@ public class CallResolver { return found; } - private OverloadResolutionResult listToOverloadResolutionResult(List result) { + private OverloadResolutionResult listToOverloadResolutionResult(List result) { if (result.isEmpty()) { return OverloadResolutionResult.nameNotFound(); } @@ -878,66 +714,6 @@ public class CallResolver { } }; - - private static class FunctionTaskPrioritizer1 { - - private List> computePrioritizedTasks(JetScope scope, JetType receiverType, Call call, String name) { - List> result = Lists.newArrayList(); - if (receiverType != null) { - Collection extensionFunctions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors()); - for (Iterator iterator = extensionFunctions.iterator(); iterator.hasNext(); ) { - FunctionDescriptor functionDescriptor = iterator.next(); - if (functionDescriptor.getReceiverType() == null) { - iterator.remove(); - } - } - List nonlocals = Lists.newArrayList(); - List locals = Lists.newArrayList(); - TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals); - - Set members = Sets.newHashSet(receiverType.getMemberScope().getFunctionGroup(name).getFunctionDescriptors()); - addConstrtuctors(receiverType.getMemberScope(), name, members); - - addTask(result, receiverType, call, locals); - addTask(result, null, call, members); - addTask(result, receiverType, call, nonlocals); - } - else { - Collection functions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors()); - for (Iterator iterator = functions.iterator(); iterator.hasNext(); ) { - FunctionDescriptor functionDescriptor = iterator.next(); - if (functionDescriptor.getReceiverType() != null) { - iterator.remove(); - } - } - addConstrtuctors(scope, name, functions); - - List nonlocals = Lists.newArrayList(); - List locals = Lists.newArrayList(); - TaskPrioritizer.splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals); - - addTask(result, receiverType, call, locals); - - addTask(result, receiverType, call, nonlocals); - } - return result; - } - - private void addTask(List> result, JetType receiverType, Call call, Collection candidates) { - if (candidates.isEmpty()) return; - result.add(new ResolutionTask(candidates, receiverType, call)); - } - - private void addConstrtuctors(JetScope scope, String name, Collection functions) { - ClassifierDescriptor classifier = scope.getClassifier(name); - if (classifier instanceof ClassDescriptor && !ErrorUtils.isError(classifier.getTypeConstructor())) { - ClassDescriptor classDescriptor = (ClassDescriptor) classifier; - functions.addAll(classDescriptor.getConstructors().getFunctionDescriptors()); - } - } - - } - private static class Flag { private boolean flag; diff --git a/idea/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResult.java b/idea/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResult.java new file mode 100644 index 00000000000..9ca7641757f --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResult.java @@ -0,0 +1,90 @@ +package org.jetbrains.jet.lang.resolve.calls; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Collections; + +/** +* @author abreslav +*/ +public class OverloadResolutionResult { + public enum Code { + SUCCESS(true), + NAME_NOT_FOUND(false), + SINGLE_FUNCTION_ARGUMENT_MISMATCH(false), + AMBIGUITY(false); + + private final boolean success; + + Code(boolean success) { + this.success = success; + } + + boolean isSuccess() { + return success; + } + + } + + public static OverloadResolutionResult success(@NotNull D functionDescriptor) { + return new OverloadResolutionResult(Code.SUCCESS, Collections.singleton(functionDescriptor)); + } + + public static OverloadResolutionResult nameNotFound() { + return new OverloadResolutionResult(Code.NAME_NOT_FOUND, Collections.emptyList()); + } + public static OverloadResolutionResult singleFunctionArgumentMismatch(D functionDescriptor) { + return new OverloadResolutionResult(Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH, Collections.singleton(functionDescriptor)); + } + + public static OverloadResolutionResult ambiguity(Collection functionDescriptors) { + return new OverloadResolutionResult(Code.AMBIGUITY, functionDescriptors); + } + + private final Collection descriptors; + + private final Code resultCode; + + public OverloadResolutionResult(@NotNull Code resultCode, @NotNull Collection descriptors) { + this.descriptors = descriptors; + this.resultCode = resultCode; + + } + + @NotNull + public Collection getDescriptors() { + return descriptors; + } + + @NotNull + public D getDescriptor() { + assert singleDescriptor(); + return descriptors.iterator().next(); + } + + @NotNull + public Code getResultCode() { + return resultCode; + } + + public boolean isSuccess() { + return resultCode.isSuccess(); + } + + public boolean singleDescriptor() { + return isSuccess() || resultCode == Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH; + } + + public boolean isNothing() { + return resultCode == Code.NAME_NOT_FOUND; + } + + public boolean isAmbiguity() { + return resultCode == Code.AMBIGUITY; + } + + public OverloadResolutionResult newContents(@NotNull Collection functionDescriptors) { + return new OverloadResolutionResult(resultCode, functionDescriptors); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index b72986fa133..4761631e13e 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -19,6 +19,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResult; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver; import org.jetbrains.jet.lang.resolve.constants.ErrorValue; @@ -1777,9 +1778,9 @@ public class JetTypeInferrer { @Nullable private JetType checkIterableConvention(@NotNull JetType type, @NotNull ASTNode reportErrorsOn, TypeInferenceContext context) { - OverloadResolutionResult iteratorResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, type, "iterator", Collections.emptyList()); + OverloadResolutionResult iteratorResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, type, "iterator", Collections.emptyList()); if (iteratorResolutionResult.isSuccess()) { - JetType iteratorType = iteratorResolutionResult.getFunctionDescriptor().getReturnType(); + JetType iteratorType = iteratorResolutionResult.getDescriptor().getReturnType(); boolean hasNextFunctionSupported = checkHasNextFunctionSupport(reportErrorsOn, iteratorType, context); boolean hasNextPropertySupported = checkHasNextPropertySupport(reportErrorsOn, iteratorType, context); if (hasNextFunctionSupported && hasNextPropertySupported && !ErrorUtils.isErrorType(iteratorType)) { @@ -1790,13 +1791,13 @@ public class JetTypeInferrer { context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property"); } - OverloadResolutionResult nextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.emptyList()); + OverloadResolutionResult nextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.emptyList()); if (nextResolutionResult.isAmbiguity()) { context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression"); } else if (nextResolutionResult.isNothing()) { context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method"); } else { - return nextResolutionResult.getFunctionDescriptor().getReturnType(); + return nextResolutionResult.getDescriptor().getReturnType(); } } else { @@ -1810,13 +1811,13 @@ public class JetTypeInferrer { } private boolean checkHasNextFunctionSupport(@NotNull ASTNode reportErrorsOn, @NotNull JetType iteratorType, TypeInferenceContext context) { - OverloadResolutionResult hasNextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.emptyList()); + OverloadResolutionResult hasNextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.emptyList()); if (hasNextResolutionResult.isAmbiguity()) { context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().hasNext()' is ambiguous for this expression"); } else if (hasNextResolutionResult.isNothing()) { return false; } else { - JetType hasNextReturnType = hasNextResolutionResult.getFunctionDescriptor().getReturnType(); + JetType hasNextReturnType = hasNextResolutionResult.getDescriptor().getReturnType(); if (!isBoolean(hasNextReturnType)) { context.trace.getErrorHandler().genericError(reportErrorsOn, "The 'iterator().hasNext()' method of the loop range must return Boolean, but returns " + hasNextReturnType); } @@ -2126,11 +2127,11 @@ public class JetTypeInferrer { if (leftType != null) { JetType rightType = getType(right, context.replaceScope(context.scope)); if (rightType != null) { - OverloadResolutionResult resolutionResult = context.services.callResolver.resolveExactSignature( + OverloadResolutionResult resolutionResult = context.services.callResolver.resolveExactSignature( context.scope, leftType, "equals", Collections.singletonList(JetStandardClasses.getNullableAnyType())); if (resolutionResult.isSuccess()) { - FunctionDescriptor equals = resolutionResult.getFunctionDescriptor(); + FunctionDescriptor equals = resolutionResult.getDescriptor(); context.trace.record(REFERENCE_TARGET, operationSign, equals); if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) { ensureNonemptyIntersectionOfOperandTypes(expression, context); @@ -2139,7 +2140,7 @@ public class JetTypeInferrer { else { if (resolutionResult.isAmbiguity()) { StringBuilder stringBuilder = new StringBuilder(); - for (FunctionDescriptor functionDescriptor : resolutionResult.getFunctionDescriptors()) { + for (FunctionDescriptor functionDescriptor : resolutionResult.getDescriptors()) { stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); } context.trace.getErrorHandler().genericError(operationSign.getNode(), "Ambiguous function: " + stringBuilder); diff --git a/idea/testData/checker/Constructors.jet b/idea/testData/checker/Constructors.jet index 13a787da063..1e964eac399 100644 --- a/idea/testData/checker/Constructors.jet +++ b/idea/testData/checker/Constructors.jet @@ -23,7 +23,7 @@ class WithPC1(a : Int) { this(s : String) : this(1) {} - this(b : Char) : this("", 2) {} + this(b : Char) : this("", 2) {} this(b : Byte) : this(""), this(1) {} } diff --git a/idea/testData/checker/ExtensionFunctions.jet b/idea/testData/checker/ExtensionFunctions.jet index 669b51c0cbe..75df8a0f4c0 100644 --- a/idea/testData/checker/ExtensionFunctions.jet +++ b/idea/testData/checker/ExtensionFunctions.jet @@ -47,6 +47,7 @@ namespace null_safety { fun Any.equals(other : Any?) : Boolean fun Any?.equals1(other : Any?) : Boolean + fun Any.equals2(other : Any?) : Boolean fun main(args: Array) { @@ -62,7 +63,7 @@ namespace null_safety { command?.equals1(null) val c = Command() - c?.equals(null) + c?.equals2(null) if (command == null) 1 } diff --git a/idea/testData/checker/QualifiedThis.jet b/idea/testData/checker/QualifiedThis.jet index 21113c22f0d..37a1f0d90d3 100644 --- a/idea/testData/checker/QualifiedThis.jet +++ b/idea/testData/checker/QualifiedThis.jet @@ -16,7 +16,7 @@ class A() { val z = foo() } -fun foo() : Unit { +fun foo1() : Unit { this this@a } diff --git a/idea/testData/checker/ResolveToJava.jet b/idea/testData/checker/ResolveToJava.jet index cc954743a82..215e9561ffe 100644 --- a/idea/testData/checker/ResolveToJava.jet +++ b/idea/testData/checker/ResolveToJava.jet @@ -22,7 +22,7 @@ fun test(l : java.util.List) { Collections.emptyList() Collections.singleton(1) : Set? - Collections.singleton(1.0) + Collections.singleton(1.0) List diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java index 1e88c2ea377..c5b220f1309 100644 --- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -15,7 +15,7 @@ import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingTraceContext; -import org.jetbrains.jet.lang.resolve.OverloadResolutionResult; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResult; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.parsing.JetParsingTest; @@ -106,8 +106,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase { List parameterTypeList = Arrays.asList(parameterType); JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext(), JetFlowInformationProvider.NONE); - OverloadResolutionResult functions = typeInferrerServices.getCallResolver().resolveExactSignature(classDescriptor.getMemberScope(typeArguments), null, name, parameterTypeList); - for (FunctionDescriptor function : functions.getFunctionDescriptors()) { + OverloadResolutionResult functions = typeInferrerServices.getCallResolver().resolveExactSignature(classDescriptor.getMemberScope(typeArguments), null, name, parameterTypeList); + for (FunctionDescriptor function : functions.getDescriptors()) { List unsubstitutedValueParameters = function.getValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i);