in legacy/java/piranha/src/main/java/com/uber/piranha/XPFlagCleaner.java [1086:1153]
private EnumEnding getEndingOfLastEnumConstantIfRemoved(Symbol enumSym, VisitorState state) {
ClassTree enumClassTree = ASTHelpers.findClass(enumSym.enclClass(), state);
if (enumClassTree == null) {
return EnumEnding.IGNORE;
}
// Find enum initializer members only
List<VariableTree> enumConstants = getEnumConstants(enumClassTree).collect(Collectors.toList());
// Get second to last index
//
// The reason to get the second to last index, is that we need to alter the second to last enum
// constant ending if the last constant is being removed, as the second to last enum constant
// will now become the last constant.
//
// In Java, the last enum constant is be required to have a different ending than other enum
// constants in the enum if the enum has non-enum constant members
//
// We do not need to alter any other enum constants because they will either never become the
// last constant [0 ... size - 3] or will be removed [size - 1].
int index = enumConstants.size() - 2;
// Check if the second to last enum is the current enum being processed
if (index < 0 || !enumConstants.get(index).getName().equals(enumSym.getSimpleName())) {
return EnumEnding.IGNORE;
}
VariableTree nextConstant = enumConstants.get(index + 1);
String nextEnumConstantSource = state.getSourceForNode(nextConstant);
// The enclosingEnumSource is the source code of the enum that will contain both the current
// enum constant and the next enum constant
String enclosingEnumSource = state.getSourceForNode(state.getPath().getParentPath().getLeaf());
// We need access to the source to remove the enum constant in the first place
if (nextEnumConstantSource == null || enclosingEnumSource == null) {
return EnumEnding.IGNORE;
}
// Make sure the last enum constant in the member list will actually be removed and cleaned up
// If not, we don't want to alter the prior enum constant
//
// These are the same checks that would run from the point in the AST were we at the enum
// constant that is being removed instead of the enum constant right before. We're skipping
// around the tree a bit here.
//
// The reason for re-checking if we are going to clean up the last enum constant when we
// encounter the second to last enum constant, rather than doing the check when we encounter the
// last enum constant, is because we are altering the syntax of the second to last enum
// constant. It is easier to add a SuggestedFix with the design of error-prone's BugChecker at
// the time you encounter that piece of code you are altering, than to attempt to add a fix
// outside of encountering that piece of code in the syntax tree traversal.
if (!(xpFlagName.equals(nextConstant.getName().toString())
|| isEnumConstantMatchingFlagName(
nextConstant.getName().toString(), enumSym.enclClass(), state))) {
return EnumEnding.IGNORE;
}
String varAsStrWithComma = nextEnumConstantSource + ",";
String varAsStrWithSemicolon = nextEnumConstantSource + ";";
if (enclosingEnumSource.contains(varAsStrWithComma)) {
return EnumEnding.COMMA;
} else if (enclosingEnumSource.contains(varAsStrWithSemicolon)) {
return EnumEnding.SEMICOLON;
} else {
return EnumEnding.NONE;
}
}