in legacy/java/piranha/src/main/java/com/uber/piranha/XPFlagCleaner.java [1284:1357]
public Description matchMethod(MethodTree tree, VisitorState state) {
if (shouldSkip(state)) return Description.NO_MATCH;
boolean deleteMethod = false;
List<AnnotationTree> deletableAnnotations = new ArrayList<>();
// Deletable identifiers used as part of the argument to an annotation, for when the entire
// annotation doesn't need to be deleted
List<ExpressionTree> deletableIdentifiers = new ArrayList<>();
final ImmutableSet<ResolvedTestAnnotation> resolvedTestAnnotations =
config.resolveTestAnnotations(tree, state);
if (resolvedTestAnnotations.size() != 0) {
// If there are any test annotations for this method, then we clean up based on those. We do
// this even if
// the method is not otherwise a recognized test method (e.g. marked @Test) and we ignore all
// other
// applicable clean up heuristics
for (ResolvedTestAnnotation resolved : resolvedTestAnnotations) {
Set<AnnotationArgument> matchedFlagsWorkingSet = new HashSet<>();
for (AnnotationArgument testedFlag : resolved.getFlags()) {
if (testedFlag.getValue().equals(xpFlagName)) {
if (isTreated == resolved.isTreated()) {
// Annotation requests the same treatment state as what Piranha is setting the flag to
matchedFlagsWorkingSet.add(testedFlag);
} else {
// Annotation (and therefore test method) requests a different (now impossible)
// treatment, compared to what Piranha is setting the flag to.
deleteMethod = true;
}
}
}
// Should we delete the full annotation, or specific flags within it? Depends if all
// flags mentioned within the annotation have been matched or not:
if (matchedFlagsWorkingSet.size() == resolved.getFlags().size()) {
deletableAnnotations.add(resolved.getSourceTree());
} else {
// Only remove the matched flag references, but preserve the annotation and its
// references to remaining flags
matchedFlagsWorkingSet.forEach(arg -> deletableIdentifiers.add(arg.getSourceTree()));
}
matchedFlagsWorkingSet.clear();
}
} else if (config.shouldCleanTestMethodsByContent()
&& PiranhaUtils.isUnitTestMethod(tree, state)) {
deleteMethod = shouldCleanBySetters(tree, state);
}
// Early exit for no changes required:
if (!deleteMethod && deletableAnnotations.size() == 0 && deletableIdentifiers.size() == 0) {
return Description.NO_MATCH;
}
// Process refactoring
Description.Builder builder = buildDescription(tree);
SuggestedFix.Builder fixBuilder = SuggestedFix.builder();
// Check first if the whole method must go away
if (deleteMethod) {
fixBuilder.delete(tree);
decrementAllSymbolUsages(tree, state, fixBuilder);
skipWithin(state.getPath()); // Deleting full method, skip refactorings within it
} else {
// Otherwise, we might still need to clean up individual obsolete test annotations and flag
// references within multi-flag annotations.
// Note that the AST elements referenced by deletableAnnotations and deletableIdentifiers
// should not overlap, given the logic above, so deleting each independently is safe.
for (ExpressionTree expr : deletableIdentifiers) {
fixBuilder = deleteExprWithComma(state, expr, resolvedTestAnnotations, fixBuilder);
decrementAllSymbolUsages(expr, state, fixBuilder);
}
for (AnnotationTree at : deletableAnnotations) {
fixBuilder.delete(at);
decrementAllSymbolUsages(at, state, fixBuilder);
}
}
builder.addFix(fixBuilder.build());
return builder.build();
}