diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 247c03005a92..8c1bc66a7351 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.daemon.impl.analysis; import com.intellij.codeInsight.ExceptionUtil; +import com.intellij.codeInsight.daemon.DaemonBundle; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.daemon.impl.HighlightInfoType; @@ -28,6 +29,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -59,6 +61,7 @@ import java.util.List; */ public class HighlightMethodUtil { private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance(); + public static final String MISMATCH_COLOR = UIUtil.isUnderDarcula() ? "ff6464" : "red"; private HighlightMethodUtil() { } @@ -337,7 +340,7 @@ public class HighlightMethodUtil { if (isDummy) return null; HighlightInfo highlightInfo; - PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); if (resolved instanceof PsiMethod && resolveResult.isValidResult()) { TextRange fixRange = getFixRange(methodCall); highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange); @@ -363,9 +366,19 @@ public class HighlightMethodUtil { String containerName = parent == null ? "" : HighlightMessageUtil.getSymbolName(parent, substitutor); String argTypes = buildArgTypesList(list); String description = JavaErrorMessages.message("wrong.method.arguments", methodName, containerName, argTypes); - String toolTip = parent instanceof PsiClass && !ApplicationManager.getApplication().isUnitTestMode() ? - createMismatchedArgumentsHtmlTooltip(candidateInfo, list) : description; - highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(list).description(description).escapedToolTip(toolTip).navigationShift(+1).create(); + final Ref elementToHighlight = new Ref(list); + String toolTip; + if (parent instanceof PsiClass && !ApplicationManager.getApplication().isUnitTestMode()) { + toolTip = buildOneLineMismatchDescription(list, candidateInfo, elementToHighlight); + if (toolTip == null) { + toolTip = createMismatchedArgumentsHtmlTooltip(candidateInfo, list); + } + } + else { + toolTip = description; + } + highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(elementToHighlight.get()) + .description(description).escapedToolTip(toolTip).navigationShift(+1).create(); if (highlightInfo != null) { registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper); } @@ -403,6 +416,46 @@ public class HighlightMethodUtil { return highlightInfo; } + private static String buildOneLineMismatchDescription(final PsiExpressionList list, + final MethodCandidateInfo candidateInfo, + final Ref elementToHighlight) { + final PsiExpression[] expressions = list.getExpressions(); + final PsiMethod resolvedMethod = candidateInfo.getElement(); + final PsiSubstitutor substitutor = candidateInfo.getSubstitutor(); + final PsiParameter[] parameters = resolvedMethod.getParameterList().getParameters(); + if (expressions.length == parameters.length && parameters.length > 1) { + int idx = -1; + for (int i = 0; i < expressions.length; i++) { + PsiExpression expression = expressions[i]; + if (!TypeConversionUtil.areTypesAssignmentCompatible(substitutor.substitute(parameters[i].getType()), expression)) { + if (idx != -1) { + idx = -1; + break; + } + else { + idx = i; + } + } + } + + if (idx > -1) { + final PsiExpression wrongArg = expressions[idx]; + final PsiType argType = wrongArg.getType(); + if (argType != null) { + elementToHighlight.set(wrongArg); + final String message = JavaErrorMessages + .message("incompatible.call.types", idx + 1, substitutor.substitute(parameters[idx].getType()).getCanonicalText(), argType.getCanonicalText()); + + return XmlStringUtil.wrapInHtml("" + message + + " " + DaemonBundle.message("inspection.extended.description") + ""); + } + } + } + return null; + } + static boolean isDummyConstructorCall(PsiMethodCallExpression methodCall, PsiResolveHelper resolveHelper, PsiExpressionList list, @@ -821,7 +874,7 @@ public class HighlightMethodUtil { PsiType type = expression.getType(); boolean showShort = showShortType(i, parameters, expressions, substitutor); - @NonNls String mismatchColor = showShort ? null : UIUtil.isUnderDarcula() ? "ff6464" : "red"; + @NonNls String mismatchColor = showShort ? null : MISMATCH_COLOR; ms += " " + "" + (i == 0 ? "(" : "") + "" + XmlStringUtil.escapeString(showShort ? type.getPresentableText() : JavaHighlightUtil.formatType(type)) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/AssignmentTooltipLinkHandler.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/AssignmentTooltipLinkHandler.java new file mode 100644 index 000000000000..906d25acb1de --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/AssignmentTooltipLinkHandler.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 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 com.intellij.codeInsight.intention.impl.config; + +import com.intellij.codeInsight.highlighting.TooltipLinkHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Handles tooltip links in format #assignment/escaped_full_tooltip_text. + * On a click comparison table opens. + */ +public class AssignmentTooltipLinkHandler extends TooltipLinkHandler { + @Nullable + @Override + public String getDescription(@NotNull String refSuffix, @NotNull Editor editor) { + return StringUtil.unescapeXml(refSuffix); + } +} diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index 2ae02e90adbf..d8caec0670ca 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -219,6 +219,7 @@ exception.already.caught.warn=Unreachable section: {1, choice, 0#exception|2#exc not.a.statement=Not a statement invalid.statement=Invalid statement incompatible.types=Incompatible types. Found: ''{1}'', required: ''{0}'' +incompatible.call.types=Wrong {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} argument type. Found: ''{2}'', required: ''{1}'' valid.switch.selector.types=byte, char, short or int valid.switch.17.selector.types=char, byte, short, int, Character, Byte, Short, Integer, String, or an enum dot.expected.after.super.or.this='.' expected diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java index 7b3a3ce4cbc7..d8f3439727b7 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java @@ -33,6 +33,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.Html; import com.intellij.util.ui.UIUtil; import com.intellij.xml.util.XmlStringUtil; import gnu.trove.THashSet; @@ -143,7 +144,7 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP if (ref != null) { String description = TooltipLinkHandlerEP.getDescription(ref, editor); if (description != null) { - description = DefaultInspectionToolPresentation.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(description)); + description = DefaultInspectionToolPresentation.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(new Html(description).setKeepFont(true))); text += UIUtil.getHtmlBody(problem).replace(DaemonBundle.message("inspection.extended.description"), DaemonBundle.message("inspection.collapse.description")) + END_MARKER + "

" + description + UIUtil.BORDER_LINE; diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 8a26f04cde6d..911c63ae74f8 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1490,6 +1490,7 @@ +