/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Chris West (Faux) - [clean up] "Use modifier 'final' where possible" can introduce compile errors - https://bugs.eclipse.org/bugs/show_bug.cgi?id=272532 *******************************************************************************/ package org.eclipse.jdt.internal.corext.fix; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.text.edits.TextEditGroup; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.IExtendedModifier; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; import org.eclipse.jdt.ui.cleanup.ICleanUpFix; public class SortModifiersFix extends CompilationUnitRewriteOperationsFix { private static class UnsortedModifiersNodeFinder extends HierarchicalASTVisitor { private final List fOperations; public UnsortedModifiersNodeFinder(List operations) { fOperations= operations; } /** * {@inheritDoc} */ public boolean visit(BodyDeclaration node) { int modifiers= node.getModifiers(); if (modifiers != Modifier.NONE) { List newModifiers= ASTNodeFactory.newModifiers(node.getAST(), modifiers); List oldModifiers= node.modifiers(); for (int o= 0, n= 0; o < oldModifiers.size(); o++) { IExtendedModifier modifier= (IExtendedModifier) oldModifiers.get(o); if (modifier.isAnnotation()) continue; ModifierKeyword oldKeyword= ((Modifier) modifier).getKeyword(); ModifierKeyword newKeyword= ((Modifier) newModifiers.get(n++)).getKeyword(); if (oldKeyword != newKeyword) { fOperations.add(new SortModifiersOperation(node, newModifiers)); break; } } } return super.visit(node); } } private static class SortModifiersOperation extends CompilationUnitRewriteOperation { private final BodyDeclaration fWithModifiersNode; private final List fNewModifiers; public SortModifiersOperation(BodyDeclaration withModifiersNode, List newModifiers) { fWithModifiersNode= withModifiersNode; fNewModifiers= newModifiers; } /** * {@inheritDoc} */ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); TextEditGroup group= createTextEditGroup(FixMessages.VariableDeclarationFix_sortModifiers_description, cuRewrite); List oldModifiers= fWithModifiersNode.modifiers(); for (int i= 0; i < oldModifiers.size(); i++) { Object modifier= oldModifiers.get(i); if (modifier instanceof Modifier) { rewrite.remove((Modifier) modifier, group); } } ListRewrite listRewrite= rewrite.getListRewrite(fWithModifiersNode, fWithModifiersNode.getModifiersProperty()); for (int i= 0; i < fNewModifiers.size(); i++) { Modifier curr= (Modifier) fNewModifiers.get(i); listRewrite.insertLast(curr, group); } } } public static SortModifiersFix createFix(final CompilationUnit compilationUnit, ASTNode[] selectedNodes) { List operations= new ArrayList(); UnsortedModifiersNodeFinder visitor= new UnsortedModifiersNodeFinder(operations); compilationUnit.accept(visitor); if (selectedNodes.length == 1) { if (selectedNodes[0] instanceof SimpleName) { selectedNodes[0]= selectedNodes[0].getParent(); } selectedNodes[0].accept(visitor); } else { for (int i= 0; i < selectedNodes.length; i++) { ASTNode selectedNode= selectedNodes[i]; selectedNode.accept(visitor); } } if (operations.size() == 0) return null; CompilationUnitRewriteOperation[] fixRewriteOperations= (CompilationUnitRewriteOperation[])operations.toArray(new CompilationUnitRewriteOperation[operations.size()]); return new SortModifiersFix(FixMessages.VariableDeclarationFix_sortModifiers_description, compilationUnit, fixRewriteOperations); } public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit) { List operations= new ArrayList(); UnsortedModifiersNodeFinder finder= new UnsortedModifiersNodeFinder(operations); compilationUnit.accept(finder); if (operations.isEmpty()) return null; CompilationUnitRewriteOperation[] fixRewriteOperations= (CompilationUnitRewriteOperation[])operations.toArray(new CompilationUnitRewriteOperation[operations.size()]); return new SortModifiersFix(FixMessages.VariableDeclarationFix_sortModifiers_description, compilationUnit, fixRewriteOperations); } protected SortModifiersFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation[] fixRewriteOperations) { super(name, compilationUnit, fixRewriteOperations); } }