Java: Inspection that checks if a field or method accessed via reflection does exist and is visible (IDEA-168837)

This commit is contained in:
Pavel Dolgov
2017-04-24 13:00:35 +03:00
parent 3b894ac36e
commit b263e82d09
15 changed files with 844 additions and 8 deletions
@@ -66,7 +66,11 @@ class ConstructorParamCount {
Constructor m = cls.getConstructor(new Class[0]);
m.newInstance(new Object[0]);
m.newInstance(new Object[]{});
m.newInstance(<warning descr="Empty array is expected">new Object[] {"abc"}</warning>);
m = cls.getConstructor(new Class[]{});
m.newInstance(new Object[]{});
}
class Test {
@@ -67,7 +67,11 @@ class MethodParamCount {
Method m = cls.getMethod("m0", new Class[0]);
m.invoke(obj, new Object[0]);
m.invoke(obj, new Object[]{});
m.invoke(obj, <warning descr="Empty array is expected">new Object[] {"abc"}</warning>);
m = cls.getMethod("m0", new Class[]{});
m.invoke(obj, new Object[]{});
}
static class Test {
@@ -0,0 +1,42 @@
class ConstructorExists {
void foo(Object o, Class<?> c) throws Exception {
Class ca = A.class;
ca.getConstructor(int.class);
ca.getConstructor<warning descr="Constructor is not public">(float.class)</warning>;
ca.getConstructor<warning descr="Constructor is not public">(boolean.class)</warning>;
ca.getConstructor<warning descr="Constructor is not public">(String.class)</warning>;
ca.getConstructor<warning descr="Cannot resolve constructor with specified argument types">(Exception.class)</warning>;
ca.getConstructor(int.class, boolean.class, String.class);
ca.getConstructor(int.class, c, String.class);
ca.getConstructor<warning descr="Cannot resolve constructor with specified argument types">(int.class, o.getClass(), String.class)</warning>;
ca.getDeclaredConstructor(int.class);
ca.getDeclaredConstructor(float.class);
ca.getDeclaredConstructor(boolean.class);
ca.getDeclaredConstructor(String.class);
ca.getDeclaredConstructor<warning descr="Cannot resolve constructor with specified argument types">(Exception.class)</warning>;
ca.getDeclaredConstructor(int.class, boolean.class, String.class);
ca.getDeclaredConstructor(int.class, c, String.class);
ca.getDeclaredConstructor<warning descr="Cannot resolve constructor with specified argument types">(int.class, o.getClass(), String.class)</warning>;
C.class.getConstructor(int.class);
C.class.getConstructor<warning descr="Cannot resolve constructor with specified argument types">(boolean.class)</warning>;
}
static class A {
public A(int n) {}
protected A(float f) {}
A(boolean b) {}
private A(String s) {}
public A(int n, boolean b, String s) {}
public A(int n, boolean b, float f) {}
}
static final class C extends A {
public C(int n) { super(n); }
}
}
@@ -0,0 +1,42 @@
class Constructors {
void foo(Object o, Class<?> c) throws Exception {
Class ca = A.class;
ca.getConstructor(int.class);
ca.getConstructor<warning descr="Constructor is not public">(float.class)</warning>;
ca.getConstructor<warning descr="Constructor is not public">(boolean.class)</warning>;
ca.getConstructor<warning descr="Constructor is not public">(String.class)</warning>;
ca.getConstructor(Exception.class);
ca.getConstructor(int.class, boolean.class, String.class);
ca.getConstructor(int.class, c, String.class);
ca.getConstructor(int.class, o.getClass(), String.class);
ca.getDeclaredConstructor(int.class);
ca.getDeclaredConstructor(float.class);
ca.getDeclaredConstructor(boolean.class);
ca.getDeclaredConstructor(String.class);
ca.getDeclaredConstructor(Exception.class);
ca.getDeclaredConstructor(int.class, boolean.class, String.class);
ca.getDeclaredConstructor(int.class, c, String.class);
ca.getDeclaredConstructor(int.class, o.getClass(), String.class);
C.class.getConstructor(int.class);
C.class.getConstructor<warning descr="Cannot resolve constructor with specified argument types">(boolean.class)</warning>;
}
static class A {
public A(int n) {}
protected A(float f) {}
A(boolean b) {}
private A (String s) {}
public A(int n, boolean b, String s) {}
public A(int n, boolean b, float f) {}
}
static final class C extends A {
public C(int n) { super(n); }
}
}
@@ -0,0 +1,67 @@
class Fields {
void foo() throws Exception {
Class ca = A.class;
Class cb = B.class;
ca.getField("a1");
ca.getField(<warning descr="Field 'a2' is not public">"a2"</warning>);
ca.getField(<warning descr="Field 'a3' is not public">"a3"</warning>);
ca.getField(<warning descr="Field 'a4' is not public">"a4"</warning>);
ca.getField(<warning descr="Cannot resolve field 'b1'">"b1"</warning>);
ca.getField(<warning descr="Cannot resolve field 'b2'">"b2"</warning>);
ca.getField(<warning descr="Cannot resolve field 'b3'">"b3"</warning>);
ca.getField(<warning descr="Cannot resolve field 'b4'">"b4"</warning>);
cb.getField("a1");
cb.getField(<warning descr="Field 'a2' is not public">"a2"</warning>);
cb.getField(<warning descr="Field 'a3' is not public">"a3"</warning>);
cb.getField(<warning descr="Field 'a4' is not public">"a4"</warning>);
cb.getField("b1");
cb.getField(<warning descr="Field 'b2' is not public">"b2"</warning>);
cb.getField(<warning descr="Field 'b3' is not public">"b3"</warning>);
cb.getField(<warning descr="Field 'b4' is not public">"b4"</warning>);
ca.getDeclaredField("a1");
ca.getDeclaredField("a2");
ca.getDeclaredField("a3");
ca.getDeclaredField("a4");
ca.getDeclaredField(<warning descr="Cannot resolve field 'b1'">"b1"</warning>);
ca.getDeclaredField(<warning descr="Cannot resolve field 'b2'">"b2"</warning>);
ca.getDeclaredField(<warning descr="Cannot resolve field 'b3'">"b3"</warning>);
ca.getDeclaredField(<warning descr="Cannot resolve field 'b4'">"b4"</warning>);
cb.getDeclaredField(<warning descr="Field 'a1' is not declared in class 'Fields.B'">"a1"</warning>);
cb.getDeclaredField(<warning descr="Field 'a2' is not declared in class 'Fields.B'">"a2"</warning>);
cb.getDeclaredField(<warning descr="Field 'a3' is not declared in class 'Fields.B'">"a3"</warning>);
cb.getDeclaredField(<warning descr="Field 'a4' is not declared in class 'Fields.B'">"a4"</warning>);
cb.getDeclaredField("b1");
cb.getDeclaredField("b2");
cb.getDeclaredField("b3");
cb.getDeclaredField("b4");
C.class.getField("c");
C.class.getField(<warning descr="Cannot resolve field 'd'">"d"</warning>);
}
static class A {
public int a1;
protected int a2;
int a3;
private int a4;
}
static class B extends A {
public int b1;
protected int b2;
int b3;
private int b4;
}
static final class C extends A {
public int c;
}
}
@@ -0,0 +1,67 @@
class Fields {
void foo() throws Exception {
Class ca = A.class;
Class cb = B.class;
ca.getField("a1");
ca.getField(<warning descr="Field 'a2' is not public">"a2"</warning>);
ca.getField(<warning descr="Field 'a3' is not public">"a3"</warning>);
ca.getField(<warning descr="Field 'a4' is not public">"a4"</warning>);
ca.getField("b1");
ca.getField("b2");
ca.getField("b3");
ca.getField("b4");
cb.getField("a1");
cb.getField(<warning descr="Field 'a2' is not public">"a2"</warning>);
cb.getField(<warning descr="Field 'a3' is not public">"a3"</warning>);
cb.getField(<warning descr="Field 'a4' is not public">"a4"</warning>);
cb.getField("b1");
cb.getField(<warning descr="Field 'b2' is not public">"b2"</warning>);
cb.getField(<warning descr="Field 'b3' is not public">"b3"</warning>);
cb.getField(<warning descr="Field 'b4' is not public">"b4"</warning>);
ca.getDeclaredField("a1");
ca.getDeclaredField("a2");
ca.getDeclaredField("a3");
ca.getDeclaredField("a4");
ca.getDeclaredField("b1");
ca.getDeclaredField("b2");
ca.getDeclaredField("b3");
ca.getDeclaredField("b4");
cb.getDeclaredField(<warning descr="Field 'a1' is not declared in class 'Fields.B'">"a1"</warning>);
cb.getDeclaredField(<warning descr="Field 'a2' is not declared in class 'Fields.B'">"a2"</warning>);
cb.getDeclaredField(<warning descr="Field 'a3' is not declared in class 'Fields.B'">"a3"</warning>);
cb.getDeclaredField(<warning descr="Field 'a4' is not declared in class 'Fields.B'">"a4"</warning>);
cb.getDeclaredField("b1");
cb.getDeclaredField("b2");
cb.getDeclaredField("b3");
cb.getDeclaredField("b4");
C.class.getField("c");
C.class.getField(<warning descr="Cannot resolve field 'd'">"d"</warning>);
}
static class A {
public int a1;
protected int a2;
int a3;
private int a4;
}
static class B extends A {
public int b1;
protected int b2;
int b3;
private int b4;
}
static final class C extends A {
public int c;
}
}
@@ -0,0 +1,98 @@
class MethodExists {
void foo() throws Exception {
Class ca = A.class;
Class cb = B.class;
ca.getMethod("a1", int.class);
ca.getMethod(<warning descr="Method 'a2' is not public">"a2"</warning>, int.class);
ca.getMethod(<warning descr="Method 'a3' is not public">"a3"</warning>, int.class);
ca.getMethod(<warning descr="Method 'a4' is not public">"a4"</warning>, int.class);
ca.getMethod(<warning descr="Cannot resolve method 'b1'">"b1"</warning>, int.class);
ca.getMethod(<warning descr="Cannot resolve method 'b2'">"b2"</warning>, int.class);
ca.getMethod(<warning descr="Cannot resolve method 'b3'">"b3"</warning>, int.class);
ca.getMethod(<warning descr="Cannot resolve method 'b4'">"b4"</warning>, int.class);
cb.getMethod("a1", int.class);
cb.getMethod(<warning descr="Method 'a2' is not public">"a2"</warning>, int.class);
cb.getMethod(<warning descr="Method 'a3' is not public">"a3"</warning>, int.class);
cb.getMethod(<warning descr="Method 'a4' is not public">"a4"</warning>, int.class);
cb.getMethod("b1", int.class);
cb.getMethod(<warning descr="Method 'b2' is not public">"b2"</warning>, int.class);
cb.getMethod(<warning descr="Method 'b3' is not public">"b3"</warning>, int.class);
cb.getMethod(<warning descr="Method 'b4' is not public">"b4"</warning>, int.class);
ca.getDeclaredMethod("a1", int.class);
ca.getDeclaredMethod("a2", int.class);
ca.getDeclaredMethod("a3", int.class);
ca.getDeclaredMethod("a4", int.class);
ca.getDeclaredMethod(<warning descr="Cannot resolve method 'b1'">"b1"</warning>, int.class);
ca.getDeclaredMethod(<warning descr="Cannot resolve method 'b2'">"b2"</warning>, int.class);
ca.getDeclaredMethod(<warning descr="Cannot resolve method 'b3'">"b3"</warning>, int.class);
ca.getDeclaredMethod(<warning descr="Cannot resolve method 'b4'">"b4"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a1' is not declared in class 'MethodExists.B'">"a1"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a2' is not declared in class 'MethodExists.B'">"a2"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a3' is not declared in class 'MethodExists.B'">"a3"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a4' is not declared in class 'MethodExists.B'">"a4"</warning>, int.class);
cb.getDeclaredMethod("b1", int.class);
cb.getDeclaredMethod("b2", int.class);
cb.getDeclaredMethod("b3", int.class);
cb.getDeclaredMethod("b4", int.class);
ca.getMethod("a5", String.class);
ca.getMethod(<warning descr="Method 'a5' is not public">"a5"</warning>, String[].class);
ca.getMethod("a5", String.class, String.class);
ca.getMethod(<warning descr="Cannot resolve method 'a5' with specified argument types">"a5"</warning>, int.class);
ca.getDeclaredMethod("a5", String.class);
ca.getDeclaredMethod("a5", String[].class);
ca.getDeclaredMethod("a5", String.class, String.class);
ca.getDeclaredMethod(<warning descr="Cannot resolve method 'a5' with specified argument types">"a5"</warning>, int.class);
cb.getMethod("a5", String.class);
cb.getMethod(<warning descr="Method 'a5' is not public">"a5"</warning>, String[].class);
cb.getMethod("a5", String.class, String.class);
cb.getMethod(<warning descr="Cannot resolve method 'a5' with specified argument types">"a5"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a5' is not declared in class 'MethodExists.B'">"a5"</warning>, String.class);
cb.getDeclaredMethod(<warning descr="Method 'a5' is not declared in class 'MethodExists.B'">"a5"</warning>, String[].class);
cb.getDeclaredMethod(<warning descr="Method 'a5' is not declared in class 'MethodExists.B'">"a5"</warning>, String.class, String.class);
cb.getDeclaredMethod(<warning descr="Cannot resolve method 'a5' with specified argument types">"a5"</warning>, int.class);
C.class.getMethod("c", int.class);
C.class.getMethod(<warning descr="Cannot resolve method 'c' with specified argument types">"c"</warning>, boolean.class);
C.class.getMethod(<warning descr="Cannot resolve method 'd'">"d"</warning>, int.class);
}
static class A {
public int a1(int n) {return n;}
protected int a2(int n) {return n;}
int a3(int n) {return n;}
private int a4(int n) {return n;}
public String a5(String s) {return s;}
public String a5(String s, String t) {return s;}
protected String a5(String[] s) {return s[0];}
}
static class B extends A {
public int b1(int n) {return n;}
protected int b2(int n) {return n;}
int b3(int n) {return n;}
private int b4(int n) {return n;}
public String b5(String s) {return s;}
public String b5(String s, String t) {return s;}
protected String b5(String[] s) {return s[0];}
}
static final class C extends A {
public int c(int n) {return n;}
}
}
@@ -0,0 +1,98 @@
class Methods {
void foo() throws Exception {
Class ca = A.class;
Class cb = B.class;
ca.getMethod("a1", int.class);
ca.getMethod(<warning descr="Method 'a2' is not public">"a2"</warning>, int.class);
ca.getMethod(<warning descr="Method 'a3' is not public">"a3"</warning>, int.class);
ca.getMethod(<warning descr="Method 'a4' is not public">"a4"</warning>, int.class);
ca.getMethod("b1", int.class);
ca.getMethod("b2", int.class);
ca.getMethod("b3", int.class);
ca.getMethod("b4", int.class);
cb.getMethod("a1", int.class);
cb.getMethod(<warning descr="Method 'a2' is not public">"a2"</warning>, int.class);
cb.getMethod(<warning descr="Method 'a3' is not public">"a3"</warning>, int.class);
cb.getMethod(<warning descr="Method 'a4' is not public">"a4"</warning>, int.class);
cb.getMethod("b1", int.class);
cb.getMethod(<warning descr="Method 'b2' is not public">"b2"</warning>, int.class);
cb.getMethod(<warning descr="Method 'b3' is not public">"b3"</warning>, int.class);
cb.getMethod(<warning descr="Method 'b4' is not public">"b4"</warning>, int.class);
ca.getDeclaredMethod("a1", int.class);
ca.getDeclaredMethod("a2", int.class);
ca.getDeclaredMethod("a3", int.class);
ca.getDeclaredMethod("a4", int.class);
ca.getDeclaredMethod("b1", int.class);
ca.getDeclaredMethod("b2", int.class);
ca.getDeclaredMethod("b3", int.class);
ca.getDeclaredMethod("b4", int.class);
cb.getDeclaredMethod(<warning descr="Method 'a1' is not declared in class 'Methods.B'">"a1"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a2' is not declared in class 'Methods.B'">"a2"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a3' is not declared in class 'Methods.B'">"a3"</warning>, int.class);
cb.getDeclaredMethod(<warning descr="Method 'a4' is not declared in class 'Methods.B'">"a4"</warning>, int.class);
cb.getDeclaredMethod("b1", int.class);
cb.getDeclaredMethod("b2", int.class);
cb.getDeclaredMethod("b3", int.class);
cb.getDeclaredMethod("b4", int.class);
ca.getMethod("a5", String.class);
ca.getMethod(<warning descr="Method 'a5' is not public">"a5"</warning>, String[].class);
ca.getMethod("a5", String.class, String.class);
ca.getMethod("a5", int.class);
ca.getDeclaredMethod("a5", String.class);
ca.getDeclaredMethod("a5", String[].class);
ca.getDeclaredMethod("a5", String.class, String.class);
ca.getDeclaredMethod("a5", int.class);
cb.getMethod("a5", String.class);
cb.getMethod(<warning descr="Method 'a5' is not public">"a5"</warning>, String[].class);
cb.getMethod("a5", String.class, String.class);
cb.getMethod("a5", int.class);
cb.getDeclaredMethod(<warning descr="Method 'a5' is not declared in class 'Methods.B'">"a5"</warning>, String.class);
cb.getDeclaredMethod(<warning descr="Method 'a5' is not declared in class 'Methods.B'">"a5"</warning>, String[].class);
cb.getDeclaredMethod(<warning descr="Method 'a5' is not declared in class 'Methods.B'">"a5"</warning>, String.class, String.class);
cb.getDeclaredMethod("a5", int.class);
C.class.getMethod("c", int.class);
C.class.getMethod(<warning descr="Cannot resolve method 'c' with specified argument types">"c"</warning>, boolean.class);
C.class.getMethod(<warning descr="Cannot resolve method 'd'">"d"</warning>, int.class);
}
static class A {
public int a1(int n) {return n;}
protected int a2(int n) {return n;}
int a3(int n) {return n;}
private int a4(int n) {return n;}
public String a5(String s) {return s;}
public String a5(String s, String t) {return s;}
protected String a5(String[] s) {return s[0];}
}
static class B extends A {
public int b1(int n) {return n;}
protected int b2(int n) {return n;}
int b3(int n) {return n;}
private int b4(int n) {return n;}
public String b5(String s) {return s;}
public String b5(String s, String t) {return s;}
protected String b5(String[] s) {return s[0];}
}
static final class C extends A {
public int c(int n) {return n;}
}
}