1919import static com .google .common .collect .Iterables .getLast ;
2020import static com .google .common .collect .Iterables .getOnlyElement ;
2121import static com .google .errorprone .BugPattern .SeverityLevel .WARNING ;
22+ import static com .google .errorprone .fixes .SuggestedFix .emptyFix ;
2223import static com .google .errorprone .matchers .Matchers .allOf ;
2324import static com .google .errorprone .matchers .Matchers .anyOf ;
2425import static com .google .errorprone .matchers .Matchers .assertEqualsInvocation ;
5556 * @author [email protected] (Eleanor Harris) 5657 */
5758@ BugPattern (
58- summary = "This type is not guaranteed to implement a useful # equals method." ,
59+ summary = "This type is not guaranteed to implement a useful equals() method." ,
5960 severity = WARNING )
6061public final class UndefinedEquals extends BugChecker implements MethodInvocationTreeMatcher {
6162
@@ -102,13 +103,8 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState
102103 .map (
103104 b ->
104105 buildDescription (tree )
105- .setMessage (
106- "Subtypes of "
107- + b .shortName ()
108- + " are not guaranteed to implement a useful #equals method." )
109- .addFix (
110- generateFix (tree , state , receiver , argument )
111- .orElse (SuggestedFix .emptyFix ()))
106+ .setMessage (b .shortName () + " does not have well-defined equality semantics" )
107+ .addFix (generateFix (tree , state , receiver , argument ).orElse (emptyFix ()))
112108 .build ())
113109 .orElse (Description .NO_MATCH );
114110 }
@@ -140,18 +136,18 @@ && isSubtype(getType(receiver), type, state)) {
140136
141137 // If both are subtypes of Iterable, rewrite
142138 Type iterableType = state .getSymtab ().iterableType ;
143- Type multimapType = COM_GOOGLE_COMMON_COLLECT_MULTIMAP .get (state );
139+ Type multimapType = MULTIMAP .get (state );
144140 Optional <SuggestedFix > fix =
145- firstPresent (
146- generateTruthFix .apply (iterableType , "containsExactlyElementsIn" ),
147- generateTruthFix .apply (multimapType , "containsExactlyEntriesIn" ));
141+ generateTruthFix
142+ .apply (iterableType , "containsExactlyElementsIn" )
143+ . or (() -> generateTruthFix .apply (multimapType , "containsExactlyEntriesIn" ));
148144 if (fix .isPresent ()) {
149145 return fix ;
150146 }
151147 }
152148
153149 // Generate fix for CharSequence
154- Type charSequenceType = JAVA_LANG_CHARSEQUENCE .get (state );
150+ Type charSequenceType = CHAR_SEQUENCE .get (state );
155151 BiFunction <Tree , Tree , Optional <SuggestedFix >> generateCharSequenceFix =
156152 (maybeCharSequence , maybeString ) -> {
157153 if (charSequenceType != null
@@ -161,23 +157,14 @@ && isSameType(getType(maybeString), state.getSymtab().stringType, state)) {
161157 }
162158 return Optional .empty ();
163159 };
164- return firstPresent (
165- generateCharSequenceFix .apply (receiver , argument ),
166- generateCharSequenceFix .apply (argument , receiver ));
160+ return generateCharSequenceFix
161+ .apply (receiver , argument )
162+ . or (() -> generateCharSequenceFix .apply (argument , receiver ));
167163 }
168164
169- private static <T > Optional <T > firstPresent (Optional <T >... optionals ) {
170- for (Optional <T > optional : optionals ) {
171- if (optional .isPresent ()) {
172- return optional ;
173- }
174- }
175- return Optional .empty ();
176- }
177-
178- private static final Supplier <Type > COM_GOOGLE_COMMON_COLLECT_MULTIMAP =
165+ private static final Supplier <Type > MULTIMAP =
179166 VisitorState .memoize (state -> state .getTypeFromString ("com.google.common.collect.Multimap" ));
180167
181- private static final Supplier <Type > JAVA_LANG_CHARSEQUENCE =
168+ private static final Supplier <Type > CHAR_SEQUENCE =
182169 VisitorState .memoize (state -> state .getTypeFromString ("java.lang.CharSequence" ));
183170}
0 commit comments