added ide renderers for type inference errors
This commit is contained in:
@@ -55,30 +55,13 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final DescriptorRenderer HTML = new DescriptorRenderer() {
|
public static final DescriptorRenderer HTML = new HtmlDescriptorRenderer();
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String escape(String s) {
|
|
||||||
return s.replaceAll("<", "<");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String renderKeyword(String keyword) {
|
|
||||||
return "<b>" + keyword + "</b>";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String renderMessage(String s) {
|
|
||||||
return "<i>" + s + "</i>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private final RenderDeclarationDescriptorVisitor rootVisitor = new RenderDeclarationDescriptorVisitor();
|
private final RenderDeclarationDescriptorVisitor rootVisitor = new RenderDeclarationDescriptorVisitor();
|
||||||
|
|
||||||
private final DeclarationDescriptorVisitor<Void, StringBuilder> subVisitor = new RenderDeclarationDescriptorVisitor() {
|
protected final DeclarationDescriptorVisitor<Void, StringBuilder> subVisitor = new RenderDeclarationDescriptorVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public Void visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, StringBuilder builder) {
|
public Void visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, StringBuilder builder) {
|
||||||
renderTypeParameter(descriptor, builder, false);
|
renderTypeParameter(descriptor, builder, false);
|
||||||
@@ -96,8 +79,17 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private DescriptorRenderer() {
|
private DescriptorRenderer() {
|
||||||
|
this(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DescriptorRenderer(boolean renderModifiers, boolean renderDefinedIn) {
|
||||||
|
this.renderModifiers = renderModifiers;
|
||||||
|
this.renderDefinedIn = renderDefinedIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean renderModifiers;
|
||||||
|
private final boolean renderDefinedIn;
|
||||||
|
|
||||||
protected boolean hasDefaultValue(ValueParameterDescriptor descriptor) {
|
protected boolean hasDefaultValue(ValueParameterDescriptor descriptor) {
|
||||||
return descriptor.hasDefaultValue();
|
return descriptor.hasDefaultValue();
|
||||||
}
|
}
|
||||||
@@ -256,7 +248,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
|
|
||||||
public String renderFunctionParameters(@NotNull FunctionDescriptor functionDescriptor) {
|
public String renderFunctionParameters(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
rootVisitor.renderValueParameters(functionDescriptor, stringBuilder);
|
renderValueParameters(functionDescriptor, stringBuilder);
|
||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,6 +257,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void appendDefinedIn(DeclarationDescriptor declarationDescriptor, StringBuilder stringBuilder) {
|
private void appendDefinedIn(DeclarationDescriptor declarationDescriptor, StringBuilder stringBuilder) {
|
||||||
|
if (!renderDefinedIn) return;
|
||||||
if (declarationDescriptor instanceof ModuleDescriptor) {
|
if (declarationDescriptor instanceof ModuleDescriptor) {
|
||||||
stringBuilder.append(" is a module");
|
stringBuilder.append(" is a module");
|
||||||
return;
|
return;
|
||||||
@@ -291,6 +284,32 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void renderValueParameters(FunctionDescriptor descriptor, StringBuilder builder) {
|
||||||
|
if (descriptor.getValueParameters().isEmpty()) {
|
||||||
|
renderEmptyValueParameters(builder);
|
||||||
|
}
|
||||||
|
for (Iterator<ValueParameterDescriptor> iterator = descriptor.getValueParameters().iterator(); iterator.hasNext(); ) {
|
||||||
|
renderValueParameter(iterator.next(), !iterator.hasNext(), builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderEmptyValueParameters(StringBuilder builder) {
|
||||||
|
builder.append("()");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderValueParameter(ValueParameterDescriptor parameterDescriptor, boolean isLast, StringBuilder builder) {
|
||||||
|
if (parameterDescriptor.getIndex() == 0) {
|
||||||
|
builder.append("(");
|
||||||
|
}
|
||||||
|
parameterDescriptor.accept(subVisitor, builder);
|
||||||
|
if (!isLast) {
|
||||||
|
builder.append(", ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder.append(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class RenderDeclarationDescriptorVisitor implements DeclarationDescriptorVisitor<Void, StringBuilder> {
|
private class RenderDeclarationDescriptorVisitor implements DeclarationDescriptorVisitor<Void, StringBuilder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -368,6 +387,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderVisibility(Visibility visibility, StringBuilder builder) {
|
private void renderVisibility(Visibility visibility, StringBuilder builder) {
|
||||||
|
if(!renderModifiers) return;
|
||||||
if ("package".equals(visibility.toString())) {
|
if ("package".equals(visibility.toString())) {
|
||||||
builder.append("public/*package*/ ");
|
builder.append("public/*package*/ ");
|
||||||
} else {
|
} else {
|
||||||
@@ -376,6 +396,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderModality(Modality modality, StringBuilder builder) {
|
private void renderModality(Modality modality, StringBuilder builder) {
|
||||||
|
if (!renderModifiers) return;
|
||||||
String keyword = "";
|
String keyword = "";
|
||||||
switch (modality) {
|
switch (modality) {
|
||||||
case FINAL:
|
case FINAL:
|
||||||
@@ -422,18 +443,6 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
return visitFunctionDescriptor(descriptor, data);
|
return visitFunctionDescriptor(descriptor, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderValueParameters(FunctionDescriptor descriptor, StringBuilder builder) {
|
|
||||||
builder.append("(");
|
|
||||||
for (Iterator<ValueParameterDescriptor> iterator = descriptor.getValueParameters().iterator(); iterator.hasNext(); ) {
|
|
||||||
ValueParameterDescriptor parameterDescriptor = iterator.next();
|
|
||||||
parameterDescriptor.accept(subVisitor, builder);
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
builder.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderWhereSuffix(@NotNull CallableMemberDescriptor callable, @NotNull StringBuilder builder) {
|
private void renderWhereSuffix(@NotNull CallableMemberDescriptor callable, @NotNull StringBuilder builder) {
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (TypeParameterDescriptor typeParameter : callable.getTypeParameters()) {
|
for (TypeParameterDescriptor typeParameter : callable.getTypeParameters()) {
|
||||||
@@ -618,4 +627,29 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class HtmlDescriptorRenderer extends DescriptorRenderer {
|
||||||
|
|
||||||
|
public HtmlDescriptorRenderer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public HtmlDescriptorRenderer(boolean renderModifiers, boolean renderDefinedIn) {
|
||||||
|
super(renderModifiers, renderDefinedIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String escape(String s) {
|
||||||
|
return s.replaceAll("<", "<").replaceAll(">", ">");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String renderKeyword(String keyword) {
|
||||||
|
return "<b>" + keyword + "</b>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String renderMessage(String s) {
|
||||||
|
return "<i>" + s + "</i>";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ public class IdeErrorMessages {
|
|||||||
MAP.put(ASSIGN_OPERATOR_AMBIGUITY, "<html>Assignment operators ambiguity. All these functions match.<ul>{0}</ul></table></html>",
|
MAP.put(ASSIGN_OPERATOR_AMBIGUITY, "<html>Assignment operators ambiguity. All these functions match.<ul>{0}</ul></table></html>",
|
||||||
HTML_AMBIGUOUS_CALLS);
|
HTML_AMBIGUOUS_CALLS);
|
||||||
|
|
||||||
|
MAP.put(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, "<html>Type inference failed: {0}</html>", HTML_INFERENCE_ERROR_CONFLICTING_SUBSTITUTIONS);
|
||||||
|
MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "<html>Type inference failed: {0}</html>", HTML_INFERENCE_NO_INFORMATION_FOR_PARAMETER);
|
||||||
|
MAP.put(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, "<html>Type inference failed: {0}</html>", HTML_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH);
|
||||||
|
MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "<html>{0}</html>", HTML_INFERENCE_UPPER_BOUND_VIOLATED);
|
||||||
|
|
||||||
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "<html>Setter parameter type must be equal to the type of the property." +
|
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "<html>Setter parameter type must be equal to the type of the property." +
|
||||||
"<table><tr><td>Expected:</td><td>{0}</td></tr>" +
|
"<table><tr><td>Expected:</td><td>{0}</td></tr>" +
|
||||||
"<tr><td>Found:</td><td>{1}</td></tr></table></html>", HTML_RENDER_TYPE, HTML_RENDER_TYPE);
|
"<tr><td>Found:</td><td>{1}</td></tr></table></html>", HTML_RENDER_TYPE, HTML_RENDER_TYPE);
|
||||||
|
|||||||
@@ -16,12 +16,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.highlighter;
|
package org.jetbrains.jet.plugin.highlighter;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1;
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1;
|
||||||
@@ -33,22 +36,38 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.TypeBounds;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class IdeRenderers {
|
public class IdeRenderers {
|
||||||
private static final String RED_TEMPLATE = "<font color=red><b>%s</b></font>";
|
private static final String RED_TEMPLATE = "<font color=red><b>%s</b></font>";
|
||||||
|
private static final String STRONG_TEMPLATE = "<b>%s</b>";
|
||||||
|
|
||||||
|
public static String strong(Object o) {
|
||||||
|
return String.format(STRONG_TEMPLATE, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String error(Object o) {
|
||||||
|
return String.format(RED_TEMPLATE, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String strong(Object o, boolean error) {
|
||||||
|
return String.format(error ? RED_TEMPLATE : STRONG_TEMPLATE, o);
|
||||||
|
}
|
||||||
|
|
||||||
public static final Renderer<Collection<? extends ResolvedCall<? extends CallableDescriptor>>> HTML_AMBIGUOUS_CALLS =
|
public static final Renderer<Collection<? extends ResolvedCall<? extends CallableDescriptor>>> HTML_AMBIGUOUS_CALLS =
|
||||||
new Renderer<Collection<? extends ResolvedCall<? extends CallableDescriptor>>>() {
|
new Renderer<Collection<? extends ResolvedCall<? extends CallableDescriptor>>>() {
|
||||||
@@ -162,4 +181,115 @@ public class IdeRenderers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> HTML_INFERENCE_ERROR_CONFLICTING_SUBSTITUTIONS =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
Collection<CallableDescriptor> substitutedDescriptors = Lists.newArrayList();
|
||||||
|
Collection<TypeSubstitutor> substitutors = inferenceErrorData.constraintSystem.getSubstitutors();
|
||||||
|
for (TypeSubstitutor substitutor : substitutors) {
|
||||||
|
CallableDescriptor substitutedDescriptor = inferenceErrorData.descriptor.substitute(substitutor);
|
||||||
|
substitutedDescriptors.add(substitutedDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = strong(inferenceErrorData.constraintSystem.getFirstConflictingParameter().getName());
|
||||||
|
TablesRenderer table = TablesRenderer.create();
|
||||||
|
table.text("Cannot infer type parameter %s in", type)
|
||||||
|
.descriptor(inferenceErrorData.descriptor)
|
||||||
|
.text("None of the following substitutions");
|
||||||
|
|
||||||
|
for (CallableDescriptor substitutedDescriptor : substitutedDescriptors) {
|
||||||
|
JetType receiverType = substitutedDescriptor.getReceiverParameter().exists() ? substitutedDescriptor.getReceiverParameter().getType() : null;
|
||||||
|
|
||||||
|
Collection<ConstraintPosition> errorPositions = Sets.newHashSet();
|
||||||
|
List<JetType> valueArgumentTypes = Lists.newArrayList();
|
||||||
|
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
|
||||||
|
valueArgumentTypes.add(valueParameterDescriptor.getType());
|
||||||
|
JetType actualType = inferenceErrorData.valueArgumentsTypes.get(valueParameterDescriptor.getIndex());
|
||||||
|
if (!JetTypeChecker.INSTANCE.isSubtypeOf(actualType, valueParameterDescriptor.getType())) {
|
||||||
|
errorPositions.add(ConstraintPosition.valueParameterPosition(valueParameterDescriptor.getIndex()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (receiverType != null && inferenceErrorData.receiverArgumentType != null &&
|
||||||
|
!JetTypeChecker.INSTANCE.isSubtypeOf(inferenceErrorData.receiverArgumentType, receiverType)) {
|
||||||
|
errorPositions.add(ConstraintPosition.RECEIVER_POSITION);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.functionArgumentTypeList(receiverType, valueArgumentTypes, errorPositions);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.text("can be applied to")
|
||||||
|
.functionArgumentTypeList(inferenceErrorData.receiverArgumentType, inferenceErrorData.valueArgumentsTypes);
|
||||||
|
return table.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> HTML_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
return TablesRenderer.create()
|
||||||
|
.descriptor(inferenceErrorData.descriptor)
|
||||||
|
.text("cannot be applied to")
|
||||||
|
.functionArgumentTypeList(inferenceErrorData.receiverArgumentType, inferenceErrorData.valueArgumentsTypes,
|
||||||
|
inferenceErrorData.constraintSystem.getErrorConstraintPositions())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> HTML_INFERENCE_NO_INFORMATION_FOR_PARAMETER =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
TypeParameterDescriptor firstUnknownParameter = null;
|
||||||
|
for (Map.Entry<TypeParameterDescriptor, TypeBounds> entry : inferenceErrorData.constraintSystem.getTypeBoundsMap().entrySet()) {
|
||||||
|
if (entry.getValue().isEmpty()) {
|
||||||
|
firstUnknownParameter = entry.getKey();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert firstUnknownParameter != null;
|
||||||
|
String firstUnknownParameterName = String.format(STRONG_TEMPLATE, firstUnknownParameter.getName());
|
||||||
|
|
||||||
|
return TablesRenderer.create()
|
||||||
|
.text("Not enough information to infer parameter %s in", firstUnknownParameterName)
|
||||||
|
.descriptor(inferenceErrorData.descriptor)
|
||||||
|
.text("Please specify it explicitly.")
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> HTML_INFERENCE_UPPER_BOUND_VIOLATED =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = null;
|
||||||
|
for (TypeParameterDescriptor typeParameter : inferenceErrorData.descriptor.getTypeParameters()) {
|
||||||
|
if (!inferenceErrorData.constraintSystem.checkUpperBound(typeParameter)) {
|
||||||
|
typeParameterDescriptor = typeParameter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert typeParameterDescriptor != null;
|
||||||
|
|
||||||
|
TablesRenderer table = TablesRenderer.create();
|
||||||
|
table.text("Type parameter bound for %s in", strong(typeParameterDescriptor.getName())).
|
||||||
|
descriptor(inferenceErrorData.descriptor);
|
||||||
|
|
||||||
|
JetType type = inferenceErrorData.constraintSystem.getValue(typeParameterDescriptor);
|
||||||
|
JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType();
|
||||||
|
JetType substitute = inferenceErrorData.constraintSystem.getSubstitutor().substitute(upperBound, Variance.INVARIANT);
|
||||||
|
|
||||||
|
table.newElement()
|
||||||
|
.text("is not satisfied: inferred type %s is not a subtype of %s.", error(type), strong(substitute));
|
||||||
|
return table.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user