@Override
public Void visitTypeDeclaration(final TypeDeclaration node, final Void ignored) {
startNode(node);
final TypeDefinition type = node.getUserData(Keys.TYPE_DEFINITION);
final boolean isTrulyAnonymous = type != null &&
type.isAnonymous() &&
node.getParent() instanceof AnonymousObjectCreationExpression;
if (!isTrulyAnonymous) {
writeAnnotations(node.getAnnotations(), true);
writeModifiers(node.getModifiers());
switch (node.getClassType()) {
case ENUM:
writeKeyword(Roles.ENUM_KEYWORD);
break;
case INTERFACE:
writeKeyword(Roles.INTERFACE_KEYWORD);
break;
case ANNOTATION:
writeKeyword(Roles.ANNOTATION_KEYWORD);
break;
default:
writeKeyword(Roles.CLASS_KEYWORD);
break;
}
node.getNameToken().acceptVisitor(this, ignored);
writeTypeParameters(node.getTypeParameters());
if (!node.getBaseType().isNull()) {
space();
writeKeyword(Roles.EXTENDS_KEYWORD);
space();
node.getBaseType().acceptVisitor(this, ignored);
}
if (any(node.getInterfaces())) {
final Collection<AstType> interfaceTypes;
if (node.getClassType() == ClassType.ANNOTATION) {
interfaceTypes = new ArrayList<>();
for (final AstType t : node.getInterfaces()) {
final TypeReference r = t.getUserData(Keys.TYPE_REFERENCE);
if (r != null && "java/lang/annotation/Annotation".equals(r.getInternalName())) {
continue;
}
interfaceTypes.add(t);
}
}
else {
interfaceTypes = node.getInterfaces();
}
if (any(interfaceTypes)) {
space();
if (node.getClassType() == ClassType.INTERFACE || node.getClassType() == ClassType.ANNOTATION) {
writeKeyword(Roles.EXTENDS_KEYWORD);
}
else {
writeKeyword(Roles.IMPLEMENTS_KEYWORD);
}
space();
writeCommaSeparatedList(node.getInterfaces());
}
}
}
final BraceStyle braceStyle;
final AstNodeCollection<EntityDeclaration> members = node.getMembers();
switch (node.getClassType()) {
case ENUM:
braceStyle = policy.EnumBraceStyle;
break;
case INTERFACE:
braceStyle = policy.InterfaceBraceStyle;
break;
case ANNOTATION:
braceStyle = policy.AnnotationBraceStyle;
break;
default:
if (type != null && type.isAnonymous()) {
braceStyle = members.isEmpty() ? BraceStyle.BannerStyle : policy.AnonymousClassBraceStyle;
}
else {
braceStyle = policy.ClassBraceStyle;
}
break;
}
openBrace(braceStyle);
boolean first = true;
EntityDeclaration lastMember = null;
for (final EntityDeclaration member : members) {
if (first) {
first = false;
}
else {
final int blankLines;
if (member instanceof FieldDeclaration && lastMember instanceof FieldDeclaration) {
blankLines = policy.BlankLinesBetweenFields;
}
else {
blankLines = policy.BlankLinesBetweenMembers;
}
for (int i = 0; i < blankLines; i++) {
formatter.newLine();
}
}
member.acceptVisitor(this, ignored);
lastMember = member;
}
closeBrace(braceStyle);
if (type == null || !type.isAnonymous()) {
optionalSemicolon();
newLine();
}
endNode(node);