mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[name hints] option to show hints for multiple parameters with the same type
This commit is contained in:
+1
-1
@@ -34,7 +34,7 @@ class JavaInlayParameterHintsProvider : InlayParameterHintsProvider {
|
||||
|
||||
override fun getParameterHints(element: PsiElement): List<InlayInfo> {
|
||||
if (element is PsiCallExpression) {
|
||||
return JavaParameterHintManager(element).descriptors
|
||||
return JavaParameterHintManager(element).descriptors.toList()
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
@@ -16,32 +16,39 @@
|
||||
package com.intellij.codeInsight.hints;
|
||||
|
||||
import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JavaParameterHintManager {
|
||||
|
||||
@NotNull
|
||||
private final List<InlayInfo> myDescriptors;
|
||||
private final Set<InlayInfo> myDescriptors;
|
||||
|
||||
public JavaParameterHintManager(@NotNull PsiCallExpression callExpression) {
|
||||
PsiExpression[] callArguments = getArguments(callExpression);
|
||||
JavaResolveResult resolveResult = callExpression.resolveMethodGenerics();
|
||||
if (!(resolveResult.getElement() instanceof PsiMethod)) {
|
||||
myDescriptors = Collections.emptySet();
|
||||
return;
|
||||
}
|
||||
|
||||
List<InlayInfo> descriptors = Collections.emptyList();
|
||||
if (resolveResult.getElement() instanceof PsiMethod
|
||||
&& isMethodToShowParams(callExpression, resolveResult)
|
||||
&& hasUnclearExpressions(callArguments))
|
||||
{
|
||||
PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
final PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
|
||||
Set<InlayInfo> descriptors = Collections.emptySet();
|
||||
if (isMethodToShowParams(callExpression, method)) {
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
descriptors = buildDescriptorsForLiteralArguments(callArguments, parameters, resolveResult);
|
||||
}
|
||||
@@ -49,11 +56,7 @@ public class JavaParameterHintManager {
|
||||
myDescriptors = descriptors;
|
||||
}
|
||||
|
||||
private static boolean isMethodToShowParams(@NotNull PsiCallExpression callExpression, @NotNull JavaResolveResult resolveResult) {
|
||||
PsiElement element = resolveResult.getElement();
|
||||
if (!(element instanceof PsiMethod)) return false;
|
||||
|
||||
PsiMethod method = (PsiMethod)element;
|
||||
private static boolean isMethodToShowParams(@NotNull PsiCallExpression callExpression, @NotNull PsiMethod method) {
|
||||
if (isSetter(method)) return false;
|
||||
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
@@ -70,6 +73,16 @@ public class JavaParameterHintManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Set<String> getDuplicatedParamTypes(PsiParameter[] parameters) {
|
||||
List<String> duplicatedTypes = Arrays
|
||||
.stream(parameters)
|
||||
.map((p) -> p.getType().getCanonicalText())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ContainerUtil.newHashSet(duplicatedTypes).forEach((e) -> duplicatedTypes.remove(e));
|
||||
return ContainerUtil.newHashSet(duplicatedTypes);
|
||||
}
|
||||
|
||||
private static boolean isParamNameContainedInMethodName(@NotNull PsiParameter parameter, @NotNull PsiMethod method) {
|
||||
String parameterName = parameter.getName();
|
||||
if (parameterName != null && parameterName.length() > 1) {
|
||||
@@ -137,42 +150,71 @@ public class JavaParameterHintManager {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<InlayInfo> getDescriptors() {
|
||||
public Set<InlayInfo> getDescriptors() {
|
||||
return myDescriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<InlayInfo> buildDescriptorsForLiteralArguments(@NotNull PsiExpression[] callArguments,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull JavaResolveResult resolveResult) {
|
||||
private static Set<InlayInfo> buildDescriptorsForLiteralArguments(@NotNull PsiExpression[] callArguments,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull JavaResolveResult resolveResult) {
|
||||
|
||||
final Set<InlayInfo> descriptors = ContainerUtil.newHashSet();
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
|
||||
if (ParameterNameHintsSettings.getInstance().isShowForParamsWithSameType()) {
|
||||
final List<InlayInfo> hintsForNonLiterals = getHintsForParamsWithSameType(callArguments, parameters, substitutor);
|
||||
descriptors.addAll(hintsForNonLiterals);
|
||||
}
|
||||
|
||||
List<InlayInfo> 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)
|
||||
|| shouldInlineParameterName(arg, param, resolveResult)) {
|
||||
|| isUnclearExpression(arg) && isAssignable(arg, param, substitutor)) {
|
||||
descriptors.add(createInlayInfo(arg, param));
|
||||
}
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
private static List<InlayInfo> getHintsForParamsWithSameType(@NotNull PsiExpression[] callArguments,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull PsiSubstitutor substitutor)
|
||||
{
|
||||
final Set<String> duplicatedTypes = getDuplicatedParamTypes(parameters);
|
||||
|
||||
final int minArraySize = Math.min(callArguments.length, parameters.length);
|
||||
List<PsiExpression> args = ContainerUtil.list(callArguments).subList(0, minArraySize);
|
||||
List<PsiParameter> params = ContainerUtil.list(parameters).subList(0, minArraySize);
|
||||
|
||||
return StreamEx
|
||||
.zip(args, params, (a, b) -> Pair.create(a, b))
|
||||
.filter((pair) -> {
|
||||
PsiParameter param = pair.getSecond();
|
||||
return duplicatedTypes.contains(param.getType().getCanonicalText());
|
||||
})
|
||||
.filter((pair) -> isAssignable(pair.first, pair.second, substitutor))
|
||||
.map((pair) -> createInlayInfo(pair.first, pair.second))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static InlayInfo createInlayInfo(@NotNull PsiExpression callArgument, @NotNull PsiParameter methodParam) {
|
||||
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) {
|
||||
private static boolean isAssignable(@NotNull PsiExpression argument,
|
||||
@NotNull PsiParameter parameter,
|
||||
@NotNull PsiSubstitutor substitutor) {
|
||||
PsiType argType = argument.getType();
|
||||
PsiType paramType = parameter.getType();
|
||||
|
||||
if (argType != null && isUnclearExpression(argument)) {
|
||||
PsiType parameterType = resolveResult.getSubstitutor().substitute(paramType);
|
||||
if (argType != null) {
|
||||
PsiType parameterType = substitutor.substitute(paramType);
|
||||
return TypeConversionUtil.isAssignable(parameterType, argType);
|
||||
}
|
||||
|
||||
|
||||
+17
@@ -789,4 +789,21 @@ class Test {
|
||||
.assertInlays("timeout->1000", "message->\"xxx\"")
|
||||
}
|
||||
|
||||
fun `test show same params`() {
|
||||
ParameterNameHintsSettings.getInstance().isShowForParamsWithSameType = true
|
||||
setup("""
|
||||
class Test {
|
||||
void main() {
|
||||
String c = "c";
|
||||
String d = "d";
|
||||
test(c, d);
|
||||
}
|
||||
void test(String parent, String child) {
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
onLineStartingWith("test").assertInlays("parent->c", "child->d")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.hints
|
||||
|
||||
class InlayInfo(val text: String, val offset: Int)
|
||||
data class InlayInfo(val text: String, val offset: Int)
|
||||
|
||||
open class MethodInfo(val fullyQualifiedName: String, val paramNames: List<String>) {
|
||||
|
||||
|
||||
+3
-3
@@ -73,7 +73,7 @@ public class ParameterNameHintsConfigurable extends DialogWrapper {
|
||||
setTitle("Configure Parameter Name Hints Blacklist");
|
||||
init();
|
||||
|
||||
myOptionsPanel.setVisible(false);
|
||||
myOptionsPanel.setVisible(true);
|
||||
}
|
||||
|
||||
private void updateOkEnabled() {
|
||||
@@ -103,7 +103,7 @@ public class ParameterNameHintsConfigurable extends DialogWrapper {
|
||||
|
||||
ParameterNameHintsSettings settings = ParameterNameHintsSettings.getInstance();
|
||||
settings.setShowParamNameContainedInMethodName(myShowIfParamNameContainedInMethod.isSelected());
|
||||
settings.setShowWhenMultipleParamsWithSameType(myShowWhenMultipleParamsWithSameType.isSelected());
|
||||
settings.setShowForParamsWithSameType(myShowWhenMultipleParamsWithSameType.isSelected());
|
||||
}
|
||||
|
||||
private static void storeBlackListDiff(@NotNull Language language, @NotNull String text) {
|
||||
@@ -147,7 +147,7 @@ public class ParameterNameHintsConfigurable extends DialogWrapper {
|
||||
|
||||
ParameterNameHintsSettings settings = ParameterNameHintsSettings.getInstance();
|
||||
myShowIfParamNameContainedInMethod.setSelected(settings.isShowParamNameContainedInMethodName());
|
||||
myShowWhenMultipleParamsWithSameType.setSelected(settings.getShowWhenMultipleParamsWithSameType());
|
||||
myShowWhenMultipleParamsWithSameType.setSelected(settings.isShowForParamsWithSameType());
|
||||
|
||||
initLanguageCombo(languages, selected);
|
||||
}
|
||||
|
||||
+4
-4
@@ -50,7 +50,7 @@ class ParameterNameHintsSettings : PersistentStateComponent<Element> {
|
||||
private val myAddedPatterns = hashMapOf<String, Set<String>>()
|
||||
|
||||
var isShowParamNameContainedInMethodName: Boolean = false
|
||||
var showWhenMultipleParamsWithSameType: Boolean = false
|
||||
var isShowForParamsWithSameType: Boolean = false
|
||||
|
||||
fun addIgnorePattern(language: Language, pattern: String) {
|
||||
val patternsBefore = getAddedPatterns(language)
|
||||
@@ -85,7 +85,7 @@ class ParameterNameHintsSettings : PersistentStateComponent<Element> {
|
||||
.setAttribute("value", isShowParamNameContainedInMethodName.toString())
|
||||
|
||||
root.getOrCreateChild(XmlTagHelper.SHOW_WHEN_MULTIPLE_PARAMS_WITH_SAME_TYPE)
|
||||
.setAttribute("value", showWhenMultipleParamsWithSameType.toString())
|
||||
.setAttribute("value", isShowForParamsWithSameType.toString())
|
||||
|
||||
return root
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class ParameterNameHintsSettings : PersistentStateComponent<Element> {
|
||||
myRemovedPatterns.clear()
|
||||
|
||||
isShowParamNameContainedInMethodName = false
|
||||
showWhenMultipleParamsWithSameType = false
|
||||
isShowForParamsWithSameType = false
|
||||
|
||||
val allBlackLists = state
|
||||
.getChild(XmlTagHelper.BLACKLISTS)
|
||||
@@ -108,7 +108,7 @@ class ParameterNameHintsSettings : PersistentStateComponent<Element> {
|
||||
}
|
||||
|
||||
isShowParamNameContainedInMethodName = state.getBooleanValue(XmlTagHelper.SHOW_IF_PARAM_NAME_CONTAINED, true)
|
||||
showWhenMultipleParamsWithSameType = state.getBooleanValue(XmlTagHelper.SHOW_WHEN_MULTIPLE_PARAMS_WITH_SAME_TYPE, false)
|
||||
isShowForParamsWithSameType = state.getBooleanValue(XmlTagHelper.SHOW_WHEN_MULTIPLE_PARAMS_WITH_SAME_TYPE, false)
|
||||
}
|
||||
|
||||
private fun Element.getBooleanValue(childName: String, defaultValue: Boolean): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user