IDEA-164144 Intention offers change to comparingInt for long fields

This commit is contained in:
Tagir Valeev
2016-11-21 13:08:30 +07:00
parent 94b19827bb
commit f60c60c661
14 changed files with 246 additions and 27 deletions
@@ -24,6 +24,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.siyeh.ig.psiutils.EquivalenceChecker;
import com.siyeh.ig.psiutils.MethodCallUtils;
import one.util.streamex.StreamEx;
@@ -82,18 +83,7 @@ public class ComparatorCombinatorsInspection extends BaseJavaBatchLocalInspectio
if (args.length == 2 && method != null && method.getName().equals("compare")) {
PsiClass compareClass = method.getContainingClass();
if (compareClass != null) {
if (CommonClassNames.JAVA_LANG_DOUBLE.equals(compareClass.getQualifiedName())) {
methodName = "comparingDouble";
}
else if (CommonClassNames.JAVA_LANG_INTEGER.equals(compareClass.getQualifiedName())) {
methodName = "comparingInt";
}
else if (CommonClassNames.JAVA_LANG_LONG.equals(compareClass.getQualifiedName())) {
methodName = "comparingLong";
}
else {
return;
}
methodName = getComparingMethodName(compareClass.getQualifiedName());
if (!areEquivalent(parameters, args[0], args[1])) return;
}
}
@@ -102,7 +92,9 @@ public class ComparatorCombinatorsInspection extends BaseJavaBatchLocalInspectio
PsiBinaryExpression binOp = (PsiBinaryExpression)body;
if (binOp.getOperationTokenType().equals(JavaTokenType.MINUS) &&
areEquivalent(parameters, binOp.getLOperand(), binOp.getROperand())) {
methodName = "comparingInt";
PsiType opType = binOp.getLOperand().getType();
if(opType == null) return;
methodName = getComparingMethodName(opType.getCanonicalText());
}
}
if (methodName != null) {
@@ -114,6 +106,24 @@ public class ComparatorCombinatorsInspection extends BaseJavaBatchLocalInspectio
};
}
@Contract(value = "null -> null", pure = true)
@Nullable
private static String getComparingMethodName(String type) {
if(type == null) return null;
switch(PsiTypesUtil.unboxIfPossible(type)) {
case "int":
case "short":
case "byte":
case "char":
return "comparingInt";
case "long":
return "comparingLong";
case "double":
return "comparingDouble";
}
return null;
}
@Contract("_, null, _ -> false; _, !null, null -> false")
private static boolean areEquivalent(@NotNull PsiParameter[] parameters, @Nullable PsiExpression left, @Nullable PsiExpression right) {
if (left == null || right == null) return false;
@@ -193,19 +203,7 @@ public class ComparatorCombinatorsInspection extends BaseJavaBatchLocalInspectio
PsiExpression[] args = methodCall.getArgumentList().getExpressions();
if (args.length != 2) return;
keyExtractor = args[0];
switch (className) {
case CommonClassNames.JAVA_LANG_LONG:
methodName = "comparingLong";
break;
case CommonClassNames.JAVA_LANG_INTEGER:
methodName = "comparingInt";
break;
case CommonClassNames.JAVA_LANG_DOUBLE:
methodName = "comparingDouble";
break;
default:
return;
}
methodName = getComparingMethodName(className);
}
}
}
@@ -213,8 +211,10 @@ public class ComparatorCombinatorsInspection extends BaseJavaBatchLocalInspectio
} else if(body instanceof PsiBinaryExpression) {
PsiBinaryExpression binOp = (PsiBinaryExpression)body;
if(!binOp.getOperationTokenType().equals(JavaTokenType.MINUS)) return;
methodName = "comparingInt";
keyExtractor = binOp.getLOperand();
PsiType type = keyExtractor.getType();
if(type == null) return;
methodName = getComparingMethodName(type.getCanonicalText());
}
if (methodName == null || keyExtractor == null) return;
if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
@@ -24,6 +24,7 @@ import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -94,6 +95,7 @@ public class PsiTypesUtil {
* @param type boxed java type name
* @return unboxed type name if available; same value otherwise
*/
@Contract("null -> null; !null -> !null")
@Nullable
public static String unboxIfPossible(final String type) {
if (type == null) return null;
@@ -106,6 +108,7 @@ public class PsiTypesUtil {
* @param type primitive java type name
* @return boxed type name if available; same value otherwise
*/
@Contract("null -> null; !null -> !null")
@Nullable
public static String boxIfPossible(final String type) {
if (type == null) return null;
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort(Comparator.comparingInt(d -> d.b));
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort(Comparator.comparingInt(d -> d.b));
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort(Comparator.comparingInt(d -> d.c));
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
Short s;
Byte b;
Character c;
Integer i;
Long l;
Double d;
}
void sort(List<Data> data) {
data.sort(Comparator.comparingInt(d -> d.c));
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingDouble" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort(Comparator.comparingDouble(d -> d.d));
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingLong" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort(Comparator.comparingLong(d -> d.l));
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort((d1, d2) -> Byte.comp<caret>are(d1.b, d2.b));
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort((d1, d2) -> d1.b - d2.<caret>b);
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort((d1, d2) -> d1.c - d2.<caret>c);
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingInt" "true"
import java.util.*;
public class Main {
static class Data {
Short s;
Byte b;
Character c;
Integer i;
Long l;
Double d;
}
void sort(List<Data> data) {
data.sort((d1, d2) -> d1.<caret>c - d2.c);
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingDouble" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort((d1, d2) -> d1.d - d2.<caret>d);
}
}
@@ -0,0 +1,18 @@
// "Replace with Comparator.comparingLong" "true"
import java.util.*;
public class Main {
static class Data {
short s;
byte b;
char c;
int i;
long l;
double d;
}
void sort(List<Data> data) {
data.sort((d1, d2) -> d1.l - d2.<caret>l);
}
}