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) { public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
return null; return null;
} }
@Override
public boolean isEmpty() {
return true;
}
}; };
/** /**
@@ -47,4 +52,9 @@ public interface OverloadDomain {
FunctionDescriptor getFunctionDescriptorForPositionedArguments( FunctionDescriptor getFunctionDescriptorForPositionedArguments(
@NotNull List<JetType> typeArguments, @NotNull List<JetType> typeArguments,
@NotNull List<JetType> positionedValueArgumentTypes); @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 @Override
public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) { public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
@@ -87,8 +87,8 @@ public class JavaDescriptorResolver {
Collections.<Attribute>emptyList(), // TODO Collections.<Attribute>emptyList(), // TODO
false); false);
constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters())); constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()));
constructors.addFunction( constructors.addFunction(constructorDescriptor);
constructorDescriptor); semanticServices.getTrace().recordDeclarationResolution(constructor, constructorDescriptor);
} }
semanticServices.getTrace().recordDeclarationResolution(psiClass, classDescriptor); semanticServices.getTrace().recordDeclarationResolution(psiClass, classDescriptor);
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.types; package org.jetbrains.jet.lang.types;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -98,13 +99,6 @@ public class JetTypeInferrer {
return expression; 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 @Nullable
private List<JetType> getTypes(JetScope scope, List<JetExpression> indexExpressions) { private List<JetType> getTypes(JetScope scope, List<JetExpression> indexExpressions) {
List<JetType> argumentTypes = new ArrayList<JetType>(); List<JetType> argumentTypes = new ArrayList<JetType>();
@@ -118,8 +112,25 @@ public class JetTypeInferrer {
return argumentTypes; 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 OverloadDomain[] result = new OverloadDomain[1];
final JetSimpleNameExpression[] reference = new JetSimpleNameExpression[1]; final JetSimpleNameExpression[] reference = new JetSimpleNameExpression[1];
calleeExpression.accept(new JetVisitor() { calleeExpression.accept(new JetVisitor() {
@@ -173,7 +184,7 @@ public class JetTypeInferrer {
throw new IllegalArgumentException("Unsupported element: " + elem); 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) { 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; if (overloadDomain == null) return OverloadDomain.EMPTY;
return new OverloadDomain() { return new OverloadDomain() {
@Override @Override
@@ -202,10 +217,9 @@ public class JetTypeInferrer {
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType); FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType);
if (descriptor != null) { if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor); trace.recordReferenceResolution(referenceExpression, descriptor);
} else { }
if (reportUnresolved) { else {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression); reportError();
}
} }
return descriptor; return descriptor;
} }
@@ -215,16 +229,33 @@ public class JetTypeInferrer {
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes); FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
if (descriptor != null) { if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor); trace.recordReferenceResolution(referenceExpression, descriptor);
} else { }
if (reportUnresolved) { else {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression); reportError();
}
} }
return descriptor; 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) { private JetType getBlockReturnedType(@NotNull JetScope outerScope, List<JetElement> block) {
if (block.isEmpty()) { if (block.isEmpty()) {
return JetStandardClasses.getUnitType(); return JetStandardClasses.getUnitType();
@@ -642,10 +673,19 @@ public class JetTypeInferrer {
OverloadDomain constructorsOverloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(constructors); OverloadDomain constructorsOverloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(constructors);
result = resolveOverloads( result = resolveOverloads(
scope, scope,
wrapForTracing(constructorsOverloadDomain, referenceExpression, true), wrapForTracing(constructorsOverloadDomain, referenceExpression, expression.getArgumentList(), false),
Collections.<JetTypeProjection>emptyList(), Collections.<JetTypeProjection>emptyList(),
expression.getArguments(), expression.getArguments(),
expression.getFunctionLiteralArguments()); 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 { else {
@@ -689,7 +729,7 @@ public class JetTypeInferrer {
JetScope compositeScope = new ScopeWithReceiver(scope, receiverType); JetScope compositeScope = new ScopeWithReceiver(scope, receiverType);
if (selectorExpression instanceof JetCallExpression) { if (selectorExpression instanceof JetCallExpression) {
JetCallExpression callExpression = (JetCallExpression) selectorExpression; JetCallExpression callExpression = (JetCallExpression) selectorExpression;
OverloadDomain overloadDomain = getOverloadDomain(compositeScope, callExpression.getCalleeExpression()); OverloadDomain overloadDomain = getOverloadDomain(compositeScope, callExpression.getCalleeExpression(), callExpression.getValueArgumentList());
return resolveOverloads(scope, callExpression, overloadDomain); return resolveOverloads(scope, callExpression, overloadDomain);
} }
else if (selectorExpression instanceof JetSimpleNameExpression) { else if (selectorExpression instanceof JetSimpleNameExpression) {
@@ -705,7 +745,7 @@ public class JetTypeInferrer {
@Override @Override
public void visitCallExpression(JetCallExpression expression) { public void visitCallExpression(JetCallExpression expression) {
JetExpression calleeExpression = expression.getCalleeExpression(); JetExpression calleeExpression = expression.getCalleeExpression();
OverloadDomain overloadDomain = getOverloadDomain(scope, calleeExpression); OverloadDomain overloadDomain = getOverloadDomain(scope, calleeExpression, expression.getValueArgumentList());
result = resolveOverloads(scope, expression, overloadDomain); result = resolveOverloads(scope, expression, overloadDomain);
} }