diff --git a/java/java-impl/src/com/intellij/codeInsight/hints/JavaParameterHintManager.java b/java/java-impl/src/com/intellij/codeInsight/hints/JavaParameterHintManager.java index f02995a76b11..f8db4f105712 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hints/JavaParameterHintManager.java +++ b/java/java-impl/src/com/intellij/codeInsight/hints/JavaParameterHintManager.java @@ -15,6 +15,8 @@ */ package com.intellij.codeInsight.hints; +import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.TypeConversionUtil; @@ -26,18 +28,18 @@ import java.util.Collections; import java.util.List; public class JavaParameterHintManager { - + @NotNull private final List myDescriptors; public JavaParameterHintManager(@NotNull PsiCallExpression callExpression) { PsiExpression[] callArguments = getArguments(callExpression); JavaResolveResult resolveResult = callExpression.resolveMethodGenerics(); - + List descriptors = Collections.emptyList(); if (resolveResult.getElement() instanceof PsiMethod && isMethodToShowParams(callExpression, resolveResult) - && hasUnclearExpressions(callArguments)) + && hasUnclearExpressions(callArguments)) { PsiMethod method = (PsiMethod)resolveResult.getElement(); PsiParameter[] parameters = method.getParameterList().getParameters(); @@ -49,9 +51,30 @@ public class JavaParameterHintManager { private static boolean isMethodToShowParams(@NotNull PsiCallExpression callExpression, @NotNull JavaResolveResult resolveResult) { PsiElement element = resolveResult.getElement(); - if (element instanceof PsiMethod) { - PsiMethod method = (PsiMethod)element; - return !isSetter(method) && !isBuilder(callExpression, method); + if (!(element instanceof PsiMethod)) return false; + + PsiMethod method = (PsiMethod)element; + if (isSetter(method)) return false; + + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length == 1) { + if (isBuilder(callExpression, method)) return false; + + ParameterNameHintsSettings settings = ParameterNameHintsSettings.getInstance(); + if (!settings.isShowParamNameContainedInMethodName() + && isParamNameContainedInMethodName(parameters[0], method)) { + return false; + } + } + + return true; + } + + private static boolean isParamNameContainedInMethodName(@NotNull PsiParameter parameter, @NotNull PsiMethod method) { + String parameterName = parameter.getName(); + if (parameterName != null && parameterName.length() > 1) { + String methodName = method.getName(); + return StringUtil.containsIgnoreCase(methodName, parameterName); } return false; } @@ -70,7 +93,7 @@ public class JavaParameterHintManager { return false; } - + private static boolean hasSingleParameter(PsiMethod method) { return method.getParameterList().getParametersCount() == 1; } @@ -79,7 +102,7 @@ public class JavaParameterHintManager { private static boolean isSetter(PsiMethod method) { String methodName = method.getName(); if (hasSingleParameter(method) && methodName.startsWith("set") - && (methodName.length() == 3 + && (methodName.length() == 3 || methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3)))) { return true; } @@ -87,8 +110,9 @@ public class JavaParameterHintManager { } static boolean isUnclearExpression(@Nullable PsiElement callArgument) { - if (callArgument instanceof PsiLiteralExpression) + if (callArgument instanceof PsiLiteralExpression) { return true; + } if (callArgument instanceof PsiPrefixExpression) { PsiPrefixExpression expr = (PsiPrefixExpression)callArgument; @@ -97,10 +121,9 @@ public class JavaParameterHintManager { || JavaTokenType.PLUS.equals(tokenType)) && expr.getOperand() instanceof PsiLiteralExpression; } - if (callArgument instanceof PsiThisExpression - || callArgument instanceof PsiBinaryExpression - || callArgument instanceof PsiPolyadicExpression) - { + if (callArgument instanceof PsiThisExpression + || callArgument instanceof PsiBinaryExpression + || callArgument instanceof PsiPolyadicExpression) { return true; } @@ -122,13 +145,13 @@ public class JavaParameterHintManager { private static List buildDescriptorsForLiteralArguments(@NotNull PsiExpression[] callArguments, @NotNull PsiParameter[] parameters, @NotNull JavaResolveResult resolveResult) { - + List descriptors = ContainerUtil.newArrayList(); for (int i = 0; i < Math.min(callArguments.length, parameters.length); i++) { PsiExpression arg = callArguments[i]; PsiParameter param = parameters[i]; - if (isVarargParam(param.getType(), arg.getType()) && hasUnclearExpressionStartingFrom(i, callArguments) + if (isVarargParam(param.getType(), arg.getType()) && hasUnclearExpressionStartingFrom(i, callArguments) || shouldInlineParameterName(arg, param, resolveResult)) { descriptors.add(createInlayInfo(arg, param)); } @@ -141,13 +164,13 @@ public class JavaParameterHintManager { String paramName = ((methodParam.getType() instanceof PsiEllipsisType) ? "..." : "") + methodParam.getName(); return new InlayInfo(paramName, callArgument.getTextRange().getStartOffset()); } - + private static boolean shouldInlineParameterName(@NotNull PsiExpression argument, @NotNull PsiParameter parameter, @NotNull JavaResolveResult resolveResult) { PsiType argType = argument.getType(); PsiType paramType = parameter.getType(); - + if (argType != null && isUnclearExpression(argument)) { PsiType parameterType = resolveResult.getSubstitutor().substitute(paramType); return TypeConversionUtil.isAssignable(parameterType, argType); @@ -155,7 +178,7 @@ public class JavaParameterHintManager { return false; } - + private static boolean hasUnclearExpressionStartingFrom(int index, PsiExpression[] callArguments) { for (int i = index; i < callArguments.length; i++) { PsiExpression arg = callArguments[i]; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/inlays/JavaParameterNameHintsTest.kt b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/inlays/JavaParameterNameHintsTest.kt index ac7a0a89ac05..199d646d6ae3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/inlays/JavaParameterNameHintsTest.kt +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/inlays/JavaParameterNameHintsTest.kt @@ -758,4 +758,35 @@ class Test { """) } + fun `test do not show hint for name contained in method`() { + ParameterNameHintsSettings.getInstance().isShowParamNameContainedInMethodName = false + setup(""" +class Test { + void main() { + timeoutExecution(1000); + } + void timeoutExecution(int timeout) { + } +} +""") + + onLineStartingWith("timeoutExec").assertNoInlays() + } + + fun `test show if multiple params but name contained`() { + ParameterNameHintsSettings.getInstance().isShowParamNameContainedInMethodName = false + setup(""" +class Test { + void main() { + timeoutExecution(1000, "xxx"); + } + void timeoutExecution(int timeout, String message) { + } +} +""") + + onLineStartingWith("timeout") + .assertInlays("timeout->1000", "message->\"xxx\"") + } + } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.form b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.form index 262c05a321a3..2f2b64f69356 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.form +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.form @@ -1,6 +1,6 @@
- + @@ -11,7 +11,7 @@ - + @@ -54,13 +54,13 @@ - + - + @@ -86,6 +86,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java index cdf5b8732589..928ee8def358 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java @@ -30,6 +30,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.EditorTextField; import com.intellij.ui.ListCellRendererWrapper; +import com.intellij.ui.components.JBCheckBox; import com.intellij.util.containers.ContainerUtil; import org.jdesktop.swingx.combobox.ListComboBoxModel; import org.jetbrains.annotations.NotNull; @@ -48,6 +49,10 @@ public class ParameterNameHintsConfigurable extends DialogWrapper { private EditorTextField myEditorTextField; private ComboBox myCurrentLanguageCombo; + private JBCheckBox myShowWhenMultipleParamsWithSameType; + private JBCheckBox myShowIfParamNameContainedInMethod; + private JPanel myOptionsPanel; + private final Language myInitiallySelectedLanguage; private final String myNewPreselectedItem; @@ -67,6 +72,8 @@ public class ParameterNameHintsConfigurable extends DialogWrapper { setTitle("Configure Parameter Name Hints Blacklist"); init(); + + myOptionsPanel.setVisible(false); } private void updateOkEnabled() { @@ -93,6 +100,10 @@ public class ParameterNameHintsConfigurable extends DialogWrapper { String text = entry.getValue(); storeBlackListDiff(lang, text); }); + + ParameterNameHintsSettings settings = ParameterNameHintsSettings.getInstance(); + settings.setShowParamNameContainedInMethodName(myShowIfParamNameContainedInMethod.isSelected()); + settings.setShowWhenMultipleParamsWithSameType(myShowWhenMultipleParamsWithSameType.isSelected()); } private static void storeBlackListDiff(@NotNull Language language, @NotNull String text) { @@ -131,6 +142,13 @@ public class ParameterNameHintsConfigurable extends DialogWrapper { } }); + myShowIfParamNameContainedInMethod = new JBCheckBox(); + myShowWhenMultipleParamsWithSameType = new JBCheckBox(); + + ParameterNameHintsSettings settings = ParameterNameHintsSettings.getInstance(); + myShowIfParamNameContainedInMethod.setSelected(settings.isShowParamNameContainedInMethodName()); + myShowWhenMultipleParamsWithSameType.setSelected(settings.getShowWhenMultipleParamsWithSameType()); + initLanguageCombo(languages, selected); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt index f702b7501d06..ac96ea0c6dbb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt @@ -15,6 +15,8 @@ private object XmlTagHelper { val ADDED = "added" val REMOVED = "removed" val PATTERN = "pattern" + val SHOW_IF_PARAM_NAME_CONTAINED = "showIfParamNameContained" + val SHOW_WHEN_MULTIPLE_PARAMS_WITH_SAME_TYPE = "showWhenMultipleParamsWithSameType" } @@ -47,6 +49,9 @@ class ParameterNameHintsSettings : PersistentStateComponent { private val myRemovedPatterns = hashMapOf>() private val myAddedPatterns = hashMapOf>() + var isShowParamNameContainedInMethodName: Boolean = false + var showWhenMultipleParamsWithSameType: Boolean = false + fun addIgnorePattern(language: Language, pattern: String) { val patternsBefore = getAddedPatterns(language) setAddedPatterns(language, patternsBefore + pattern) @@ -76,22 +81,38 @@ class ParameterNameHintsSettings : PersistentStateComponent { blacklists.addLanguagePatternElements(language, patterns, XmlTagHelper.ADDED) } + root.getOrCreateChild(XmlTagHelper.SHOW_IF_PARAM_NAME_CONTAINED) + .setAttribute("value", isShowParamNameContainedInMethodName.toString()) + + root.getOrCreateChild(XmlTagHelper.SHOW_WHEN_MULTIPLE_PARAMS_WITH_SAME_TYPE) + .setAttribute("value", showWhenMultipleParamsWithSameType.toString()) + return root } override fun loadState(state: Element) { + myAddedPatterns.clear() + myRemovedPatterns.clear() + + isShowParamNameContainedInMethodName = false + showWhenMultipleParamsWithSameType = false + val allBlackLists = state .getChild(XmlTagHelper.BLACKLISTS) ?.getChildren(XmlTagHelper.LANGUAGE_LIST) ?: emptyList() - myAddedPatterns.clear() - myRemovedPatterns.clear() - allBlackLists.mapNotNull { blacklist -> val language = blacklist.attributeValue(XmlTagHelper.LANGUAGE) ?: return@mapNotNull myAddedPatterns[language] = blacklist.extractPatterns(XmlTagHelper.ADDED) myRemovedPatterns[language] = blacklist.extractPatterns(XmlTagHelper.REMOVED) } + + isShowParamNameContainedInMethodName = state.getBooleanValue(XmlTagHelper.SHOW_IF_PARAM_NAME_CONTAINED, true) + showWhenMultipleParamsWithSameType = state.getBooleanValue(XmlTagHelper.SHOW_WHEN_MULTIPLE_PARAMS_WITH_SAME_TYPE, false) + } + + private fun Element.getBooleanValue(childName: String, defaultValue: Boolean): Boolean { + return getChild(childName)?.getAttributeValue("value")?.toBoolean() ?: defaultValue } companion object {