@@ -57,16 +57,37 @@ public class EqualsAvoidsNullVisitor<P> extends JavaVisitor<P> {
57
57
@ Override
58
58
public J visitMethodInvocation (J .MethodInvocation method , P p ) {
59
59
J .MethodInvocation m = (J .MethodInvocation ) super .visitMethodInvocation (method , p );
60
- if (m .getSelect () != null &&
61
- !(m .getSelect () instanceof J .Literal ) &&
62
- !m .getArguments ().isEmpty () &&
63
- m .getArguments ().get (0 ) instanceof J .Literal &&
64
- isStringComparisonMethod (m )) {
65
- return literalsFirstInComparisonsBinaryCheck (m , getCursor ().getParentTreeCursor ().getValue ());
60
+ if (m .getSelect () != null && !(m .getSelect () instanceof J .Literal ) &&
61
+ isStringComparisonMethod (m ) && hasCompatibleArgument (m )) {
62
+
63
+ maybeHandleParentBinary (m );
64
+
65
+ Expression firstArgument = m .getArguments ().get (0 );
66
+ return firstArgument .getType () == JavaType .Primitive .Null ?
67
+ literalsFirstInComparisonsNull (m , firstArgument ) :
68
+ literalsFirstInComparisons (m , firstArgument );
66
69
}
67
70
return m ;
68
71
}
69
72
73
+ private boolean hasCompatibleArgument (J .MethodInvocation m ) {
74
+ if (m .getArguments ().isEmpty ()) {
75
+ return false ;
76
+ }
77
+ Expression firstArgument = m .getArguments ().get (0 );
78
+ if (firstArgument instanceof J .Literal ) {
79
+ return true ;
80
+ }
81
+ if (firstArgument instanceof J .FieldAccess ) {
82
+ firstArgument = ((J .FieldAccess ) firstArgument ).getName ();
83
+ }
84
+ if (firstArgument instanceof J .Identifier ) {
85
+ JavaType .Variable fieldType = ((J .Identifier ) firstArgument ).getFieldType ();
86
+ return fieldType != null && fieldType .hasFlags (Flag .Static , Flag .Final );
87
+ }
88
+ return false ;
89
+ }
90
+
70
91
private boolean isStringComparisonMethod (J .MethodInvocation methodInvocation ) {
71
92
return EQUALS .matches (methodInvocation ) ||
72
93
!style .getIgnoreEqualsIgnoreCase () &&
@@ -76,17 +97,26 @@ private boolean isStringComparisonMethod(J.MethodInvocation methodInvocation) {
76
97
CONTENT_EQUALS .matches (methodInvocation );
77
98
}
78
99
79
- private Expression literalsFirstInComparisonsBinaryCheck (J .MethodInvocation m , P parent ) {
100
+ private void maybeHandleParentBinary (J .MethodInvocation m ) {
101
+ P parent = getCursor ().getParentTreeCursor ().getValue ();
80
102
if (parent instanceof J .Binary ) {
81
- handleBinaryExpression (m , (J .Binary ) parent );
103
+ if (((J .Binary ) parent ).getOperator () == J .Binary .Type .And && ((J .Binary ) parent ).getLeft () instanceof J .Binary ) {
104
+ J .Binary potentialNullCheck = (J .Binary ) ((J .Binary ) parent ).getLeft ();
105
+ if (isNullLiteral (potentialNullCheck .getLeft ()) && matchesSelect (potentialNullCheck .getRight (), requireNonNull (m .getSelect ())) ||
106
+ isNullLiteral (potentialNullCheck .getRight ()) && matchesSelect (potentialNullCheck .getLeft (), requireNonNull (m .getSelect ()))) {
107
+ doAfterVisit (new RemoveUnnecessaryNullCheck <>((J .Binary ) parent ));
108
+ }
109
+ }
82
110
}
83
- return getExpression (m , m .getArguments ().get (0 ));
84
111
}
85
112
86
- private static Expression getExpression (J .MethodInvocation m , Expression firstArgument ) {
87
- return firstArgument .getType () == JavaType .Primitive .Null ?
88
- literalsFirstInComparisonsNull (m , firstArgument ) :
89
- literalsFirstInComparisons (m , firstArgument );
113
+ private boolean isNullLiteral (Expression expression ) {
114
+ return expression instanceof J .Literal && ((J .Literal ) expression ).getType () == JavaType .Primitive .Null ;
115
+ }
116
+
117
+ private boolean matchesSelect (Expression expression , Expression select ) {
118
+ return expression .printTrimmed (getCursor ()).replaceAll ("\\ s" , "" )
119
+ .equals (select .printTrimmed (getCursor ()).replaceAll ("\\ s" , "" ));
90
120
}
91
121
92
122
private static J .Binary literalsFirstInComparisonsNull (J .MethodInvocation m , Expression firstArgument ) {
@@ -104,25 +134,6 @@ private static J.MethodInvocation literalsFirstInComparisons(J.MethodInvocation
104
134
.withArguments (singletonList (m .getSelect ().withPrefix (Space .EMPTY )));
105
135
}
106
136
107
- private void handleBinaryExpression (J .MethodInvocation m , J .Binary binary ) {
108
- if (binary .getOperator () == J .Binary .Type .And && binary .getLeft () instanceof J .Binary ) {
109
- J .Binary potentialNullCheck = (J .Binary ) binary .getLeft ();
110
- if (isNullLiteral (potentialNullCheck .getLeft ()) && matchesSelect (potentialNullCheck .getRight (), requireNonNull (m .getSelect ())) ||
111
- isNullLiteral (potentialNullCheck .getRight ()) && matchesSelect (potentialNullCheck .getLeft (), requireNonNull (m .getSelect ()))) {
112
- doAfterVisit (new RemoveUnnecessaryNullCheck <>(binary ));
113
- }
114
- }
115
- }
116
-
117
- private boolean isNullLiteral (Expression expression ) {
118
- return expression instanceof J .Literal && ((J .Literal ) expression ).getType () == JavaType .Primitive .Null ;
119
- }
120
-
121
- private boolean matchesSelect (Expression expression , Expression select ) {
122
- return expression .printTrimmed (getCursor ()).replaceAll ("\\ s" , "" )
123
- .equals (select .printTrimmed (getCursor ()).replaceAll ("\\ s" , "" ));
124
- }
125
-
126
137
private static class RemoveUnnecessaryNullCheck <P > extends JavaVisitor <P > {
127
138
128
139
private final J .Binary scope ;
0 commit comments