-
Notifications
You must be signed in to change notification settings - Fork 690
/
Copy pathVarCanBeUsedCheck.java
172 lines (127 loc) · 5.08 KB
/
VarCanBeUsedCheck.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package checks;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
class MyTestClass {}
interface Interface {}
class Clazz implements Interface {}
public class VarCanBeUsedCheck {
public static final MyTestClass MyTest = new MyTestClass(); // Compliant
void f(int[] array) {
String undefinedString;
String s = "ABC"; // Noncompliant
String s1 = new String("ABC"); // Noncompliant {{Declare this local variable with "var" instead.}}
// ^^
int i = 10; // Noncompliant
long l = 10L; // Noncompliant
ArrayList<String> arrayList = new ArrayList<>(5); // Compliant
List<String> list = new ArrayList<>(5); // Compliant
int sum = list.stream().mapToInt(String::length).sum(); // Compliant, too many calls
String format = String.format("%s %s %s", "a", "b", "c"); // Noncompliant
Object o = new Object(); // Noncompliant
Object ooo = getObject(); // Noncompliant
Object oooo = getO(); // Compliant, not obvious from a method name
Interface inter = new Clazz(); // Compliant
var arrayList1 = new ArrayList<>(); // Compliant
var varObject = getObject(); // Compliant
var sss = "STRING"; // Compliant
for (int j = 0, length = array.length; j <= length; j++) { // Compliant, 'var' not allowed here
}
for (int index = 0; index <= array.length; index++) { // Noncompliant
}
for (var j = 0; j <= array.length; j++) { // Compliant
}
int length = "AbCDE".length(); // Compliant, primitive not initialised with a literal
var length1 = "AbCDE".length(); // Compliant
long u = System.currentTimeMillis(), uu = System.nanoTime(); // Compliant, 'var' not allowed here
long u1 = System.currentTimeMillis(), // Compliant, 'var' not allowed here
uu1 = System.nanoTime(); // Compliant, 'var' not allowed here
char c = i == 3 ? 0 : "hdr".charAt(i); // Compliant, despite it's possible here, ternary operator may bring confusion in understanding the inferred type
byte[] input = new byte[array.length]; // Noncompliant
var input2 = new byte[array.length]; // Compliant
String[] arrayInit = new String[]{"A", "B", "C"}; // Noncompliant
var arrayInit2 = new String[]{"A", "B", "C"}; // Compliant
String[] arrayInit3 = {"A", "B", "C"}; // Compliant, for array initializer, without type, it is not possible to change to var
//var arrayInit4 = {"A", "B", "C"}; does not compile, see JEP 286: Poly expressions that require such a type will trigger an error
Abc abc = Abc.getAbc(); // Noncompliant
Abc abavababab = Abc.getAbc(); // Noncompliant
var varAbc = Abc.getAbc(); // Compliant
Abc myCustom = varAbc; // Noncompliant
// When the initializer is a lambda, you have to cast the rhs. The result is not really cleaner and should not be reported.
Consumer consumer = (str) -> System.out.println("s" + str); // Compliant
var consumer2 = (Consumer)(str) -> System.out.println("s" + str); // Compliant: not cleaner
Consumer consumer3 = (str) -> { // Compliant
var a = "A";
System.out.println(a + str);
};
Consumer<String> consumer4 = ((str) -> System.out.println("s" + str)); // Compliant
Consumer<String> consumer5 = (str) -> System.out.println("s" + str); // Compliant, excluded by both parameterized type and lambda in rhs.
// Same applies to functions:
Function function1 = VarCanBeUsedCheck::objectToObject; // Compliant
Function function2 = this::objectToObject2; // Compliant
}
class MyType {
void f() {
MyType myType = getValue(); // Compliant, see next two lines
var myType2 = getValue(); // Type is "Object"
var myType3 = (MyType) getValue(); // Type is correct, but acceptable to not use var here
}
<T> T getValue() {
return null;
}
}
void testFile(File file) {
try (FileInputStream in = new FileInputStream(file)) // Noncompliant
{
in.read();
}
catch (IOException e)
{
}
try (var in = new FileInputStream(file)) // Compliant
{
in.read();
}
catch (IOException e)
{
}
}
private Object getObject() {
return new Object();
}
private Object getO() {
return new Object();
}
static Object objectToObject(Object o) {
return o;
}
Object objectToObject2(Object o) {
return o;
}
}
class VarCanBeUsedInLambdas {
public static final Comparator<Integer> COMPARATOR = (e1, e2) -> {
int compare = Integer.compare(e1, e2); // Noncompliant {{Declare this local variable with "var" instead.}}
return compare != 0 ? compare : Integer.compare(e2, e1);
};
public static int foo() {
java.util.function.IntSupplier supplier = () -> {
var sum = 0;
for (int i = 0; i < 10; i++) { // Noncompliant {{Declare this local variable with "var" instead.}}
sum += i;
}
return sum;
};
return supplier.getAsInt();
}
}
class Abc {
static Abc getAbc() {
return new Abc();
}
}