Bug 538459 - Wrong removal of redundant modifiers (static method in enum in interface)

Add cases for nested enums

- remove 'static' modifier from nested enum
- do not remove 'public' modifier from static methods in nested enums
- added test case

Change-Id: I045e6b62044383f8f9bd513695797a22037cb7c5
Signed-off-by: Karsten Thoms <karsten.thoms@itemis.de>
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java
index 58c743e..15af8cf 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java
@@ -9171,11 +9171,24 @@
 		buf.append("  }\n");
 		buf.append("}\n");
 		String expected3 = buf.toString();
-
 		ICompilationUnit cu3= pack1.createCompilationUnit("AnonymousNestedInInterface.java", buf.toString(), false, null);
 
+		// public modifier must not be removed from enum methods 
+		buf= new StringBuffer();
+		buf.append("package test;\n");
+		buf.append("public interface A {\n");
+		buf.append("  public static enum B {\n");
+		buf.append("    public static void method () { }\n");
+		buf.append("  }\n");
+		buf.append("}\n");
+		ICompilationUnit cu4= pack1.createCompilationUnit("NestedEnum.java", buf.toString(), false, null);
+		// https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9
+		// nested enum type is implicitly static
+		// Bug#538459 'public' modified must not be removed from static method in nested enum
+		String expected4 = buf.toString().replace("static enum", "enum");
+		
 		enable(CleanUpConstants.REMOVE_REDUNDANT_MODIFIERS);
-		assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1, cu2, cu3 }, new String[] { expected1, expected2, expected3 });
+		assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1, cu2, cu3, cu4 }, new String[] { expected1, expected2, expected3, expected4 });
 
 	}
 	
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/RedundantModifiersCleanUp.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/RedundantModifiersCleanUp.java
index 84659b6..299a907 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/RedundantModifiersCleanUp.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/RedundantModifiersCleanUp.java
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.core.dom.ASTVisitor;
 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
 import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
 import org.eclipse.jdt.core.dom.FieldDeclaration;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.jdt.core.dom.Modifier;
@@ -139,7 +140,7 @@
 				TypeDeclaration typeDecl= ASTNodes.getParent(node, TypeDeclaration.class);
 				if (typeDecl != null && typeDecl.isInterface()) {
 					rewriteOperations.add(new RemoveModifiersOperation(node, Modifier.ABSTRACT));
-					if (!AnonymousClassDeclaration.class.isInstance(node.getParent())) {
+					if (!AnonymousClassDeclaration.class.isInstance(node.getParent()) && !EnumDeclaration.class.isInstance(node.getParent())) {
 						rewriteOperations.add(new RemoveModifiersOperation(node, Modifier.PUBLIC));
 					}
 				} else if (typeDecl != null && Modifier.isFinal(typeDecl.getModifiers()) && Modifier.isFinal(node.getModifiers())) {
@@ -156,6 +157,15 @@
 				}
 				return true;
 			}
+			
+			@Override
+			public boolean visit(EnumDeclaration node) {
+				TypeDeclaration typeDecl= ASTNodes.getParent(node, TypeDeclaration.class);
+				if (typeDecl != null && Modifier.isStatic(node.getModifiers())) {
+					rewriteOperations.add(new RemoveModifiersOperation(node, Modifier.STATIC));
+				}
+				return true;
+			}
 
 		});
 		if (rewriteOperations.isEmpty()) {