Test data fixed
Useless code removed Some naming refactored
This commit is contained in:
@@ -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<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
|
||||
// return OverloadResolutionResult.nameNotFound();
|
||||
// }
|
||||
//
|
||||
// @NotNull
|
||||
// @Override
|
||||
// public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> 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<JetType> typeArguments,
|
||||
// @NotNull Map<String, JetType> 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<JetType> typeArguments,
|
||||
// @NotNull List<JetType> positionedValueArgumentTypes);
|
||||
//
|
||||
// /**
|
||||
// * @return true if the domain is empty
|
||||
// */
|
||||
// boolean isEmpty();
|
||||
//}
|
||||
@@ -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.<FunctionDescriptor>emptyList());
|
||||
}
|
||||
public static OverloadResolutionResult singleFunctionArgumentMismatch(FunctionDescriptor functionDescriptor) {
|
||||
return new OverloadResolutionResult(Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH, Collections.singleton(functionDescriptor));
|
||||
}
|
||||
|
||||
public static OverloadResolutionResult ambiguity(Collection<FunctionDescriptor> functionDescriptors) {
|
||||
return new OverloadResolutionResult(Code.AMBIGUITY, functionDescriptors);
|
||||
}
|
||||
|
||||
private final Collection<FunctionDescriptor> functionDescriptors;
|
||||
|
||||
private final Code resultCode;
|
||||
|
||||
public OverloadResolutionResult(@NotNull Code resultCode, @NotNull Collection<FunctionDescriptor> functionDescriptors) {
|
||||
this.functionDescriptors = functionDescriptors;
|
||||
this.resultCode = resultCode;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<FunctionDescriptor> 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<FunctionDescriptor> functionDescriptors) {
|
||||
return new OverloadResolutionResult(resultCode, functionDescriptors);
|
||||
}
|
||||
}
|
||||
@@ -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<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
|
||||
// OverloadResolutionResult resolutionResult = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes);
|
||||
// if (!resolutionResult.isAmbiguity() && !resolutionResult.isSuccess()) return resolutionResult;
|
||||
//
|
||||
// Collection<FunctionDescriptor> possiblyApplicableFunctions = resolutionResult.getFunctionDescriptors();
|
||||
//
|
||||
// if (possiblyApplicableFunctions.isEmpty()) {
|
||||
// return OverloadResolutionResult.nameNotFound(); // TODO : it may be found, only the number of params did not match
|
||||
// }
|
||||
//
|
||||
// List<FunctionDescriptor> applicable = new ArrayList<FunctionDescriptor>();
|
||||
//
|
||||
// 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<ValueParameterDescriptor> 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<FunctionDescriptor> maximallySpecific = new ArrayList<FunctionDescriptor>();
|
||||
// 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<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
|
||||
// throw new UnsupportedOperationException(); // TODO
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// private boolean moreSpecific(FunctionDescriptor f, FunctionDescriptor g) {
|
||||
// List<ValueParameterDescriptor> fParams = f.getValueParameters();
|
||||
// List<ValueParameterDescriptor> 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;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -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();
|
||||
// }
|
||||
//}
|
||||
@@ -236,7 +236,7 @@ public class CallResolver {
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Nullable
|
||||
private <Descriptor extends CallableDescriptor, Task extends ResolutionTask<Descriptor>> Descriptor performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull Task task, @NotNull TracingStrategy tracing) {
|
||||
private <Descriptor extends CallableDescriptor> Descriptor performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask<Descriptor> task, @NotNull TracingStrategy tracing) {
|
||||
Map<Descriptor, Descriptor> successfulCandidates = Maps.newLinkedHashMap();
|
||||
Set<Descriptor> failedCandidates = Sets.newLinkedHashSet();
|
||||
Set<Descriptor> 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<FunctionDescriptor> task, @NotNull TracingStrategy tracing) {
|
||||
Map<FunctionDescriptor, FunctionDescriptor> successfulCandidates = Maps.newLinkedHashMap();
|
||||
Set<FunctionDescriptor> failedCandidates = Sets.newLinkedHashSet();
|
||||
Set<FunctionDescriptor> dirtyCandidates = Sets.newLinkedHashSet();
|
||||
Map<FunctionDescriptor, ConstraintSystem.Solution> solutions = Maps.newHashMap();
|
||||
Map<FunctionDescriptor, TemporaryBindingTrace> 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<ValueArgument, ValueParameterDescriptor> 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.<ValueParameterDescriptor>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<ValueArgument, ValueParameterDescriptor> 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<JetTypeProjection> 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<JetType> typeArguments = new ArrayList<JetType>();
|
||||
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<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
||||
for (ValueParameterDescriptor valueParameterDescriptor : substitutedFunctionDescriptor.getValueParameters()) {
|
||||
parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
||||
}
|
||||
|
||||
Function<ValueParameterDescriptor, ValueParameterDescriptor> mapFunction = new Function<ValueParameterDescriptor, ValueParameterDescriptor>() {
|
||||
@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 <Descriptor extends CallableDescriptor> boolean checkReceiver(ResolutionTask<Descriptor> 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<JetType> parameterTypes) {
|
||||
public OverloadResolutionResult<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @Nullable JetType receiverType, @NotNull String name, @NotNull List<JetType> parameterTypes) {
|
||||
List<FunctionDescriptor> result = findCandidatesByExactSignature(scope, receiverType, name, parameterTypes);
|
||||
return listToOverloadResolutionResult(result);
|
||||
}
|
||||
@@ -748,7 +584,7 @@ public class CallResolver {
|
||||
return found;
|
||||
}
|
||||
|
||||
private OverloadResolutionResult listToOverloadResolutionResult(List<FunctionDescriptor> result) {
|
||||
private OverloadResolutionResult<FunctionDescriptor> listToOverloadResolutionResult(List<FunctionDescriptor> result) {
|
||||
if (result.isEmpty()) {
|
||||
return OverloadResolutionResult.nameNotFound();
|
||||
}
|
||||
@@ -878,66 +714,6 @@ public class CallResolver {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private static class FunctionTaskPrioritizer1 {
|
||||
|
||||
private List<ResolutionTask<FunctionDescriptor>> computePrioritizedTasks(JetScope scope, JetType receiverType, Call call, String name) {
|
||||
List<ResolutionTask<FunctionDescriptor>> result = Lists.newArrayList();
|
||||
if (receiverType != null) {
|
||||
Collection<FunctionDescriptor> extensionFunctions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
|
||||
for (Iterator<FunctionDescriptor> iterator = extensionFunctions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor functionDescriptor = iterator.next();
|
||||
if (functionDescriptor.getReceiverType() == null) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
List<FunctionDescriptor> nonlocals = Lists.newArrayList();
|
||||
List<FunctionDescriptor> locals = Lists.newArrayList();
|
||||
TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
Set<FunctionDescriptor> 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<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
|
||||
for (Iterator<FunctionDescriptor> iterator = functions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor functionDescriptor = iterator.next();
|
||||
if (functionDescriptor.getReceiverType() != null) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
addConstrtuctors(scope, name, functions);
|
||||
|
||||
List<FunctionDescriptor> nonlocals = Lists.newArrayList();
|
||||
List<FunctionDescriptor> 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<ResolutionTask<FunctionDescriptor>> result, JetType receiverType, Call call, Collection<FunctionDescriptor> candidates) {
|
||||
if (candidates.isEmpty()) return;
|
||||
result.add(new ResolutionTask<FunctionDescriptor>(candidates, receiverType, call));
|
||||
}
|
||||
|
||||
private void addConstrtuctors(JetScope scope, String name, Collection<FunctionDescriptor> 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;
|
||||
|
||||
|
||||
@@ -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<D> {
|
||||
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 <D> OverloadResolutionResult<D> success(@NotNull D functionDescriptor) {
|
||||
return new OverloadResolutionResult<D>(Code.SUCCESS, Collections.singleton(functionDescriptor));
|
||||
}
|
||||
|
||||
public static <D> OverloadResolutionResult<D> nameNotFound() {
|
||||
return new OverloadResolutionResult<D>(Code.NAME_NOT_FOUND, Collections.<D>emptyList());
|
||||
}
|
||||
public static <D> OverloadResolutionResult<D> singleFunctionArgumentMismatch(D functionDescriptor) {
|
||||
return new OverloadResolutionResult<D>(Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH, Collections.singleton(functionDescriptor));
|
||||
}
|
||||
|
||||
public static <D> OverloadResolutionResult<D> ambiguity(Collection<D> functionDescriptors) {
|
||||
return new OverloadResolutionResult<D>(Code.AMBIGUITY, functionDescriptors);
|
||||
}
|
||||
|
||||
private final Collection<D> descriptors;
|
||||
|
||||
private final Code resultCode;
|
||||
|
||||
public OverloadResolutionResult(@NotNull Code resultCode, @NotNull Collection<D> descriptors) {
|
||||
this.descriptors = descriptors;
|
||||
this.resultCode = resultCode;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<D> 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<D> newContents(@NotNull Collection<D> functionDescriptors) {
|
||||
return new OverloadResolutionResult<D>(resultCode, functionDescriptors);
|
||||
}
|
||||
}
|
||||
@@ -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.<JetType>emptyList());
|
||||
OverloadResolutionResult<FunctionDescriptor> iteratorResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, type, "iterator", Collections.<JetType>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.<JetType>emptyList());
|
||||
OverloadResolutionResult<FunctionDescriptor> nextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.<JetType>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.<JetType>emptyList());
|
||||
OverloadResolutionResult<FunctionDescriptor> hasNextResolutionResult = context.services.callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.<JetType>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<FunctionDescriptor> 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);
|
||||
|
||||
@@ -23,7 +23,7 @@ class WithPC1(a : Int) {
|
||||
|
||||
this(s : String) : this(1) {}
|
||||
|
||||
this(b : Char) : this<error>("", 2)</error> {}
|
||||
this(b : Char) : <error>this("", 2)</error> {}
|
||||
|
||||
this(b : Byte) : this(""), <error>this(1)</error> {}
|
||||
}
|
||||
|
||||
@@ -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<String>) {
|
||||
|
||||
@@ -62,7 +63,7 @@ namespace null_safety {
|
||||
command<warning>?.</warning>equals1(null)
|
||||
|
||||
val c = Command()
|
||||
c<warning>?.</warning>equals(null)
|
||||
c<warning>?.</warning>equals2(null)
|
||||
|
||||
if (command == null) 1
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class A() {
|
||||
val z = foo()
|
||||
}
|
||||
|
||||
fun foo() : Unit {
|
||||
fun foo1() : Unit {
|
||||
<error>this</error>
|
||||
this<error>@a</error>
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ fun test(l : java.util.List<Int>) {
|
||||
Collections.emptyList()
|
||||
|
||||
Collections.singleton<Int>(1) : Set<Int>?
|
||||
Collections.singleton<Int><error>(1.0)</error>
|
||||
Collections.singleton<Int>(<error>1.0</error>)
|
||||
|
||||
<error>List</error><Int>
|
||||
|
||||
|
||||
@@ -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<JetType> 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<FunctionDescriptor> functions = typeInferrerServices.getCallResolver().resolveExactSignature(classDescriptor.getMemberScope(typeArguments), null, name, parameterTypeList);
|
||||
for (FunctionDescriptor function : functions.getDescriptors()) {
|
||||
List<ValueParameterDescriptor> unsubstitutedValueParameters = function.getValueParameters();
|
||||
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
|
||||
ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i);
|
||||
|
||||
Reference in New Issue
Block a user