mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: improve incompatible types reporting
- only report type with "anonymous" prefix when the left side is anonymous - use short names in the tool tip when fq names would be identical as well - use error color for the entire type name, including the anonymous prefix GitOrigin-RevId: f1555687adb0ab9e7c5850719165a7a508ecf181
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8c259fa269
commit
0cae65939b
+31
-47
@@ -144,7 +144,7 @@ public final class HighlightUtil {
|
||||
|
||||
private static final String SERIAL_PERSISTENT_FIELDS_FIELD_NAME = "serialPersistentFields";
|
||||
public static final TokenSet BRACKET_TOKENS = TokenSet.create(JavaTokenType.LBRACKET, JavaTokenType.RBRACKET);
|
||||
private static final String ANONYMOUS = "anonymous";
|
||||
private static final @NlsSafe String ANONYMOUS = "anonymous ";
|
||||
|
||||
private HighlightUtil() { }
|
||||
|
||||
@@ -3208,26 +3208,24 @@ public final class HighlightUtil {
|
||||
|
||||
@NotNull
|
||||
static HighlightInfo.Builder createIncompatibleTypeHighlightInfo(@NotNull PsiType lType,
|
||||
@Nullable PsiType rType,
|
||||
@NotNull TextRange textRange,
|
||||
int navigationShift,
|
||||
@NotNull String reason) {
|
||||
@Nullable PsiType rType,
|
||||
@NotNull TextRange textRange,
|
||||
int navigationShift,
|
||||
@NotNull String reason) {
|
||||
PsiType baseLType = PsiUtil.convertAnonymousToBaseType(lType);
|
||||
PsiType baseRType = rType == null ? null : PsiUtil.convertAnonymousToBaseType(rType);
|
||||
boolean leftAnonymous = PsiUtil.resolveClassInClassTypeOnly(lType) instanceof PsiAnonymousClass;
|
||||
String styledReason = reason.isEmpty() ? "" :
|
||||
String.format("<table><tr><td style=''padding-top: 10px; padding-left: 4px;''>%s</td></tr></table>", reason);
|
||||
IncompatibleTypesTooltipComposer tooltipComposer = (lTypeString, lTypeArguments, rTypeString, rTypeArguments) -> {
|
||||
lTypeString = addAnonymousIfNecessary(lType, lTypeString);
|
||||
rTypeString = addAnonymousIfNecessary(rType, rTypeString);
|
||||
return JavaErrorBundle.message("incompatible.types.html.tooltip",
|
||||
lTypeString, lTypeArguments,
|
||||
rTypeString, rTypeArguments,
|
||||
styledReason, "#" + ColorUtil.toHex(UIUtil.getContextHelpForeground()));
|
||||
};
|
||||
String toolTip = createIncompatibleTypesTooltip(baseLType, baseRType, tooltipComposer);
|
||||
IncompatibleTypesTooltipComposer tooltipComposer = (lTypeString, lTypeArguments, rTypeString, rTypeArguments) ->
|
||||
JavaErrorBundle.message("incompatible.types.html.tooltip",
|
||||
lTypeString, lTypeArguments,
|
||||
rTypeString, rTypeArguments,
|
||||
styledReason, "#" + ColorUtil.toHex(UIUtil.getContextHelpForeground()));
|
||||
String toolTip = createIncompatibleTypesTooltip(leftAnonymous ? lType : baseLType, leftAnonymous ? rType : baseRType, tooltipComposer);
|
||||
|
||||
String lTypeString = JavaHighlightUtil.formatType(lType);
|
||||
String rTypeString = JavaHighlightUtil.formatType(rType);
|
||||
String lTypeString = JavaHighlightUtil.formatType(leftAnonymous ? lType : baseLType);
|
||||
String rTypeString = JavaHighlightUtil.formatType(leftAnonymous ? rType : baseRType);
|
||||
String description = JavaErrorBundle.message("incompatible.types", lTypeString, rTypeString);
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(textRange)
|
||||
@@ -3236,22 +3234,6 @@ public final class HighlightUtil {
|
||||
.navigationShift(navigationShift);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type the type
|
||||
* @param typeString the raw type (base type of anonymous type)
|
||||
* @return String representation if `anonymous` is requried
|
||||
*/
|
||||
@NotNull
|
||||
private static String addAnonymousIfNecessary(@Nullable PsiType type,
|
||||
@NotNull String typeString) {
|
||||
if (type instanceof PsiClassType lClassType &&
|
||||
lClassType.resolve() instanceof PsiAnonymousClass) {
|
||||
typeString = ANONYMOUS + " " + typeString;
|
||||
}
|
||||
return typeString;
|
||||
}
|
||||
|
||||
public static HighlightInfo.Builder checkArrayType(PsiTypeElement type) {
|
||||
int dimensions = 0;
|
||||
for (PsiElement child = type.getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||
@@ -3321,21 +3303,17 @@ public final class HighlightUtil {
|
||||
String closeBrace = i == typeParamColumns - 1 ? ">" : ",";
|
||||
boolean showShortType = showShortType(lSubstitutedType, rSubstitutedType);
|
||||
|
||||
requiredRow.append(skipColumns ? ""
|
||||
: "<td style='padding: 0px 0px 8px 0px;'>")
|
||||
requiredRow.append(skipColumns ? "" : "<td style='padding: 0px 0px 8px 0px;'>")
|
||||
.append(lTypeParams.length == 0 ? "" : openBrace)
|
||||
.append(redIfNotMatch(lSubstitutedType, true, showShortType))
|
||||
.append(i < lTypeParams.length ? closeBrace : "")
|
||||
.append(skipColumns ? ""
|
||||
: "</td>");
|
||||
.append(skipColumns ? "" : "</td>");
|
||||
|
||||
foundRow.append(skipColumns ? ""
|
||||
: "<td style='padding: 0px 0px 0px 0px;'>")
|
||||
foundRow.append(skipColumns ? "" : "<td style='padding: 0px 0px 0px 0px;'>")
|
||||
.append(rTypeParams.length == 0 ? "" : openBrace)
|
||||
.append(redIfNotMatch(rSubstitutedType, matches, showShortType))
|
||||
.append(i < rTypeParams.length ? closeBrace : "")
|
||||
.append(skipColumns ? ""
|
||||
: "</td>");
|
||||
.append(skipColumns ? "" : "</td>");
|
||||
}
|
||||
PsiType lRawType = lType instanceof PsiClassType ? ((PsiClassType)lType).rawType() : lType;
|
||||
PsiType rRawType = rType instanceof PsiClassType ? ((PsiClassType)rType).rawType() : rType;
|
||||
@@ -3350,7 +3328,9 @@ public final class HighlightUtil {
|
||||
static boolean showShortType(@Nullable PsiType lType, @Nullable PsiType rType) {
|
||||
if (Comparing.equal(lType, rType)) return true;
|
||||
|
||||
return lType != null && rType != null && !Comparing.strEqual(lType.getPresentableText(), rType.getPresentableText());
|
||||
return lType != null && rType != null &&
|
||||
(!lType.getPresentableText().equals(rType.getPresentableText()) ||
|
||||
lType.getCanonicalText().equals(rType.getCanonicalText()));
|
||||
}
|
||||
|
||||
private static @NotNull String getReasonForIncompatibleTypes(PsiType rType) {
|
||||
@@ -3385,15 +3365,19 @@ public final class HighlightUtil {
|
||||
@NotNull
|
||||
static @NlsSafe HtmlChunk redIfNotMatch(@Nullable PsiType type, boolean matches, boolean shortType) {
|
||||
if (type == null) return HtmlChunk.empty();
|
||||
Color color;
|
||||
if (matches) {
|
||||
color = ExperimentalUI.isNewUI() ? JBUI.CurrentTheme.Editor.Tooltip.FOREGROUND : UIUtil.getToolTipForeground();
|
||||
String typeText;
|
||||
if (shortType || type instanceof PsiCapturedWildcardType) {
|
||||
typeText = PsiUtil.resolveClassInClassTypeOnly(type) instanceof PsiAnonymousClass
|
||||
? ANONYMOUS + type.getPresentableText()
|
||||
: type.getPresentableText();
|
||||
}
|
||||
else {
|
||||
color = NamedColorUtil.getErrorForeground();
|
||||
typeText = type.getCanonicalText();
|
||||
}
|
||||
return HtmlChunk.tag("font").attr("color", ColorUtil.toHtmlColor(color))
|
||||
.addText(shortType || type instanceof PsiCapturedWildcardType ? type.getPresentableText() : type.getCanonicalText());
|
||||
Color color = matches
|
||||
? ExperimentalUI.isNewUI() ? JBUI.CurrentTheme.Editor.Tooltip.FOREGROUND : UIUtil.getToolTipForeground()
|
||||
: NamedColorUtil.getErrorForeground();
|
||||
return HtmlChunk.tag("font").attr("color", ColorUtil.toHtmlColor(color)).addText(typeText);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class X {}
|
||||
class Y {
|
||||
public void main(String[] args) {
|
||||
var x = new X();
|
||||
<error descr="Incompatible types. Found: 'Y', required: 'X'">x = new Y() {}</error>;
|
||||
}
|
||||
}
|
||||
+5
-8
@@ -1,10 +1,7 @@
|
||||
class TypeObjectWithAnotherInitializer {
|
||||
class X {}
|
||||
class Y {
|
||||
public void main(String[] args) {
|
||||
var x = new X() {};
|
||||
<error descr="Incompatible types. Found: 'TypeObjectWithAnotherInitializer.Y', required: 'anonymous TypeObjectWithAnotherInitializer.X'">x = new Y()</error>;
|
||||
}
|
||||
class X {}
|
||||
class Y {
|
||||
public void main(String[] args) {
|
||||
var x = new X() {};
|
||||
<error descr="Incompatible types. Found: 'Y', required: 'anonymous X'">x = new Y()</error>;
|
||||
}
|
||||
|
||||
}
|
||||
+9
-4
@@ -99,12 +99,14 @@ public class LightAdvLVTIHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testTypeObject() {
|
||||
doTest();
|
||||
String toolTipForeground = ColorUtil.toHtmlColor(UIUtil.getToolTipForeground());
|
||||
String errorTipForeground = ColorUtil.toHtmlColor(UIUtil.getErrorForeground());
|
||||
String greyed = ColorUtil.toHtmlColor(UIUtil.getContextHelpForeground());
|
||||
String expected = "<html><table>" +
|
||||
"<tr>" +
|
||||
"<td style='padding: 0px 16px 8px 4px;color: "+greyed+"'>Required type:</td>" +
|
||||
"<td style='padding: 0px 4px 8px 0px;'>anonymous <font color=\""+toolTipForeground+"\">Object</font></td></tr>" +
|
||||
"<tr><td style='padding: 0px 16px 0px 4px;color: "+greyed+"'>Provided:</td><td style='padding: 0px 4px 0px 0px;'><font color=\""+toolTipForeground+"\">Object</font></td></tr>" +
|
||||
"<td style='padding: 0px 4px 8px 0px;'><font color=\""+toolTipForeground+"\">anonymous Object</font></td></tr>" +
|
||||
"<tr><td style='padding: 0px 16px 0px 4px;color: "+greyed+"'>Provided:</td>" +
|
||||
"<td style='padding: 0px 4px 0px 0px;'><font color=\""+errorTipForeground+"\">Object</font></td></tr>" +
|
||||
"</table>" +
|
||||
"</html>";
|
||||
|
||||
@@ -122,8 +124,9 @@ public class LightAdvLVTIHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
String expected = "<html><table>" +
|
||||
"<tr>" +
|
||||
"<td style='padding: 0px 16px 8px 4px;color: "+greyed+"'>Required type:</td>" +
|
||||
"<td style='padding: 0px 4px 8px 0px;'>anonymous <font color=\""+toolTipForeground+"\">X</font></td></tr>" +
|
||||
"<tr><td style='padding: 0px 16px 0px 4px;color: "+greyed+"'>Provided:</td><td style='padding: 0px 4px 0px 0px;'><font color=\""+errorTipForeground+"\">Y</font></td></tr>" +
|
||||
"<td style='padding: 0px 4px 8px 0px;'><font color=\""+toolTipForeground+"\">anonymous X</font></td></tr>" +
|
||||
"<tr><td style='padding: 0px 16px 0px 4px;color: "+greyed+"'>Provided:</td>" +
|
||||
"<td style='padding: 0px 4px 0px 0px;'><font color=\""+errorTipForeground+"\">Y</font></td></tr>" +
|
||||
"</table>" +
|
||||
"</html>";
|
||||
|
||||
@@ -132,6 +135,8 @@ public class LightAdvLVTIHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
.filter(info -> info.type == HighlightInfoType.ERROR)
|
||||
.forEach(info -> Assert.assertEquals(expected, info.getToolTip()));
|
||||
}
|
||||
|
||||
public void testLeftSideNotAnonymous() { doTest(); }
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
|
||||
Reference in New Issue
Block a user