added error TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH

This commit is contained in:
Svetlana Isakova
2012-07-19 15:31:26 +04:00
parent 17c16d8bfc
commit b161b6bfbf
12 changed files with 89 additions and 38 deletions
@@ -340,6 +340,7 @@ public interface Errors {
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_UPPER_BOUND_VIOLATED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<PsiElement, JetType, JetType> TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR);
Collection<AbstractDiagnosticFactory> TYPE_INFERENCE_ERRORS = Lists.<AbstractDiagnosticFactory>newArrayList(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER,
TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, TYPE_INFERENCE_UPPER_BOUND_VIOLATED);
@@ -35,8 +35,6 @@ import java.util.Iterator;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.*;
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.RENDER_TYPE;
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.TO_STRING;
/**
* @author Evgeny Gerashchenko
@@ -399,6 +397,7 @@ public class DefaultErrorMessages {
MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Type inference failed: {0}", TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER);
MAP.put(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, "Type inference failed: {0}", TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH_RENDERER);
MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "{0}", TYPE_INFERENCE_UPPER_BOUND_VIOLATED_RENDERER);
MAP.put(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH, "Type inference failed. Expected type mismatch: found: {0} required: {1}", RENDER_TYPE, RENDER_TYPE);
MAP.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type argument} expected", null);
@@ -256,10 +256,10 @@ public class Renderers {
assert firstUnknownParameter != null;
return renderer
.text(TabledDescriptorRenderer.newText().normal("Not enough information to infer parameter ")
.text(newText().normal("Not enough information to infer parameter ")
.strong(firstUnknownParameter.getName())
.normal(" in "))
.table(TabledDescriptorRenderer.newTable()
.table(newTable()
.descriptor(inferenceErrorData.descriptor)
.text("Please specify it explicitly."));
}
@@ -22,9 +22,7 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.DescriptorRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.FunctionArgumentsRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.TableRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.*;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TextRenderer.TextElement;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.types.JetType;
@@ -63,7 +61,6 @@ public class TabledDescriptorRenderer {
}
}
public final List<TableRow> rows = Lists.newArrayList();
public TableRenderer descriptor(CallableDescriptor descriptor) {
@@ -95,7 +92,6 @@ public class TabledDescriptorRenderer {
}
public static class TextRenderer implements TableOrTextRenderer, TableRow {
public static enum TextElementType {STRONG, ERROR, DEFAULT}
public static class TextElement {
public TextElementType type;
@@ -248,4 +244,5 @@ public class TabledDescriptorRenderer {
return new TabledDescriptorRenderer();
}
public static enum TextElementType { STRONG, ERROR, DEFAULT }
}
@@ -365,7 +365,7 @@ public class CallResolver {
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, context.trace).argumentTypes;
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
tracing.typeInferenceFailed(context.trace,
InferenceErrorData.create(descriptor, constraintsSystem, argumentTypes, receiverType));
InferenceErrorData.create(descriptor, constraintsSystem, argumentTypes, receiverType, context.expectedType));
resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR);
failed.add(resolvedCall);
return;
@@ -761,7 +761,7 @@ public class CallResolver {
List<JetType> argumentTypes = checkingResult.argumentTypes;
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
context.tracing.typeInferenceFailed(context.trace,
InferenceErrorData.create(candidate, constraintsBuilderWithRightTypeParameters, argumentTypes, receiverType));
InferenceErrorData.create(candidate, constraintsBuilderWithRightTypeParameters, argumentTypes, receiverType, context.expectedType));
return TYPE_INFERENCE_ERROR.combine(argumentsStatus);
}
}
@@ -27,6 +27,8 @@ import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -233,20 +235,26 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends R
}
@Override
public void typeInferenceFailed(@NotNull BindingTrace trace, @NotNull InferenceErrorData inferenceErrorData) {
assert !inferenceErrorData.constraintsSystem.isSuccessful();
if (inferenceErrorData.constraintsSystem.hasErrorInConstrainingTypes()) {
public void typeInferenceFailed(@NotNull BindingTrace trace, @NotNull InferenceErrorData data) {
ConstraintsSystem constraintsSystem = data.constraintsSystem;
assert !constraintsSystem.isSuccessful();
if (constraintsSystem.hasErrorInConstrainingTypes()) {
return;
}
if (inferenceErrorData.constraintsSystem.hasTypeConstructorMismatch()) {
trace.report(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH.on(reference, inferenceErrorData));
if (constraintsSystem.hasExpectedTypeMismatch()) {
JetType returnType = data.descriptor.getReturnType();
assert returnType != null;
trace.report(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH.on(reference, returnType, data.expectedType));
}
else if (inferenceErrorData.constraintsSystem.hasConflictingConstraints()) {
trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(reference, inferenceErrorData));
else if (constraintsSystem.hasTypeConstructorMismatch()) {
trace.report(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH.on(reference, data));
}
else if (constraintsSystem.hasConflictingConstraints()) {
trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(reference, data));
}
else {
assert inferenceErrorData.constraintsSystem.hasUnknownParameters();
trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(reference, inferenceErrorData));
assert constraintsSystem.hasUnknownParameters();
trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(reference, data));
}
}
@@ -99,6 +99,11 @@ public interface ConstraintsSystem {
*/
boolean hasTypeConstructorMismatchAt(@NotNull ConstraintPosition constraintPosition);
/**
* Returns <tt>true</tt> if there is type constructor mismatch only in {@link ConstraintPosition.EXPECTED_TYPE_POSITION}.
*/
boolean hasExpectedTypeMismatch();
/**
* Returns <tt>true</tt> if there is an error in constraining types. <p/>
* Is used not to generate type inference error if there was one in argument types.
@@ -89,6 +89,11 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
return errorConstraintPositions.contains(constraintPosition);
}
@Override
public boolean hasExpectedTypeMismatch() {
return errorConstraintPositions.size() == 1 && errorConstraintPositions.contains(ConstraintPosition.EXPECTED_TYPE_POSITION);
}
@Override
public boolean hasErrorInConstrainingTypes() {
return hasErrorInConstrainingTypes;
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import java.util.List;
@@ -30,22 +31,25 @@ public class InferenceErrorData {
public final CallableDescriptor descriptor;
public final ConstraintsSystem constraintsSystem;
public final JetType receiverArgumentType;
public final JetType expectedType;
public final List<JetType> valueArgumentsTypes;
private InferenceErrorData(@NotNull CallableDescriptor descriptor, @NotNull ConstraintsSystem constraintsSystem,
@Nullable List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType) {
@Nullable List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType, @Nullable JetType expectedType) {
this.descriptor = descriptor;
this.constraintsSystem = constraintsSystem;
this.receiverArgumentType = receiverArgumentType;
this.valueArgumentsTypes = valueArgumentsTypes;
this.expectedType = expectedType;
}
public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintsSystem constraintsSystem,
@NotNull List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType) {
return new InferenceErrorData(descriptor, constraintsSystem, valueArgumentsTypes, receiverArgumentType);
@NotNull List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType, @Nullable JetType expectedType) {
return new InferenceErrorData(descriptor, constraintsSystem, valueArgumentsTypes, receiverArgumentType,
expectedType != TypeUtils.NO_EXPECTED_TYPE ? expectedType : null);
}
public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintsSystem constraintsSystem) {
return new InferenceErrorData(descriptor, constraintsSystem, null, null);
return new InferenceErrorData(descriptor, constraintsSystem, null, null, null);
}
}
@@ -0,0 +1,11 @@
package typeInferenceExpectedTypeMismatch
import java.util.*
fun test() {
val <!UNUSED_VARIABLE!>s<!> : Set<Int> = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>newList<!>()
}
fun newList<S>() : ArrayList<S> {
return ArrayList<S>()
}
@@ -23,9 +23,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.DescriptorRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.FunctionArgumentsRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.TableRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.*;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.resolve.DescriptorRenderer;
@@ -33,6 +31,7 @@ import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.Iterator;
import java.util.List;
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.HTML_RENDER_TYPE;
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.error;
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.strong;
@@ -41,21 +40,26 @@ import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.strong;
*/
public class HtmlTabledDescriptorRenderer extends TabledDescriptorRenderer {
@Override
protected void renderText(TextRenderer textRenderer, StringBuilder result) {
for (TextRenderer.TextElement element : textRenderer.elements) {
if (element.type == TextRenderer.TextElementType.DEFAULT) {
result.append(element.text);
}
else if (element.type == TextRenderer.TextElementType.ERROR) {
result.append(error(element.text));
}
else if (element.type == TextRenderer.TextElementType.STRONG) {
result.append(strong(element.text));
}
renderText(result, element.type, element.text);
}
}
private int countRowsNumber(TableRenderer table) {
private static void renderText(StringBuilder result, TextElementType elementType, String text) {
if (elementType == TextElementType.DEFAULT) {
result.append(text);
}
else if (elementType == TextElementType.ERROR) {
result.append(error(text));
}
else if (elementType == TextElementType.STRONG) {
result.append(strong(text));
}
}
private int countColumnNumber(TableRenderer table) {
int argumentsNumber = 0;
for (TableRow row : table.rows) {
if (row instanceof DescriptorRow) {
@@ -79,7 +83,7 @@ public class HtmlTabledDescriptorRenderer extends TabledDescriptorRenderer {
@Override
protected void renderTable(TableRenderer table, StringBuilder result) {
if (table.rows.isEmpty()) return;
int rowsNumber = countRowsNumber(table);
int rowsNumber = countColumnNumber(table);
result.append("<table>");
@@ -221,4 +225,15 @@ public class HtmlTabledDescriptorRenderer extends TabledDescriptorRenderer {
private static void tdRightBoldColspan(StringBuilder builder, int colspan, String text) {
builder.append("<td align=\"right\" colspan=\"").append(colspan).append("\"><div style=\"white-space:nowrap;font-weight:bold;\">").append(text).append("</div></td>");
}
public static String tableForTypes(String message, String firstDescription, TextElementType firstType, String secondDescription, TextElementType secondType) {
StringBuilder result = new StringBuilder();
result.append("<html>").append(message);
result.append("<table><tr><td>").append(firstDescription).append("</td><td>");
renderText(result, firstType, "{0}");
result.append("</td></tr><tr><td>").append(secondDescription).append("</td><td>");
renderText(result, secondType, "{1}");
result.append("</td></tr></table></html>");
return result.toString();
}
}
@@ -25,8 +25,11 @@ import org.jetbrains.jet.resolve.DescriptorRenderer;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.RENDER_CLASS_OR_OBJECT;
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.TO_STRING;
import static org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TextElementType;
import static org.jetbrains.jet.plugin.highlighter.HtmlTabledDescriptorRenderer.tableForTypes;
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.*;
/**
* @see DefaultErrorMessages
*
@@ -47,6 +50,9 @@ public class IdeErrorMessages {
MAP.put(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, "<html>Type inference failed: {0}</html>", HTML_TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER);
MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "<html>Type inference failed: {0}</html>", HTML_TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER);
MAP.put(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, "<html>Type inference failed: {0}</html>", HTML_TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH_RENDERER);
MAP.put(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH, tableForTypes("Type inference failed. Expected type mismatch: ",
"found: ", TextElementType.ERROR,
"required: ", TextElementType.STRONG), HTML_RENDER_TYPE, HTML_RENDER_TYPE);
MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "<html>{0}</html>", HTML_TYPE_INFERENCE_UPPER_BOUND_VIOLATED_RENDERER);
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "<html>Setter parameter type must be equal to the type of the property." +