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
|
@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();
|
Map<Descriptor, Descriptor> successfulCandidates = Maps.newLinkedHashMap();
|
||||||
Set<Descriptor> failedCandidates = Sets.newLinkedHashSet();
|
Set<Descriptor> failedCandidates = Sets.newLinkedHashSet();
|
||||||
Set<Descriptor> dirtyCandidates = 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) {
|
private <Descriptor extends CallableDescriptor> boolean checkReceiver(ResolutionTask<Descriptor> task, TracingStrategy tracing, Descriptor candidate, TemporaryBindingTrace temporaryTrace) {
|
||||||
if (!checkReceiverAbsence(task, tracing, candidate, temporaryTrace)) return false;
|
if (!checkReceiverAbsence(task, tracing, candidate, temporaryTrace)) return false;
|
||||||
JetType receiverType = task.getReceiverType();
|
JetType receiverType = task.getReceiverType();
|
||||||
@@ -704,7 +540,7 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@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);
|
List<FunctionDescriptor> result = findCandidatesByExactSignature(scope, receiverType, name, parameterTypes);
|
||||||
return listToOverloadResolutionResult(result);
|
return listToOverloadResolutionResult(result);
|
||||||
}
|
}
|
||||||
@@ -748,7 +584,7 @@ public class CallResolver {
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OverloadResolutionResult listToOverloadResolutionResult(List<FunctionDescriptor> result) {
|
private OverloadResolutionResult<FunctionDescriptor> listToOverloadResolutionResult(List<FunctionDescriptor> result) {
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
return OverloadResolutionResult.nameNotFound();
|
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 static class Flag {
|
||||||
private boolean 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.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
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.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
|
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
|
||||||
@@ -1777,9 +1778,9 @@ public class JetTypeInferrer {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JetType checkIterableConvention(@NotNull JetType type, @NotNull ASTNode reportErrorsOn, TypeInferenceContext context) {
|
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()) {
|
if (iteratorResolutionResult.isSuccess()) {
|
||||||
JetType iteratorType = iteratorResolutionResult.getFunctionDescriptor().getReturnType();
|
JetType iteratorType = iteratorResolutionResult.getDescriptor().getReturnType();
|
||||||
boolean hasNextFunctionSupported = checkHasNextFunctionSupport(reportErrorsOn, iteratorType, context);
|
boolean hasNextFunctionSupported = checkHasNextFunctionSupport(reportErrorsOn, iteratorType, context);
|
||||||
boolean hasNextPropertySupported = checkHasNextPropertySupport(reportErrorsOn, iteratorType, context);
|
boolean hasNextPropertySupported = checkHasNextPropertySupport(reportErrorsOn, iteratorType, context);
|
||||||
if (hasNextFunctionSupported && hasNextPropertySupported && !ErrorUtils.isErrorType(iteratorType)) {
|
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");
|
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()) {
|
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()) {
|
||||||
context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method");
|
context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method");
|
||||||
} else {
|
} else {
|
||||||
return nextResolutionResult.getFunctionDescriptor().getReturnType();
|
return nextResolutionResult.getDescriptor().getReturnType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1810,13 +1811,13 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkHasNextFunctionSupport(@NotNull ASTNode reportErrorsOn, @NotNull JetType iteratorType, TypeInferenceContext context) {
|
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()) {
|
if (hasNextResolutionResult.isAmbiguity()) {
|
||||||
context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().hasNext()' is ambiguous for this expression");
|
context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().hasNext()' is ambiguous for this expression");
|
||||||
} else if (hasNextResolutionResult.isNothing()) {
|
} else if (hasNextResolutionResult.isNothing()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
JetType hasNextReturnType = hasNextResolutionResult.getFunctionDescriptor().getReturnType();
|
JetType hasNextReturnType = hasNextResolutionResult.getDescriptor().getReturnType();
|
||||||
if (!isBoolean(hasNextReturnType)) {
|
if (!isBoolean(hasNextReturnType)) {
|
||||||
context.trace.getErrorHandler().genericError(reportErrorsOn, "The 'iterator().hasNext()' method of the loop range must return Boolean, but returns " + 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) {
|
if (leftType != null) {
|
||||||
JetType rightType = getType(right, context.replaceScope(context.scope));
|
JetType rightType = getType(right, context.replaceScope(context.scope));
|
||||||
if (rightType != null) {
|
if (rightType != null) {
|
||||||
OverloadResolutionResult resolutionResult = context.services.callResolver.resolveExactSignature(
|
OverloadResolutionResult<FunctionDescriptor> resolutionResult = context.services.callResolver.resolveExactSignature(
|
||||||
context.scope, leftType, "equals",
|
context.scope, leftType, "equals",
|
||||||
Collections.singletonList(JetStandardClasses.getNullableAnyType()));
|
Collections.singletonList(JetStandardClasses.getNullableAnyType()));
|
||||||
if (resolutionResult.isSuccess()) {
|
if (resolutionResult.isSuccess()) {
|
||||||
FunctionDescriptor equals = resolutionResult.getFunctionDescriptor();
|
FunctionDescriptor equals = resolutionResult.getDescriptor();
|
||||||
context.trace.record(REFERENCE_TARGET, operationSign, equals);
|
context.trace.record(REFERENCE_TARGET, operationSign, equals);
|
||||||
if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) {
|
if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) {
|
||||||
ensureNonemptyIntersectionOfOperandTypes(expression, context);
|
ensureNonemptyIntersectionOfOperandTypes(expression, context);
|
||||||
@@ -2139,7 +2140,7 @@ public class JetTypeInferrer {
|
|||||||
else {
|
else {
|
||||||
if (resolutionResult.isAmbiguity()) {
|
if (resolutionResult.isAmbiguity()) {
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
for (FunctionDescriptor functionDescriptor : resolutionResult.getFunctionDescriptors()) {
|
for (FunctionDescriptor functionDescriptor : resolutionResult.getDescriptors()) {
|
||||||
stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
|
stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
|
||||||
}
|
}
|
||||||
context.trace.getErrorHandler().genericError(operationSign.getNode(), "Ambiguous function: " + stringBuilder);
|
context.trace.getErrorHandler().genericError(operationSign.getNode(), "Ambiguous function: " + stringBuilder);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class WithPC1(a : Int) {
|
|||||||
|
|
||||||
this(s : String) : this(1) {}
|
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> {}
|
this(b : Byte) : this(""), <error>this(1)</error> {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace null_safety {
|
|||||||
|
|
||||||
fun Any.equals(other : Any?) : Boolean
|
fun Any.equals(other : Any?) : Boolean
|
||||||
fun Any?.equals1(other : Any?) : Boolean
|
fun Any?.equals1(other : Any?) : Boolean
|
||||||
|
fun Any.equals2(other : Any?) : Boolean
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ namespace null_safety {
|
|||||||
command<warning>?.</warning>equals1(null)
|
command<warning>?.</warning>equals1(null)
|
||||||
|
|
||||||
val c = Command()
|
val c = Command()
|
||||||
c<warning>?.</warning>equals(null)
|
c<warning>?.</warning>equals2(null)
|
||||||
|
|
||||||
if (command == null) 1
|
if (command == null) 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class A() {
|
|||||||
val z = foo()
|
val z = foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foo() : Unit {
|
fun foo1() : Unit {
|
||||||
<error>this</error>
|
<error>this</error>
|
||||||
this<error>@a</error>
|
this<error>@a</error>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ fun test(l : java.util.List<Int>) {
|
|||||||
Collections.emptyList()
|
Collections.emptyList()
|
||||||
|
|
||||||
Collections.singleton<Int>(1) : Set<Int>?
|
Collections.singleton<Int>(1) : Set<Int>?
|
||||||
Collections.singleton<Int><error>(1.0)</error>
|
Collections.singleton<Int>(<error>1.0</error>)
|
||||||
|
|
||||||
<error>List</error><Int>
|
<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.cfg.JetFlowInformationProvider;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
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.lang.types.*;
|
||||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||||
|
|
||||||
@@ -106,8 +106,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
|
|||||||
List<JetType> parameterTypeList = Arrays.asList(parameterType);
|
List<JetType> parameterTypeList = Arrays.asList(parameterType);
|
||||||
JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext(), JetFlowInformationProvider.NONE);
|
JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext(), JetFlowInformationProvider.NONE);
|
||||||
|
|
||||||
OverloadResolutionResult functions = typeInferrerServices.getCallResolver().resolveExactSignature(classDescriptor.getMemberScope(typeArguments), null, name, parameterTypeList);
|
OverloadResolutionResult<FunctionDescriptor> functions = typeInferrerServices.getCallResolver().resolveExactSignature(classDescriptor.getMemberScope(typeArguments), null, name, parameterTypeList);
|
||||||
for (FunctionDescriptor function : functions.getFunctionDescriptors()) {
|
for (FunctionDescriptor function : functions.getDescriptors()) {
|
||||||
List<ValueParameterDescriptor> unsubstitutedValueParameters = function.getValueParameters();
|
List<ValueParameterDescriptor> unsubstitutedValueParameters = function.getValueParameters();
|
||||||
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
|
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
|
||||||
ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i);
|
ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i);
|
||||||
|
|||||||
Reference in New Issue
Block a user