Small fixes for error reporting in the IDE for overloads and constructors

This commit is contained in:
Andrey Breslav
2011-03-21 18:25:01 +03:00
parent baa0bc5ba9
commit fe84695b85
4 changed files with 78 additions and 23 deletions
@@ -24,6 +24,11 @@ public interface OverloadDomain {
public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
return null;
}
@Override
public boolean isEmpty() {
return true;
}
};
/**
@@ -47,4 +52,9 @@ public interface OverloadDomain {
FunctionDescriptor getFunctionDescriptorForPositionedArguments(
@NotNull List<JetType> typeArguments,
@NotNull List<JetType> positionedValueArgumentTypes);
/**
* @return true if the domain is empty
*/
boolean isEmpty();
}
@@ -109,6 +109,11 @@ public class OverloadResolver {
}
}
@Override
public boolean isEmpty() {
return functionGroup.isEmpty();
}
@Override
public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
throw new UnsupportedOperationException(); // TODO
@@ -87,8 +87,8 @@ public class JavaDescriptorResolver {
Collections.<Attribute>emptyList(), // TODO
false);
constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()));
constructors.addFunction(
constructorDescriptor);
constructors.addFunction(constructorDescriptor);
semanticServices.getTrace().recordDeclarationResolution(constructor, constructorDescriptor);
}
semanticServices.getTrace().recordDeclarationResolution(psiClass, classDescriptor);
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.types;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -98,13 +99,6 @@ public class JetTypeInferrer {
return expression;
}
@Nullable
private FunctionDescriptor lookupFunction(JetScope scope, JetReferenceExpression reference, String name, JetType receiverType, List<JetType> argumentTypes, boolean reportUnresolved) {
OverloadDomain overloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(receiverType, scope, name);
overloadDomain = wrapForTracing(overloadDomain, reference, reportUnresolved);
return overloadDomain.getFunctionDescriptorForPositionedArguments(Collections.<JetType>emptyList(), argumentTypes);
}
@Nullable
private List<JetType> getTypes(JetScope scope, List<JetExpression> indexExpressions) {
List<JetType> argumentTypes = new ArrayList<JetType>();
@@ -118,8 +112,25 @@ public class JetTypeInferrer {
return argumentTypes;
}
@Nullable
private FunctionDescriptor lookupFunction(
@NotNull JetScope scope,
@NotNull JetReferenceExpression reference,
@NotNull String name,
@NotNull JetType receiverType,
@NotNull List<JetType> argumentTypes,
boolean reportUnresolved) {
OverloadDomain overloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(receiverType, scope, name);
overloadDomain = wrapForTracing(overloadDomain, reference, null, reportUnresolved);
return overloadDomain.getFunctionDescriptorForPositionedArguments(Collections.<JetType>emptyList(), argumentTypes);
}
private OverloadDomain getOverloadDomain(final JetScope scope, JetExpression calleeExpression) {
private OverloadDomain getOverloadDomain(
@NotNull final JetScope scope,
@NotNull JetExpression calleeExpression,
@Nullable PsiElement argumentList
) {
final OverloadDomain[] result = new OverloadDomain[1];
final JetSimpleNameExpression[] reference = new JetSimpleNameExpression[1];
calleeExpression.accept(new JetVisitor() {
@@ -173,7 +184,7 @@ public class JetTypeInferrer {
throw new IllegalArgumentException("Unsupported element: " + elem);
}
});
return wrapForTracing(result[0], reference[0], true);
return wrapForTracing(result[0], reference[0], argumentList, true);
}
private void checkNullSafety(JetType receiverType, JetQualifiedExpression expression) {
@@ -194,7 +205,11 @@ public class JetTypeInferrer {
}
}
private OverloadDomain wrapForTracing(final OverloadDomain overloadDomain, @NotNull final JetReferenceExpression referenceExpression, final boolean reportUnresolved) {
private OverloadDomain wrapForTracing(
@Nullable final OverloadDomain overloadDomain,
@NotNull final JetReferenceExpression referenceExpression,
@Nullable final PsiElement argumentList,
final boolean reportUnresolved) {
if (overloadDomain == null) return OverloadDomain.EMPTY;
return new OverloadDomain() {
@Override
@@ -202,10 +217,9 @@ public class JetTypeInferrer {
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType);
if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor);
} else {
if (reportUnresolved) {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
}
else {
reportError();
}
return descriptor;
}
@@ -215,16 +229,33 @@ public class JetTypeInferrer {
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor);
} else {
if (reportUnresolved) {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
}
else {
reportError();
}
return descriptor;
}
private void reportError() {
if (reportUnresolved) {
if (overloadDomain.isEmpty() || argumentList == null) {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
else {
// TODO : More helpful message. NOTE: there's a separate handling for this for constructors
semanticServices.getErrorHandler().genericError(argumentList.getNode(), "No overload found for these arguments");
}
}
}
@Override
public boolean isEmpty() {
return overloadDomain.isEmpty();
}
};
}
private JetType getBlockReturnedType(@NotNull JetScope outerScope, List<JetElement> block) {
if (block.isEmpty()) {
return JetStandardClasses.getUnitType();
@@ -642,10 +673,19 @@ public class JetTypeInferrer {
OverloadDomain constructorsOverloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(constructors);
result = resolveOverloads(
scope,
wrapForTracing(constructorsOverloadDomain, referenceExpression, true),
wrapForTracing(constructorsOverloadDomain, referenceExpression, expression.getArgumentList(), false),
Collections.<JetTypeProjection>emptyList(),
expression.getArguments(),
expression.getFunctionLiteralArguments());
if (result == null && !ErrorType.isErrorType(receiverType)) {
trace.recordReferenceResolution(referenceExpression, receiverType.getConstructor().getDeclarationDescriptor());
// TODO : more helpful message
JetArgumentList argumentList = expression.getArgumentList();
if (argumentList != null) {
semanticServices.getErrorHandler().genericError(argumentList.getNode(), "Cannot find an overload for these arguments");
}
result = receiverType;
}
}
}
else {
@@ -689,7 +729,7 @@ public class JetTypeInferrer {
JetScope compositeScope = new ScopeWithReceiver(scope, receiverType);
if (selectorExpression instanceof JetCallExpression) {
JetCallExpression callExpression = (JetCallExpression) selectorExpression;
OverloadDomain overloadDomain = getOverloadDomain(compositeScope, callExpression.getCalleeExpression());
OverloadDomain overloadDomain = getOverloadDomain(compositeScope, callExpression.getCalleeExpression(), callExpression.getValueArgumentList());
return resolveOverloads(scope, callExpression, overloadDomain);
}
else if (selectorExpression instanceof JetSimpleNameExpression) {
@@ -705,7 +745,7 @@ public class JetTypeInferrer {
@Override
public void visitCallExpression(JetCallExpression expression) {
JetExpression calleeExpression = expression.getCalleeExpression();
OverloadDomain overloadDomain = getOverloadDomain(scope, calleeExpression);
OverloadDomain overloadDomain = getOverloadDomain(scope, calleeExpression, expression.getValueArgumentList());
result = resolveOverloads(scope, expression, overloadDomain);
}