Test data fixed

Useless code removed
Some naming refactored
This commit is contained in:
Andrey Breslav
2011-08-30 20:20:43 +04:00
parent 496549cab8
commit 2a67c4a591
12 changed files with 111 additions and 615 deletions
@@ -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);
+1 -1
View File
@@ -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> {}
}
+2 -1
View File
@@ -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
}
+1 -1
View File
@@ -16,7 +16,7 @@ class A() {
val z = foo()
}
fun foo() : Unit {
fun foo1() : Unit {
<error>this</error>
this<error>@a</error>
}
+1 -1
View File
@@ -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);