1
1
/**
2
- * Provides predicates for identifying precondition checks like
2
+ * Provides predicates for identifying precondition and assertion checks like
3
3
* `com.google.common.base.Preconditions` and
4
4
* `org.apache.commons.lang3.Validate`.
5
5
*/
@@ -9,99 +9,150 @@ module;
9
9
import java
10
10
11
11
/**
12
- * Holds if `m` is a non-overridable method that checks that its zero-indexed `argument`
13
- * is equal to `checkTrue` and throws otherwise.
12
+ * Holds if `m` is a method that checks that its argument at position `arg` is
13
+ * equal to true and throws otherwise.
14
14
*/
15
- predicate conditionCheckMethodArgument ( Method m , int argument , boolean checkTrue ) {
16
- condtionCheckMethodGooglePreconditions ( m , checkTrue ) and argument = 0
17
- or
18
- conditionCheckMethodApacheCommonsLang3Validate ( m , checkTrue ) and argument = 0
15
+ private predicate methodCheckTrue ( Method m , int arg ) {
16
+ arg = 0 and
17
+ (
18
+ m .hasQualifiedName ( "com.google.common.base" , "Preconditions" , [ "checkArgument" , "checkState" ] ) or
19
+ m .hasQualifiedName ( "com.google.common.base" , "Verify" , "verify" ) or
20
+ m .hasQualifiedName ( "org.apache.commons.lang3" , "Validate" , [ "isTrue" , "validState" ] ) or
21
+ m .hasQualifiedName ( "org.junit.jupiter.api" , "Assertions" , "assertTrue" ) or
22
+ m .hasQualifiedName ( "org.junit.jupiter.api" , "Assumptions" , "assumeTrue" ) or
23
+ m .hasQualifiedName ( "org.testng" , "Assert" , "assertTrue" )
24
+ )
19
25
or
20
- condtionCheckMethodTestingFramework ( m , argument , checkTrue )
26
+ m .getParameter ( arg ) .getType ( ) instanceof BooleanType and
27
+ (
28
+ m .hasQualifiedName ( "org.junit" , "Assert" , "assertTrue" ) or
29
+ m .hasQualifiedName ( "org.junit" , "Assume" , "assumeTrue" ) or
30
+ m .hasQualifiedName ( "junit.framework" , "Assert" , "assertTrue" )
31
+ )
32
+ }
33
+
34
+ /**
35
+ * Holds if `m` is a method that checks that its argument at position `arg` is
36
+ * equal to false and throws otherwise.
37
+ */
38
+ private predicate methodCheckFalse ( Method m , int arg ) {
39
+ arg = 0 and
40
+ (
41
+ m .hasQualifiedName ( "org.junit.jupiter.api" , "Assertions" , "assertFalse" ) or
42
+ m .hasQualifiedName ( "org.junit.jupiter.api" , "Assumptions" , "assumeFalse" ) or
43
+ m .hasQualifiedName ( "org.testng" , "Assert" , "assertFalse" )
44
+ )
21
45
or
22
- exists ( Parameter p , MethodCall ma , int argIndex , boolean ct , Expr arg |
23
- p = m .getParameter ( argument ) and
24
- not m .isOverridable ( ) and
25
- m .getBody ( ) .getStmt ( 0 ) .( ExprStmt ) .getExpr ( ) = ma and
26
- conditionCheckArgument ( ma , argIndex , ct ) and
27
- ma .getArgument ( argIndex ) = arg and
28
- (
29
- arg .( LogNotExpr ) .getExpr ( ) .( VarAccess ) .getVariable ( ) = p and
30
- checkTrue = ct .booleanNot ( )
31
- or
32
- arg .( VarAccess ) .getVariable ( ) = p and checkTrue = ct
33
- )
46
+ m .getParameter ( arg ) .getType ( ) instanceof BooleanType and
47
+ (
48
+ m .hasQualifiedName ( "org.junit" , "Assert" , "assertFalse" ) or
49
+ m .hasQualifiedName ( "org.junit" , "Assume" , "assumeFalse" ) or
50
+ m .hasQualifiedName ( "junit.framework" , "Assert" , "assertFalse" )
51
+ )
52
+ }
53
+
54
+ /**
55
+ * Holds if `m` is a method that checks that its argument at position `arg` is
56
+ * not null and throws otherwise.
57
+ */
58
+ private predicate methodCheckNotNull ( Method m , int arg ) {
59
+ arg = 0 and
60
+ (
61
+ m .hasQualifiedName ( "com.google.common.base" , "Preconditions" , "checkNotNull" ) or
62
+ m .hasQualifiedName ( "com.google.common.base" , "Verify" , "verifyNotNull" ) or
63
+ m .hasQualifiedName ( "org.apache.commons.lang3" , "Validate" , "notNull" ) or
64
+ m .hasQualifiedName ( "java.util" , "Objects" , "requireNonNull" ) or
65
+ m .hasQualifiedName ( "org.junit.jupiter.api" , "Assertions" , "assertNotNull" ) or
66
+ m .hasQualifiedName ( "org.junit" , "Assume" , "assumeNotNull" ) or // vararg
67
+ m .hasQualifiedName ( "org.testng" , "Assert" , "assertNotNull" )
34
68
)
35
69
or
36
- exists ( Parameter p , IfStmt ifstmt , Expr cond |
37
- p = m .getParameter ( argument ) and
38
- not m .isOverridable ( ) and
39
- p .getType ( ) instanceof BooleanType and
40
- m .getBody ( ) .getStmt ( 0 ) = ifstmt and
41
- ifstmt .getCondition ( ) = cond and
42
- (
43
- cond .( LogNotExpr ) .getExpr ( ) .( VarAccess ) .getVariable ( ) = p and checkTrue = true
44
- or
45
- cond .( VarAccess ) .getVariable ( ) = p and checkTrue = false
46
- ) and
47
- (
48
- ifstmt .getThen ( ) instanceof ThrowStmt or
49
- ifstmt .getThen ( ) .( SingletonBlock ) .getStmt ( ) instanceof ThrowStmt
50
- )
70
+ arg = m .getNumberOfParameters ( ) - 1 and
71
+ (
72
+ m .hasQualifiedName ( "org.junit" , "Assert" , "assertNotNull" ) or
73
+ m .hasQualifiedName ( "junit.framework" , "Assert" , "assertNotNull" )
51
74
)
52
75
}
53
76
54
- private predicate condtionCheckMethodGooglePreconditions ( Method m , boolean checkTrue ) {
55
- m .getDeclaringType ( ) .hasQualifiedName ( "com.google.common.base" , "Preconditions" ) and
56
- checkTrue = true and
57
- ( m .hasName ( "checkArgument" ) or m .hasName ( "checkState" ) )
77
+ /**
78
+ * Holds if `m` is a method that checks that its argument at position `arg`
79
+ * satisfies a property specified by another argument and throws otherwise.
80
+ */
81
+ private predicate methodCheckThat ( Method m , int arg ) {
82
+ m .getParameter ( arg ) .getType ( ) .getErasure ( ) instanceof TypeObject and
83
+ (
84
+ m .hasQualifiedName ( "org.hamcrest" , "MatcherAssert" , "assertThat" ) or
85
+ m .hasQualifiedName ( "org.junit" , "Assert" , "assertThat" ) or
86
+ m .hasQualifiedName ( "org.junit" , "Assume" , "assumeThat" )
87
+ )
58
88
}
59
89
60
- private predicate conditionCheckMethodApacheCommonsLang3Validate ( Method m , boolean checkTrue ) {
61
- m .getDeclaringType ( ) .hasQualifiedName ( "org.apache.commons.lang3" , "Validate" ) and
62
- checkTrue = true and
63
- ( m .hasName ( "isTrue" ) or m .hasName ( "validState" ) )
90
+ /** Holds if `m` is a method that unconditionally throws. */
91
+ private predicate methodUnconditionallyThrows ( Method m ) {
92
+ m .hasQualifiedName ( "org.junit.jupiter.api" , "Assertions" , "fail" ) or
93
+ m .hasQualifiedName ( "org.junit" , "Assert" , "fail" ) or
94
+ m .hasQualifiedName ( "junit.framework" , "Assert" , "fail" ) or
95
+ m .hasQualifiedName ( "org.testng" , "Assert" , "fail" )
64
96
}
65
97
66
98
/**
67
- * Holds if `m ` is a non-overridable testing framework method that checks that its first argument
68
- * is equal to `checkTrue` and throws otherwise.
99
+ * Holds if `mc ` is a call to a method that checks that its argument `arg` is
100
+ * equal to `checkTrue` and throws otherwise.
69
101
*/
70
- private predicate condtionCheckMethodTestingFramework ( Method m , int argument , boolean checkTrue ) {
71
- argument = 0 and
72
- (
73
- m .getDeclaringType ( ) .hasQualifiedName ( "org.junit" , "Assume" ) and
74
- checkTrue = true and
75
- m .hasName ( "assumeTrue" )
102
+ predicate methodCallChecksBoolean ( MethodCall mc , Expr arg , boolean checkTrue ) {
103
+ exists ( int pos | mc .getArgument ( pos ) = arg |
104
+ methodCheckTrue ( mc .getMethod ( ) .getSourceDeclaration ( ) , pos ) and checkTrue = true
76
105
or
77
- m .getDeclaringType ( ) .hasQualifiedName ( "org.junit.jupiter.api" , "Assertions" ) and
78
- (
79
- checkTrue = true and m .hasName ( "assertTrue" )
80
- or
81
- checkTrue = false and m .hasName ( "assertFalse" )
82
- )
83
- or
84
- m .getDeclaringType ( ) .hasQualifiedName ( "org.junit.jupiter.api" , "Assumptions" ) and
85
- (
86
- checkTrue = true and m .hasName ( "assumeTrue" )
87
- or
88
- checkTrue = false and m .hasName ( "assumeFalse" )
89
- )
106
+ methodCheckFalse ( mc .getMethod ( ) .getSourceDeclaration ( ) , pos ) and checkTrue = false
90
107
)
91
- or
92
- m .getDeclaringType ( ) .hasQualifiedName ( [ "org.junit" , "org.testng" ] , "Assert" ) and
93
- m .getParameter ( argument ) .getType ( ) instanceof BooleanType and
94
- (
95
- checkTrue = true and m .hasName ( "assertTrue" )
108
+ }
109
+
110
+ /**
111
+ * Holds if `mc` is a call to a method that checks that its argument `arg` is
112
+ * not null and throws otherwise.
113
+ */
114
+ predicate methodCallChecksNotNull ( MethodCall mc , Expr arg ) {
115
+ exists ( int pos | mc .getArgument ( pos ) = arg |
116
+ methodCheckNotNull ( mc .getMethod ( ) .getSourceDeclaration ( ) , pos )
96
117
or
97
- checkTrue = false and m .hasName ( "assertFalse" )
118
+ methodCheckThat ( mc .getMethod ( ) .getSourceDeclaration ( ) , pos ) and
119
+ mc .getAnArgument ( ) .( MethodCall ) .getMethod ( ) .getName ( ) = "notNullValue"
98
120
)
99
121
}
100
122
101
123
/**
124
+ * Holds if `mc` is a call to a method that checks one of its arguments in some
125
+ * way and possibly throws.
126
+ */
127
+ predicate methodCallChecksArgument ( MethodCall mc ) {
128
+ methodCallChecksBoolean ( mc , _, _) or
129
+ methodCallChecksNotNull ( mc , _)
130
+ }
131
+
132
+ /** Holds if `mc` is a call to a method that unconditionally throws. */
133
+ predicate methodCallUnconditionallyThrows ( MethodCall mc ) {
134
+ methodUnconditionallyThrows ( mc .getMethod ( ) .getSourceDeclaration ( ) ) or
135
+ exists ( BooleanLiteral b | methodCallChecksBoolean ( mc , b , b .getBooleanValue ( ) .booleanNot ( ) ) )
136
+ }
137
+
138
+ /**
139
+ * DEPRECATED: Use `methodCallChecksBoolean` instead.
140
+ *
141
+ * Holds if `m` is a non-overridable method that checks that its zero-indexed `argument`
142
+ * is equal to `checkTrue` and throws otherwise.
143
+ */
144
+ deprecated predicate conditionCheckMethodArgument ( Method m , int argument , boolean checkTrue ) {
145
+ methodCheckTrue ( m , argument ) and checkTrue = true
146
+ or
147
+ methodCheckFalse ( m , argument ) and checkTrue = false
148
+ }
149
+
150
+ /**
151
+ * DEPRECATED: Use `methodCallChecksBoolean` instead.
152
+ *
102
153
* Holds if `ma` is an access to a non-overridable method that checks that its
103
154
* zero-indexed `argument` is equal to `checkTrue` and throws otherwise.
104
155
*/
105
- predicate conditionCheckArgument ( MethodCall ma , int argument , boolean checkTrue ) {
156
+ deprecated predicate conditionCheckArgument ( MethodCall ma , int argument , boolean checkTrue ) {
106
157
conditionCheckMethodArgument ( ma .getMethod ( ) .getSourceDeclaration ( ) , argument , checkTrue )
107
158
}
0 commit comments