Bug 432628 - [formatter] Add option "Insert new line after annotations on enum constants"
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
index d5ada9c..53ba3b3 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
@@ -8038,6 +8038,7 @@
 	public void test558() {
 		Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
 
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_ENUM_CONSTANT, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE, null);
@@ -8078,6 +8079,7 @@
 	 */
 	public void test559() {
 		Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_ENUM_CONSTANT, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE, null);
@@ -8382,6 +8384,7 @@
 
 	public void test575() {
 		Map options = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_ENUM_CONSTANT, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD, null);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE, null);
@@ -10879,6 +10882,7 @@
  */
 public void test728() {
 	this.formatterPrefs = null;
+	this.formatterOptions.remove(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_ENUM_CONSTANT);
 	this.formatterOptions.remove(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD);
 	this.formatterOptions.remove(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD);
 	this.formatterOptions.remove(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE);
@@ -13317,4 +13321,60 @@
 		"}";
 	formatSource(source);
 }
+/**
+ * https://bugs.eclipse.org/432628 - [formatter] Add option "Insert new line after annotations on enum constants"
+ */
+public void testBug432628a() {
+	setComplianceLevel(CompilerOptions.VERSION_1_5);
+	this.formatterPrefs.insert_new_line_after_annotation_on_enum_constant = false;
+	String source =
+		"public enum SomeEnum {\n" + 
+		"	@XmlEnumValue(\"val1\") VAL_1(\"val1\"), @XmlEnumValue(\"val2\") VAL_2(\"val2\");\n" + 
+		"}";
+	formatSource(source);
+}
+/**
+ * https://bugs.eclipse.org/432628 - [formatter] Add option "Insert new line after annotations on enum constants"
+ */
+public void testBug432628b() {
+	setComplianceLevel(CompilerOptions.VERSION_1_5);
+	this.formatterPrefs.insert_new_line_after_annotation_on_enum_constant = true;
+	String source =
+		"public enum SomeEnum {\n" + 
+		"	@XmlEnumValue(\"val1\")\n" + 
+		"	VAL_1(\"val1\"), @XmlEnumValue(\"val2\")\n" + 
+		"	VAL_2(\"val2\");\n" + 
+		"}";
+	formatSource(source);
+}
+/**
+ * https://bugs.eclipse.org/432628 - [formatter] Add option "Insert new line after annotations on enum constants"
+ */
+public void testBug432628c() {
+	setComplianceLevel(CompilerOptions.VERSION_1_5);
+	this.formatterPrefs.insert_new_line_after_annotation_on_enum_constant = true;
+	this.formatterPrefs.alignment_for_enum_constants = Alignment.M_ONE_PER_LINE_SPLIT + Alignment.M_FORCE;
+	String source =
+		"public enum SomeEnum {\n" + 
+		"	@XmlEnumValue(\"val1\")\n" + 
+		"	VAL_1(\"val1\"),\n" + 
+		"	@XmlEnumValue(\"val2\")\n" + 
+		"	VAL_2(\"val2\");\n" + 
+		"}";
+	formatSource(source);
+}
+/**
+ * https://bugs.eclipse.org/432628 - [formatter] Add option "Insert new line after annotations on enum constants"
+ */
+public void testBug432628d() {
+	setComplianceLevel(CompilerOptions.VERSION_1_5);
+	this.formatterPrefs.insert_new_line_after_annotation_on_enum_constant = false;
+	this.formatterPrefs.alignment_for_enum_constants = Alignment.M_ONE_PER_LINE_SPLIT + Alignment.M_FORCE;
+	String source =
+		"public enum SomeEnum {\n" + 
+		"	@XmlEnumValue(\"val1\") VAL_1(\"val1\"),\n" + 
+		"	@XmlEnumValue(\"val2\") VAL_2(\"val2\");\n" + 
+		"}";
+	formatSource(source);
+}
 }
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index e29a62d..4a8e8a1 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -1364,6 +1364,19 @@
 
 	/**
 	 * <pre>
+	 * FORMATTER / Option to insert a new line after an annotation on an enum constant declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.12
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_enum_constant";//$NON-NLS-1$
+
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a new line after an annotation on a field declaration
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
index f8a03cf..dafd837 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -206,6 +206,7 @@
 
 	public boolean insert_new_line_after_annotation_on_type;
 	public boolean insert_new_line_after_type_annotation;
+	public boolean insert_new_line_after_annotation_on_enum_constant;
 	public boolean insert_new_line_after_annotation_on_field;
 	public boolean insert_new_line_after_annotation_on_method;
 	public boolean insert_new_line_after_annotation_on_package;
@@ -509,6 +510,7 @@
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, Integer.toString(this.tab_char == MIXED ? this.indentation_size : this.tab_size)); // reverse values swapping performed by IndentationTabPage
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE, this.insert_new_line_after_annotation_on_type ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_TYPE_ANNOTATION, this.insert_new_line_after_type_annotation ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_ENUM_CONSTANT, this.insert_new_line_after_annotation_on_enum_constant ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD, this.insert_new_line_after_annotation_on_field ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD, this.insert_new_line_after_annotation_on_method ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE, this.insert_new_line_after_annotation_on_package ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
@@ -2222,6 +2224,7 @@
 		
 		final Object insertNewLineAfterAnnotationOnMemberOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER);
 		final Object insertNewLineAfterAnnotationOnTypeOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE);
+		final Object insertNewLineAfterAnnotationOnEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_ENUM_CONSTANT);
 		final Object insertNewLineAfterAnnotationOnFieldOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD);
 		final Object insertNewLineAfterAnnotationOnMethodOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD);
 		final Object insertNewLineAfterAnnotationOnPackageOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE);
@@ -2230,6 +2233,7 @@
 		final Object insertNewLineAfterAnnotationOnLocalVariableOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE);
 
 		if (insertNewLineAfterAnnotationOnTypeOption == null
+				&& insertNewLineAfterAnnotationOnEnumConstantOption == null
 				&& insertNewLineAfterAnnotationOnFieldOption == null
 				&& insertNewLineAfterAnnotationOnMethodOption == null
 				&& insertNewLineAfterAnnotationOnPackageOption == null) {
@@ -2237,6 +2241,7 @@
 			if (insertNewLineAfterAnnotationOnMemberOption != null) {
 				boolean insert = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnMemberOption);
 				this.insert_new_line_after_annotation_on_type = insert;
+				this.insert_new_line_after_annotation_on_enum_constant = insert;
 				this.insert_new_line_after_annotation_on_field = insert;
 				this.insert_new_line_after_annotation_on_method = insert;
 				this.insert_new_line_after_annotation_on_package = insert;
@@ -2248,13 +2253,13 @@
 				if (insertNewLineAfterAnnotationOnLocalVariableOption != null) {
 					this.insert_new_line_after_annotation_on_local_variable = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnLocalVariableOption);
 				}
-				
 			} else if (insertNewLineAfterAnnotationOnParameterOption == null
 					&& insertNewLineAfterAnnotationOnLocalVariableOption == null) {
 				// if none of the new 3.4 options is used, fall back to the deprecated 3.1 option
 				if (insertNewLineAfterAnnotationOption != null) {
 					boolean insert = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOption);
 					this.insert_new_line_after_annotation_on_type = insert;
+					this.insert_new_line_after_annotation_on_enum_constant = insert;
 					this.insert_new_line_after_annotation_on_field = insert;
 					this.insert_new_line_after_annotation_on_method = insert;
 					this.insert_new_line_after_annotation_on_package = insert;
@@ -2266,6 +2271,9 @@
 			if (insertNewLineAfterAnnotationOnTypeOption != null) {
 				this.insert_new_line_after_annotation_on_type = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnTypeOption);
 			}
+			if (insertNewLineAfterAnnotationOnEnumConstantOption != null) {
+				this.insert_new_line_after_annotation_on_enum_constant = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnEnumConstantOption);
+			}
 			if (insertNewLineAfterAnnotationOnFieldOption != null) {
 				this.insert_new_line_after_annotation_on_field = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnFieldOption);
 			}
@@ -2368,6 +2376,7 @@
 		this.indentation_size = 4;
 		this.insert_new_line_after_annotation_on_type = true;
 		this.insert_new_line_after_type_annotation = false;
+		this.insert_new_line_after_annotation_on_enum_constant = true;
 		this.insert_new_line_after_annotation_on_field = true;
 		this.insert_new_line_after_annotation_on_method = true;
 		this.insert_new_line_after_annotation_on_package = true;
@@ -2660,6 +2669,7 @@
 		this.indentation_size = 4;
 		this.insert_new_line_after_annotation_on_type = true;
 		this.insert_new_line_after_type_annotation = false;
+		this.insert_new_line_after_annotation_on_enum_constant = true;
 		this.insert_new_line_after_annotation_on_field = true;
 		this.insert_new_line_after_annotation_on_method = true;
 		this.insert_new_line_after_annotation_on_package = true;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
index d93f7fa..6da6936 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
@@ -455,6 +455,12 @@
 	}
 
 	@Override
+	public boolean visit(EnumConstantDeclaration node) {
+		this.declarationModifierVisited = false;
+		return true;
+	}
+
+	@Override
 	public boolean visit(Modifier node) {
 		this.declarationModifierVisited = true;
 		return true;
@@ -470,6 +476,8 @@
 			breakAfter = this.options.insert_new_line_after_annotation_on_package;
 		} else if (parentNode instanceof AbstractTypeDeclaration) {
 			breakAfter = this.options.insert_new_line_after_annotation_on_type;
+		} else if (parentNode instanceof EnumConstantDeclaration) {
+			breakAfter = this.options.insert_new_line_after_annotation_on_enum_constant;
 		} else if (parentNode instanceof FieldDeclaration) {
 			breakAfter = this.options.insert_new_line_after_annotation_on_field;
 		} else if (parentNode instanceof MethodDeclaration) {