added default renderers for type inference errors
TabledDescriptorRenderer is responsible for rendering messages with tables (in compiler); HtmlTabledDescriptorRenderer changes rendering in ide using html tables
This commit is contained in:
+4
-5
@@ -395,11 +395,10 @@ public class DefaultErrorMessages {
|
|||||||
|
|
||||||
MAP.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class");
|
MAP.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class");
|
||||||
|
|
||||||
//todo
|
MAP.put(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, "Type inference failed: {0}", TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER);
|
||||||
MAP.put(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, "Type inference failed: {0}", TO_STRING);
|
MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Type inference failed: {0}", TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER);
|
||||||
MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Type inference failed: {0}", TO_STRING);
|
MAP.put(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, "Type inference failed: {0}", TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH_RENDERER);
|
||||||
MAP.put(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, "Type inference failed: {0}", TO_STRING);
|
MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "{0}", TYPE_INFERENCE_UPPER_BOUND_VIOLATED_RENDERER);
|
||||||
MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "Type parameter bound is not satisfied: {0} is not a subtype of {1}", TO_STRING);
|
|
||||||
|
|
||||||
MAP.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type argument} expected", null);
|
MAP.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, "{0,choice,0#No type arguments|1#Type argument|1<{0,number,integer} type argument} expected", null);
|
||||||
|
|
||||||
|
|||||||
@@ -16,18 +16,32 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.diagnostics.rendering;
|
package org.jetbrains.jet.lang.diagnostics.rendering;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.Named;
|
import org.jetbrains.jet.lang.descriptors.Named;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
|
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.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 static org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
@@ -117,6 +131,151 @@ public class Renderers {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
return renderConflictingSubstitutionsInferenceError(inferenceErrorData, TabledDescriptorRenderer.create()).toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH_RENDERER =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
return renderTypeConstructorMismatchError(inferenceErrorData, TabledDescriptorRenderer.create()).toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
return renderNoInformationForParameterError(inferenceErrorData, TabledDescriptorRenderer.create()).toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final Renderer<InferenceErrorData> TYPE_INFERENCE_UPPER_BOUND_VIOLATED_RENDERER =
|
||||||
|
new Renderer<InferenceErrorData>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
return renderUpperBoundViolatedInferenceError(inferenceErrorData, TabledDescriptorRenderer.create()).toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static TabledDescriptorRenderer renderConflictingSubstitutionsInferenceError(InferenceErrorData inferenceErrorData,
|
||||||
|
TabledDescriptorRenderer result) {
|
||||||
|
assert inferenceErrorData.constraintSystem.hasConflictingParameters();
|
||||||
|
|
||||||
|
Collection<CallableDescriptor> substitutedDescriptors = Lists.newArrayList();
|
||||||
|
Collection<TypeSubstitutor> substitutors = inferenceErrorData.constraintSystem.getSubstitutors();
|
||||||
|
for (TypeSubstitutor substitutor : substitutors) {
|
||||||
|
CallableDescriptor substitutedDescriptor = inferenceErrorData.descriptor.substitute(substitutor);
|
||||||
|
substitutedDescriptors.add(substitutedDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeParameterDescriptor firstConflictingParameter = inferenceErrorData.constraintSystem.getFirstConflictingParameter();
|
||||||
|
assert firstConflictingParameter != null;
|
||||||
|
|
||||||
|
result.text(newText()
|
||||||
|
.normal("Cannot infer type parameter ")
|
||||||
|
.strong(firstConflictingParameter.getName())
|
||||||
|
.normal(" in"));
|
||||||
|
//String type = strong(firstConflictingParameter.getName());
|
||||||
|
TableRenderer table = newTable();
|
||||||
|
result.table(table);
|
||||||
|
table.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 result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TabledDescriptorRenderer renderTypeConstructorMismatchError(InferenceErrorData inferenceErrorData,
|
||||||
|
TabledDescriptorRenderer renderer) {
|
||||||
|
return renderer.table(TabledDescriptorRenderer.newTable()
|
||||||
|
.descriptor(inferenceErrorData.descriptor)
|
||||||
|
.text("cannot be applied to")
|
||||||
|
.functionArgumentTypeList(
|
||||||
|
inferenceErrorData.receiverArgumentType,
|
||||||
|
inferenceErrorData.valueArgumentsTypes,
|
||||||
|
inferenceErrorData.constraintSystem
|
||||||
|
.getErrorConstraintPositions()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TabledDescriptorRenderer renderNoInformationForParameterError(InferenceErrorData inferenceErrorData,
|
||||||
|
TabledDescriptorRenderer renderer) {
|
||||||
|
TypeParameterDescriptor firstUnknownParameter = null;
|
||||||
|
for (Map.Entry<TypeParameterDescriptor, TypeBounds> entry : inferenceErrorData.constraintSystem.getTypeBoundsMap().entrySet()) {
|
||||||
|
if (entry.getValue().isEmpty()) {
|
||||||
|
firstUnknownParameter = entry.getKey();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert firstUnknownParameter != null;
|
||||||
|
|
||||||
|
return renderer
|
||||||
|
.text(TabledDescriptorRenderer.newText().normal("Not enough information to infer parameter ")
|
||||||
|
.strong(firstUnknownParameter.getName())
|
||||||
|
.normal(" in "))
|
||||||
|
.table(TabledDescriptorRenderer.newTable()
|
||||||
|
.descriptor(inferenceErrorData.descriptor)
|
||||||
|
.text("Please specify it explicitly."));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TabledDescriptorRenderer renderUpperBoundViolatedInferenceError(InferenceErrorData inferenceErrorData, TabledDescriptorRenderer result) {
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = null;
|
||||||
|
for (TypeParameterDescriptor typeParameter : inferenceErrorData.descriptor.getTypeParameters()) {
|
||||||
|
if (!inferenceErrorData.constraintSystem.checkUpperBound(typeParameter)) {
|
||||||
|
typeParameterDescriptor = typeParameter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert typeParameterDescriptor != null;
|
||||||
|
|
||||||
|
result.text(newText().normal("Type parameter bound for ").strong(typeParameterDescriptor.getName()).normal(" in "))
|
||||||
|
.table(newTable().
|
||||||
|
descriptor(inferenceErrorData.descriptor));
|
||||||
|
|
||||||
|
JetType type = inferenceErrorData.constraintSystem.getValue(typeParameterDescriptor);
|
||||||
|
JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType();
|
||||||
|
JetType substitute = inferenceErrorData.constraintSystem.getSubstitutor().substitute(upperBound, Variance.INVARIANT);
|
||||||
|
|
||||||
|
result.text(newText()
|
||||||
|
.normal(" is not satisfied: inferred type ")
|
||||||
|
.error(type)
|
||||||
|
.normal(" is not a subtype of ")
|
||||||
|
.strong(substitute));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private Renderers() {
|
private Renderers() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+249
@@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.lang.diagnostics.rendering;
|
||||||
|
|
||||||
|
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.resolve.calls.inference.ConstraintPosition;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.*;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TextRenderer.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author svtk
|
||||||
|
*/
|
||||||
|
public class TabledDescriptorRenderer {
|
||||||
|
public interface TableOrTextRenderer {}
|
||||||
|
|
||||||
|
public static class TableRenderer implements TableOrTextRenderer{
|
||||||
|
public interface TableRow {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DescriptorRow implements TableRow {
|
||||||
|
public final CallableDescriptor descriptor;
|
||||||
|
|
||||||
|
public DescriptorRow(CallableDescriptor descriptor) {
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FunctionArgumentsRow implements TableRow {
|
||||||
|
public final JetType receiverType;
|
||||||
|
public final List<JetType> argumentTypes;
|
||||||
|
public final Collection<ConstraintPosition> errorPositions;
|
||||||
|
|
||||||
|
public FunctionArgumentsRow(JetType receiverType, List<JetType> argumentTypes, Collection<ConstraintPosition> errorPositions) {
|
||||||
|
this.receiverType = receiverType;
|
||||||
|
this.argumentTypes = argumentTypes;
|
||||||
|
this.errorPositions = errorPositions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final List<TableRow> rows = Lists.newArrayList();
|
||||||
|
|
||||||
|
public TableRenderer descriptor(CallableDescriptor descriptor) {
|
||||||
|
rows.add(new DescriptorRow(descriptor));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableRenderer functionArgumentTypeList(@Nullable JetType receiverType, @NotNull List<JetType> argumentTypes) {
|
||||||
|
return functionArgumentTypeList(receiverType, argumentTypes, Collections.<ConstraintPosition>emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableRenderer functionArgumentTypeList(@Nullable JetType receiverType,
|
||||||
|
@NotNull List<JetType> argumentTypes,
|
||||||
|
Collection<ConstraintPosition> errorPositions) {
|
||||||
|
rows.add(new FunctionArgumentsRow(receiverType, argumentTypes, errorPositions));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableRenderer text(@NotNull String text) {
|
||||||
|
rows.add(newText().normal(text));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableRenderer text(@NotNull TextRenderer textRenderer) {
|
||||||
|
rows.add(textRenderer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TextRenderer implements TableOrTextRenderer, TableRow {
|
||||||
|
public static enum TextElementType {STRONG, ERROR, DEFAULT}
|
||||||
|
public static class TextElement {
|
||||||
|
|
||||||
|
public TextElementType type;
|
||||||
|
public String text;
|
||||||
|
|
||||||
|
public TextElement(@NotNull TextElementType type, @NotNull String text) {
|
||||||
|
this.type = type;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final List<TextElement> elements = Lists.newArrayList();
|
||||||
|
|
||||||
|
public TextRenderer normal(@NotNull Object text) {
|
||||||
|
elements.add(new TextElement(TextElementType.DEFAULT, text.toString()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextRenderer error(@NotNull Object text) {
|
||||||
|
elements.add(new TextElement(TextElementType.ERROR, text.toString()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextRenderer strong(@NotNull Object text) {
|
||||||
|
elements.add(new TextElement(TextElementType.STRONG, text.toString()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final List<TableOrTextRenderer> renderers = Lists.newArrayList();
|
||||||
|
|
||||||
|
public TabledDescriptorRenderer text(@NotNull TextRenderer textRenderer) {
|
||||||
|
renderers.add(textRenderer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TabledDescriptorRenderer table(@NotNull TableRenderer tableRenderer) {
|
||||||
|
renderers.add(tableRenderer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TextRenderer newText() {
|
||||||
|
return new TextRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TableRenderer newTable() {
|
||||||
|
return new TableRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//protected final List<TableRenderer> previousTables = Lists.newArrayList();
|
||||||
|
//private TextRow currentFirstText;
|
||||||
|
//private List<TableRow> currentRows;
|
||||||
|
//
|
||||||
|
//public TabledDescriptorRenderer newElement() {
|
||||||
|
// previousTables.add(new TableRenderer(currentFirstText, currentRows));
|
||||||
|
// currentFirstText = null;
|
||||||
|
// currentRows = Lists.newArrayList();
|
||||||
|
// return this;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//public TabledDescriptorRenderer text(String text) {
|
||||||
|
// if (currentRows.isEmpty()) {
|
||||||
|
// currentFirstText = new TextRow(text);
|
||||||
|
// return this;
|
||||||
|
// }
|
||||||
|
// currentRows.add(new TextRow(text));
|
||||||
|
// return this;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//public TabledDescriptorRenderer text(String text, Object... args) {
|
||||||
|
// return text(String.format(text, args));
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//private TabledDescriptorRenderer(@Nullable TextRow firstText, @NotNull List<TableRow> rows) {
|
||||||
|
// this.currentFirstText = firstText;
|
||||||
|
// this.currentRows = rows;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//protected TabledDescriptorRenderer() {
|
||||||
|
// this(null, Lists.<TableRow>newArrayList());
|
||||||
|
//}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
for (TableOrTextRenderer tableOrTextRenderer : renderers) {
|
||||||
|
if (tableOrTextRenderer instanceof TableRenderer) {
|
||||||
|
renderTable((TableRenderer)tableOrTextRenderer, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderText((TextRenderer)tableOrTextRenderer, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderText(TextRenderer textRenderer, StringBuilder result) {
|
||||||
|
for (TextElement element : textRenderer.elements) {
|
||||||
|
result.append(element.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderTable(TableRenderer table, StringBuilder result) {
|
||||||
|
if (table.rows.isEmpty()) return;
|
||||||
|
for (TableRow row : table.rows) {
|
||||||
|
if (row instanceof TextRenderer) {
|
||||||
|
renderText((TextRenderer) row, result);
|
||||||
|
}
|
||||||
|
if (row instanceof DescriptorRow) {
|
||||||
|
result.append(DescriptorRenderer.COMPACT.render(((DescriptorRow) row).descriptor));
|
||||||
|
}
|
||||||
|
if (row instanceof FunctionArgumentsRow) {
|
||||||
|
FunctionArgumentsRow functionArgumentsRow = (FunctionArgumentsRow) row;
|
||||||
|
renderFunctionArguments(functionArgumentsRow.receiverType, functionArgumentsRow.argumentTypes, result);
|
||||||
|
}
|
||||||
|
result.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderFunctionArguments(@Nullable JetType receiverType, @NotNull List<JetType> argumentTypes, StringBuilder result) {
|
||||||
|
boolean hasReceiver = receiverType != null;
|
||||||
|
if (hasReceiver) {
|
||||||
|
result.append("receiver: ");
|
||||||
|
result.append(Renderers.RENDER_TYPE.render(receiverType));
|
||||||
|
result.append(" arguments: ");
|
||||||
|
}
|
||||||
|
if (argumentTypes.isEmpty()) {
|
||||||
|
result.append("()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.append("(");
|
||||||
|
for (Iterator<JetType> iterator = argumentTypes.iterator(); iterator.hasNext(); ) {
|
||||||
|
JetType argumentType = iterator.next();
|
||||||
|
String renderedArgument = Renderers.RENDER_TYPE.render(argumentType);
|
||||||
|
|
||||||
|
result.append(renderedArgument);
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
result.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TabledDescriptorRenderer create() {
|
||||||
|
return new TabledDescriptorRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+38
-111
@@ -16,119 +16,43 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.highlighter;
|
package org.jetbrains.jet.plugin.highlighter;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
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.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.*;
|
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.*;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class TablesRenderer {
|
public class HtmlTabledDescriptorRenderer extends TabledDescriptorRenderer {
|
||||||
public static class Table {
|
|
||||||
public final TextRow firstText;
|
|
||||||
public final List<TableRow> rows;
|
|
||||||
|
|
||||||
public Table(TextRow firstText, List<TableRow> rows) {
|
protected void renderText(TextRenderer textRenderer, StringBuilder result) {
|
||||||
this.firstText = firstText;
|
for (TextRenderer.TextElement element : textRenderer.elements) {
|
||||||
this.rows = rows;
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TableRow {
|
private int countRowsNumber(TableRenderer table) {
|
||||||
}
|
|
||||||
|
|
||||||
public static class TextRow implements TableRow {
|
|
||||||
public final String text;
|
|
||||||
|
|
||||||
public TextRow(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DescriptorRow implements TableRow {
|
|
||||||
public final CallableDescriptor descriptor;
|
|
||||||
|
|
||||||
public DescriptorRow(CallableDescriptor descriptor) {
|
|
||||||
this.descriptor = descriptor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FunctionArgumentsRow implements TableRow {
|
|
||||||
public final JetType receiverType;
|
|
||||||
public final List<JetType> argumentTypes;
|
|
||||||
public final Collection<ConstraintPosition> errorPositions;
|
|
||||||
|
|
||||||
public FunctionArgumentsRow(JetType receiverType, List<JetType> argumentTypes, Collection<ConstraintPosition> errorPositions) {
|
|
||||||
this.receiverType = receiverType;
|
|
||||||
this.argumentTypes = argumentTypes;
|
|
||||||
this.errorPositions = errorPositions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final List<Table> previousTables = Lists.newArrayList();
|
|
||||||
private TextRow currentFirstText;
|
|
||||||
private List<TableRow> currentRows;
|
|
||||||
|
|
||||||
public TablesRenderer newElement() {
|
|
||||||
previousTables.add(new Table(currentFirstText, currentRows));
|
|
||||||
currentFirstText = null;
|
|
||||||
currentRows = Lists.newArrayList();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TablesRenderer text(String text) {
|
|
||||||
if (currentRows.isEmpty()) {
|
|
||||||
currentFirstText = new TextRow(text);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
currentRows.add(new TextRow(text));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TablesRenderer text(String text, Object... args) {
|
|
||||||
return text(String.format(text, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
public TablesRenderer descriptor(CallableDescriptor descriptor) {
|
|
||||||
currentRows.add(new DescriptorRow(descriptor));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TablesRenderer functionArgumentTypeList(@Nullable JetType receiverType, @NotNull List<JetType> argumentTypes) {
|
|
||||||
return functionArgumentTypeList(receiverType, argumentTypes, Collections.<ConstraintPosition>emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public TablesRenderer functionArgumentTypeList(@Nullable JetType receiverType,
|
|
||||||
@NotNull List<JetType> argumentTypes,
|
|
||||||
Collection<ConstraintPosition> errorPositions) {
|
|
||||||
currentRows.add(new FunctionArgumentsRow(receiverType, argumentTypes, errorPositions));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
newElement();
|
|
||||||
for (Table table : previousTables) {
|
|
||||||
renderTable(table, result);
|
|
||||||
}
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int countRowsNumber(Table table) {
|
|
||||||
int argumentsNumber = 0;
|
int argumentsNumber = 0;
|
||||||
for (TableRow row : table.rows) {
|
for (TableRow row : table.rows) {
|
||||||
if (row instanceof DescriptorRow) {
|
if (row instanceof DescriptorRow) {
|
||||||
@@ -149,21 +73,19 @@ public class TablesRenderer {
|
|||||||
return argumentsNumber + 6;
|
return argumentsNumber + 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderTable(TableRenderer table, StringBuilder result) {
|
||||||
private static void renderTable(Table table, StringBuilder result) {
|
if (table.rows.isEmpty()) return;
|
||||||
if (table.firstText == null && table.rows.isEmpty()) return;
|
|
||||||
if (table.firstText != null) {
|
|
||||||
result.append(table.firstText.text);
|
|
||||||
}
|
|
||||||
int rowsNumber = countRowsNumber(table);
|
int rowsNumber = countRowsNumber(table);
|
||||||
|
|
||||||
|
|
||||||
result.append("<table>");
|
result.append("<table>");
|
||||||
for (TableRow row : table.rows) {
|
for (TableRow row : table.rows) {
|
||||||
result.append("<tr>");
|
result.append("<tr>");
|
||||||
if (row instanceof TextRow) {
|
if (row instanceof TextRenderer) {
|
||||||
tdColspan(result, ((TextRow) row).text, rowsNumber);
|
StringBuilder rowText = new StringBuilder();
|
||||||
|
renderText((TextRenderer) row, rowText);
|
||||||
|
tdColspan(result, rowText.toString(), rowsNumber);
|
||||||
}
|
}
|
||||||
if (row instanceof DescriptorRow) {
|
if (row instanceof DescriptorRow) {
|
||||||
result.append(DESCRIPTOR_IN_TABLE.render(((DescriptorRow) row).descriptor));
|
result.append(DESCRIPTOR_IN_TABLE.render(((DescriptorRow) row).descriptor));
|
||||||
@@ -179,7 +101,7 @@ public class TablesRenderer {
|
|||||||
result.append("</table>");
|
result.append("</table>");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderFunctionArguments(@Nullable JetType receiverType, @NotNull List<JetType> argumentTypes, Collection<ConstraintPosition> errorPositions, StringBuilder result) {
|
private void renderFunctionArguments(@Nullable JetType receiverType, @NotNull List<JetType> argumentTypes, Collection<ConstraintPosition> errorPositions, StringBuilder result) {
|
||||||
boolean hasReceiver = receiverType != null;
|
boolean hasReceiver = receiverType != null;
|
||||||
tdSpace(result);
|
tdSpace(result);
|
||||||
String receiver = "";
|
String receiver = "";
|
||||||
@@ -213,20 +135,25 @@ public class TablesRenderer {
|
|||||||
td(result, strong(")"));
|
td(result, strong(")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TablesRenderer create() {
|
public static HtmlTabledDescriptorRenderer create() {
|
||||||
return new TablesRenderer();
|
return new HtmlTabledDescriptorRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
TablesRenderer(@Nullable TextRow firstText, @NotNull List<TableRow> rows) {
|
protected HtmlTabledDescriptorRenderer() {
|
||||||
this.currentFirstText = firstText;
|
super();
|
||||||
this.currentRows = rows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TablesRenderer() {
|
public static final DescriptorRenderer DESCRIPTOR_IN_TABLE = new DescriptorRenderer.HtmlDescriptorRenderer() {
|
||||||
this(null, Lists.<TableRow>newArrayList());
|
@Override
|
||||||
}
|
protected boolean shouldRenderDefinedIn() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldRenderModifiers() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static final DescriptorRenderer DESCRIPTOR_IN_TABLE = new DescriptorRenderer.HtmlDescriptorRenderer(false, false) {
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull DeclarationDescriptor declarationDescriptor) {
|
public String render(@NotNull DeclarationDescriptor declarationDescriptor) {
|
||||||
@@ -44,10 +44,10 @@ 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_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_INFERENCE_NO_INFORMATION_FOR_PARAMETER);
|
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_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH);
|
MAP.put(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, "<html>Type inference failed: {0}</html>", HTML_TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH_RENDERER);
|
||||||
MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "<html>{0}</html>", HTML_INFERENCE_UPPER_BOUND_VIOLATED);
|
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." +
|
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>" +
|
||||||
|
|||||||
@@ -16,15 +16,12 @@
|
|||||||
|
|
||||||
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;
|
||||||
@@ -36,19 +33,19 @@ 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.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.*;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
@@ -181,115 +178,40 @@ public class IdeRenderers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Renderer<InferenceErrorData> HTML_INFERENCE_ERROR_CONFLICTING_SUBSTITUTIONS =
|
public static final Renderer<InferenceErrorData> HTML_TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER =
|
||||||
new Renderer<InferenceErrorData>() {
|
new Renderer<InferenceErrorData>() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
Collection<CallableDescriptor> substitutedDescriptors = Lists.newArrayList();
|
return renderConflictingSubstitutionsInferenceError(inferenceErrorData, HtmlTabledDescriptorRenderer.create()).toString();
|
||||||
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_TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH_RENDERER =
|
||||||
public static final Renderer<InferenceErrorData> HTML_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH =
|
|
||||||
new Renderer<InferenceErrorData>() {
|
new Renderer<InferenceErrorData>() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
return TablesRenderer.create()
|
return renderTypeConstructorMismatchError(inferenceErrorData, HtmlTabledDescriptorRenderer.create()).toString();
|
||||||
.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 =
|
public static final Renderer<InferenceErrorData> HTML_TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER =
|
||||||
new Renderer<InferenceErrorData>() {
|
new Renderer<InferenceErrorData>() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
TypeParameterDescriptor firstUnknownParameter = null;
|
return renderNoInformationForParameterError(inferenceErrorData, HtmlTabledDescriptorRenderer.create()).toString();
|
||||||
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 =
|
public static final Renderer<InferenceErrorData> HTML_TYPE_INFERENCE_UPPER_BOUND_VIOLATED_RENDERER =
|
||||||
new Renderer<InferenceErrorData>() {
|
new Renderer<InferenceErrorData>() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
public String render(@NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
return renderUpperBoundViolatedInferenceError(inferenceErrorData, HtmlTabledDescriptorRenderer.create()).toString();
|
||||||
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