[Inline Param Name Hints] hints shown for single parameter methods, except setters and well know method names like "println", "get", "contains"...

This commit is contained in:
Yaroslav Lepenkin
2016-09-28 17:03:19 +03:00
parent 1382f2f474
commit 669e4e1c4d
2 changed files with 83 additions and 23 deletions
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -38,6 +37,16 @@ public class ParameterNameHintsManager {
Couple.of("key", "value"),
Couple.of("min", "max")
);
private static final List<String> COMMON_METHODS = ContainerUtil.newArrayList(
"get",
"set",
"indexOf",
"contains",
"append",
"print",
"println"
);
@NotNull
private final List<InlayInfo> myDescriptors;
@@ -45,12 +54,12 @@ public class ParameterNameHintsManager {
public ParameterNameHintsManager(@NotNull PsiCallExpression callExpression) {
PsiExpression[] callArguments = getArguments(callExpression);
JavaResolveResult resolveResult = callExpression.resolveMethodGenerics();
EditorSettingsExternalizable settings = EditorSettingsExternalizable.getInstance();
List<InlayInfo> descriptors = Collections.emptyList();
if (callArguments.length >= settings.getMinArgsToShow() &&
hasLiteralExpression(callArguments) &&
resolveResult.getElement() instanceof PsiMethod) {
if (resolveResult.getElement() instanceof PsiMethod
&& isMethodToShowParams(resolveResult)
&& hasUnclearExpressions(callArguments))
{
PsiMethod method = (PsiMethod)resolveResult.getElement();
PsiParameter[] parameters = method.getParameterList().getParameters();
descriptors = buildDescriptorsForLiteralArguments(callArguments, parameters, resolveResult);
@@ -59,6 +68,30 @@ public class ParameterNameHintsManager {
myDescriptors = descriptors;
}
private static boolean isMethodToShowParams(JavaResolveResult resolveResult) {
PsiElement element = resolveResult.getElement();
if (element instanceof PsiMethod) {
PsiMethod method = (PsiMethod)element;
return !isSetter(method) && !isCommonMethod(method);
}
return false;
}
private static boolean isCommonMethod(PsiMethod method) {
String methodName = method.getName();
return COMMON_METHODS.stream().anyMatch((name) -> methodName.equals(name));
}
private static boolean isSetter(PsiMethod method) {
String methodName = method.getName();
if (method.getParameterList().getParametersCount() == 1
&& methodName.startsWith("set")
&& methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3))) {
return true;
}
return false;
}
static boolean isUnclearExpression(@Nullable PsiElement callArgument) {
if (callArgument instanceof PsiLiteralExpression)
return true;
@@ -108,11 +141,7 @@ public class ParameterNameHintsManager {
index++;
}
if (ContainerUtil.find(descriptors, hint -> hasProperLength(hint.getText())) != null) {
return descriptors;
}
return ContainerUtil.emptyList();
return descriptors;
}
@NotNull
@@ -150,7 +179,7 @@ public class ParameterNameHintsManager {
PsiType argType = argument.getType();
PsiType paramType = parameter.getType();
if (isVarargParam(paramType, argType) && hasLiteralInVarargs(paramIndex, callArguments)) {
if (isVarargParam(paramType, argType) && hasUnclearExpression(paramIndex, callArguments)) {
return true;
}
@@ -161,13 +190,8 @@ public class ParameterNameHintsManager {
return false;
}
private static boolean hasProperLength(@Nullable String paramName) {
final int minLength = EditorSettingsExternalizable.getInstance().getMinParamNameLengthToShow();
return paramName != null && paramName.length() >= minLength;
}
private static boolean hasLiteralInVarargs(int index, PsiExpression[] callArguments) {
private static boolean hasUnclearExpression(int index, PsiExpression[] callArguments) {
for (int i = index; i < callArguments.length; i++) {
PsiExpression arg = callArguments[i];
if (isUnclearExpression(arg)) return true;
@@ -180,7 +204,7 @@ public class ParameterNameHintsManager {
return param instanceof PsiEllipsisType && TypeConversionUtil.isAssignable(deepType, argument);
}
private static boolean hasLiteralExpression(@NotNull PsiExpression[] arguments) {
private static boolean hasUnclearExpressions(@NotNull PsiExpression[] arguments) {
for (PsiExpression argument : arguments) {
if (isUnclearExpression(argument)) return true;
}
@@ -140,7 +140,7 @@ public class VarArgTest {
}
""")
onLineStartingWith("testBooleanVarargs").assertNoInlays()
onLineStartingWith("testBooleanVarargs").assertInlays("test->13")
}
fun `test multiple vararg hint`() {
@@ -179,7 +179,7 @@ public class CharSymbol {
}
""")
onLineStartingWith("count").assertNoInlays()
onLineStartingWith("count").assertInlays("t->1", "fa->false")
}
fun `test do not inline known subsequent parameter names`() {
@@ -274,12 +274,44 @@ public class Test {
""")
onLineStartingWith("System")
.assertInlays("""x->"AAA"""")
.assertNoInlays()
onLineStartingWith("main(t")
.assertInlays("isActive->true", "requestFocus->false", "xoo->2")
}
fun `test ignored methods`() {
setup("""
public class Test {
public void main() {
println("A");
print("A");
get(1);
set(1, new Object());
setNewIndex(10);
"sss".contains("s");
append("sdfsdf");
clearStatus(false);
}
void print(String s) {}
void println(String s) {}
void get(int index) {}
void set(int index, Object object) {}
void append(String s) {}
void clearStatus(boolean updatedRecently) {}
}
""")
val inlays = getInlays()
assertThat(inlays).hasSize(1)
assertThat(inlays[0].offset).isEqualTo(myFixture.editor.document.text.indexOf("false"))
}
fun `test hints for generic arguments`() {
val settings = EditorSettingsExternalizable.getInstance()
settings.minArgsToShow = 1
@@ -443,6 +475,10 @@ public class VarArgTest {
.assertInlays("test->this", "endIndex->1000")
}
private fun getInlays(): List<Inlay> {
val editor = myFixture.editor
return editor.inlayModel.getInlineElementsInRange(0, editor.document.textLength)
}
private fun onLineStartingWith(text: String): InlayAssert {
val range = getLineRangeStartingWith(text)