modifiers |= ClassFileConstants.AccAbstract;
break checkAbstractEnum;
}
// body of enum constant must implement any inherited abstract methods
// enum type needs to implement abstract methods if one of its constants does not supply a body
TypeDeclaration typeDeclaration = this.referenceContext;
FieldDeclaration[] fields = typeDeclaration.fields;
int fieldsLength = fields == null ? 0 : fields.length;
if (fieldsLength == 0) break checkAbstractEnum; // has no constants so must implement the method itself
AbstractMethodDeclaration[] methods = typeDeclaration.methods;
int methodsLength = methods == null ? 0 : methods.length;
// TODO (kent) cannot tell that the superinterfaces are empty or that their methods are implemented
boolean definesAbstractMethod = typeDeclaration.superInterfaces != null;
for (int i = 0; i < methodsLength && !definesAbstractMethod; i++)
definesAbstractMethod = methods[i].isAbstract();
if (!definesAbstractMethod) break checkAbstractEnum; // all methods have bodies
boolean needAbstractBit = false;
for (int i = 0; i < fieldsLength; i++) {
FieldDeclaration fieldDecl = fields[i];
if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
if (fieldDecl.initialization instanceof QualifiedAllocationExpression) {
needAbstractBit = true;
} else {
break checkAbstractEnum;
}
}
}
// tag this enum as abstract since an abstract method must be implemented AND all enum constants define an anonymous body
// as a result, each of its anonymous constants will see it as abstract and must implement each inherited abstract method
if (needAbstractBit) {
modifiers |= ClassFileConstants.AccAbstract;
}
}
// final if no enum constant with anonymous body
checkFinalEnum: {
TypeDeclaration typeDeclaration = this.referenceContext;
FieldDeclaration[] fields = typeDeclaration.fields;
if (fields != null) {
for (int i = 0, fieldsLength = fields.length; i < fieldsLength; i++) {
FieldDeclaration fieldDecl = fields[i];
if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {