@@ -145,12 +145,14 @@ private static boolean isNull(ExpressionTree tree) {
145
145
146
146
private final boolean matchTestAssertions ;
147
147
private final boolean checkPrimitives ;
148
+ private final boolean checkValueOf ;
148
149
149
150
@ Inject
150
151
ImpossibleNullComparison (ErrorProneFlags flags ) {
151
152
this .matchTestAssertions =
152
153
flags .getBoolean ("ProtoFieldNullComparison:MatchTestAssertions" ).orElse (true );
153
154
this .checkPrimitives = flags .getBoolean ("ImmutableNullComparison:CheckPrimitives" ).orElse (true );
155
+ this .checkValueOf = flags .getBoolean ("ImpossibleNullComparison:CheckValueOf" ).orElse (true );
154
156
}
155
157
156
158
@ Override
@@ -262,6 +264,7 @@ private Optional<Fixer> getFixer(ExpressionTree tree, VisitorState state) {
262
264
}
263
265
return stream (GetterTypes .values ())
264
266
.filter (gt -> !gt .equals (GetterTypes .PRIMITIVE ) || checkPrimitives )
267
+ .filter (gt -> !gt .equals (GetterTypes .VALUE_OF ) || checkValueOf )
265
268
.map (type -> type .match (resolvedTree , state ))
266
269
.filter (Objects ::nonNull )
267
270
.findFirst ();
@@ -311,6 +314,12 @@ private interface Fixer {
311
314
private static final Matcher <ExpressionTree > TABLE_COLUMN_MATCHER =
312
315
instanceMethod ().onDescendantOf ("com.google.common.collect.Table" ).named ("column" );
313
316
317
+ private static final Matcher <ExpressionTree > NON_NULL_VALUE_OF =
318
+ staticMethod ()
319
+ .onDescendantOfAny ("java.lang.Enum" , "java.lang.Number" )
320
+ .named ("valueOf" )
321
+ .withParameters ("java.lang.String" );
322
+
314
323
private enum GetterTypes {
315
324
OPTIONAL_GET {
316
325
@ Nullable
@@ -394,6 +403,17 @@ Fixer match(ExpressionTree tree, VisitorState state) {
394
403
return type != null && type .isPrimitive () ? GetterTypes ::emptyFix : null ;
395
404
}
396
405
},
406
+ VALUE_OF {
407
+ @ Nullable
408
+ @ Override
409
+ Fixer match (ExpressionTree tree , VisitorState state ) {
410
+ if (!NON_NULL_VALUE_OF .matches (tree , state )) {
411
+ return null ;
412
+ }
413
+ // TODO(cpovirk): Suggest Enums.getIfPresent, Ints.tryParse, etc.
414
+ return GetterTypes ::emptyFix ;
415
+ }
416
+ },
397
417
/** {@code proto.getFoo()} */
398
418
SCALAR {
399
419
@ Nullable
0 commit comments