### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/core/util/CompilationUnitSorter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java,v retrieving revision 1.36 diff -u -r1.36 CompilationUnitSorter.java --- model/org/eclipse/jdt/core/util/CompilationUnitSorter.java 23 Jan 2007 14:58:32 -0000 1.36 +++ model/org/eclipse/jdt/core/util/CompilationUnitSorter.java 28 Jan 2007 23:49:21 -0000 @@ -328,11 +328,145 @@ if (compilationUnit == null || comparator == null) { throw new IllegalArgumentException(); } - checkASTLevel(level); ICompilationUnit[] compilationUnits = new ICompilationUnit[] { compilationUnit }; - SortElementsOperation operation = new SortElementsOperation(level, compilationUnits, positions, comparator); - operation.runOperation(monitor); + int[][] positionses = new int[][] { positions }; + + sort(level, compilationUnits, positionses, comparator, options, monitor); } + + /** + * Reorders the declarations in the given compilation units according to + * the specified AST level. The caller is responsible for arranging in + * advance that the given compilations unit are a working copy, and for + * saving the changes afterwards. + *

+ * Note: Reordering the members within a type declaration might be + * more than a cosmetic change and could have potentially serious + * repercussions. Firstly, the order in which the fields of a type are + * initialized is significant in the Java language; reordering fields + * and initializers may result in compilation errors or change the execution + * behavior of the code. Secondly, reordering a class's members may affect + * how its instances are serialized. This operation should therefore be used + * with caution and due concern for potential negative side effects. + *

+ *

+ * The optional positionses array contains an array of non-decreasing + * ordered list of character-based source positions within the corresponding compilation + * unit's source code string. Upon return from this method, the positionses in + * the array reflect the corresponding new locations in the modified source + * code string. Note that this operation modifies the given array in place. + *

+ *

+ * The compare method of the given comparator is passed pairs + * of body declarations (subclasses of BodyDeclaration) + * representing body declarations at the same level. The nodes are from an + * AST of the specified level + * ({@link org.eclipse.jdt.core.dom.ASTParser#newParser(int)}. Clients + * will generally specify AST.JLS3 since that will cover all constructs found + * in Java 1.0, 1.1, 1.2, 1.3, 1.4, and 1.5 source code. + * The comparator is called on body declarations of nested classes, including + * anonymous and local classes, but always at the same level. Clients need to provide + * a comparator implementation (there is no standard comparator). The + * RELATIVE_ORDER property attached to these AST nodes afforts + * the comparator a way to preserve the original relative order. + *

+ *

+ * The body declarations passed as parameters to the comparator + * always carry at least the following minimal signature information: + *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
TypeDeclarationmodifiers, isInterface, name, superclass, + * superInterfaces, typeParameters
+ * RELATIVE_ORDER property
FieldDeclarationmodifiers, type, fragments + * (VariableDeclarationFragments + * with name only)
+ * RELATIVE_ORDER property
MethodDeclarationmodifiers, isConstructor, returnType, name, + * typeParameters, parameters + * (SingleVariableDeclarations with name, type, and modifiers only), + * thrownExceptions
+ * RELATIVE_ORDER property
Initializermodifiers
+ * RELATIVE_ORDER property
AnnotationTypeDeclarationmodifiers, name
+ * RELATIVE_ORDER property
AnnotationTypeMemberDeclarationmodifiers, name, type, default
+ * RELATIVE_ORDER property
EnumDeclarationmodifiers, name, superInterfaces
+ * RELATIVE_ORDER property
EnumConstantDeclarationmodifiers, name, arguments
+ * RELATIVE_ORDER property
+ * Clients should not rely on the AST nodes being properly parented or on + * having source range information. (Future releases may provide options + * for requesting additional information like source positions, full ASTs, + * non-recursive sorting, etc.) + *

+ * + * @param level the AST level; one of the AST LEVEL constants + * @param compilationUnits the given compilation units, which must be a + * working copy + * @param positionses an array of array of source positions to map, or + * null if none. If supplied, the positions must + * character-based source positions within the original source code for + * the given compilation unit, arranged in non-decreasing order. + * The array is updated in place when this method returns to reflect the + * corresponding source positions in the permuted source code string + * (but not necessarily any longer in non-decreasing order). + * @param comparator the comparator capable of ordering + * BodyDeclarations; this comparator is passed AST nodes + * from an AST of the specified AST level + * @param options bitwise-or of option flags; 0 for default + * behavior (reserved for future growth) + * @param monitor the progress monitor to notify, or null if + * none + * @exception JavaModelException if the compilation unit could not be + * sorted. Reasons include: + * + * @exception IllegalArgumentException if the given compilation unit is null + * or if the given comparator is null, or if level is not one of + * the AST JLS level constants. + * @see org.eclipse.jdt.core.dom.BodyDeclaration + * @see #RELATIVE_ORDER + * @since 3.1 + */ + public static void sort(int level, ICompilationUnit[] compilationUnits, + int[][] positionses, Comparator comparator, int options, IProgressMonitor monitor) + throws JavaModelException { + checkASTLevel(level); + SortElementsOperation operation = new SortElementsOperation(compilationUnits, comparator, level, positionses); + operation.runOperation(monitor); + } /** * Reorders the declarations in the given compilation unit according to the @@ -463,7 +597,7 @@ if (unit == null || comparator == null) { throw new IllegalArgumentException(); } - SortElementsOperation operation = new SortElementsOperation(AST.JLS3, new IJavaElement[] { unit.getJavaElement() }, null, comparator); + SortElementsOperation operation = new SortElementsOperation(new IJavaElement[] { unit.getJavaElement() }, comparator, AST.JLS3, null); return operation.calculateEdit(unit, group); } } Index: model/org/eclipse/jdt/internal/core/SortElementsOperation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java,v retrieving revision 1.37 diff -u -r1.37 SortElementsOperation.java --- model/org/eclipse/jdt/internal/core/SortElementsOperation.java 23 Jan 2007 14:58:32 -0000 1.37 +++ model/org/eclipse/jdt/internal/core/SortElementsOperation.java 28 Jan 2007 23:49:21 -0000 @@ -51,12 +51,36 @@ * * @since 2.1 */ -public class SortElementsOperation extends JavaModelOperation { +public class SortElementsOperation extends MultiOperation { public static final String CONTAINS_MALFORMED_NODES = "malformed"; //$NON-NLS-1$ Comparator comparator; + // TODO ASB Is this important? We should be using postitionses[] instead. + /** + * @deprecated use positionses[0] instead + */ int[] positions; + int[][] positionses; int apiLevel; + + /** + * Constructor for SortElementsOperation. + * + * @param elements the array of elements (possibly more than one) + * @param comparator the comparator to use for comparison purposes + * @param level the AST API level; one of the AST LEVEL constants + * @param positionses the arrray of array of elements to track for the element + * @Since 3.3 + */ + public SortElementsOperation(IJavaElement[] elements, Comparator comparator, int level, int[][] positionses) { + // NB reordered field declarations to avoid ambiguity with the positionses element + super(elements, false); + this.comparator = comparator; + this.apiLevel = level; + this.positionses = positionses; + // TODO Do we need to keep this field? + this.positions = (positionses != null && positionses.length > 0 ? positionses[0] : null) ; + } /** * Constructor for SortElementsOperation. @@ -65,20 +89,13 @@ * @param elements * @param positions * @param comparator + * @deprecated since this only works on 1 element, use the other one instead + * @throws IllegalArgumentException if called with more than one element */ public SortElementsOperation(int level, IJavaElement[] elements, int[] positions, Comparator comparator) { - super(elements); - this.comparator = comparator; - this.positions = positions; - this.apiLevel = level; - } - - /** - * Returns the amount of work for the main task of this operation for - * progress reporting. - */ - protected int getMainAmountOfWork(){ - return this.elementsToProcess.length; + this(elements,comparator, level, (positions == null ? null : new int[][] { positions })); + if (elements.length > 1) + throw new IllegalArgumentException("Can only handle one element"); // TODO ASB Decide on right message } boolean checkMalformedNodes(ASTNode node) { @@ -91,26 +108,28 @@ return (node.getFlags() & ASTNode.MALFORMED) != 0; } - /** - * @see org.eclipse.jdt.internal.core.JavaModelOperation#executeOperation() - */ - protected void executeOperation() throws JavaModelException { - try { - beginTask(Messages.operation_sortelements, getMainAmountOfWork()); - CompilationUnit copy = (CompilationUnit) this.elementsToProcess[0]; - ICompilationUnit unit = copy.getPrimary(); - IBuffer buffer = copy.getBuffer(); - if (buffer == null) { - return; - } - char[] bufferContents = buffer.getCharacters(); - String result = processElement(unit, bufferContents); - if (!CharOperation.equals(result.toCharArray(), bufferContents)) { - copy.getBuffer().setContents(result); - } - worked(1); - } finally { - done(); + protected void processElement(IJavaElement element) throws JavaModelException { + CompilationUnit copy = (CompilationUnit) element; + ICompilationUnit unit = copy.getPrimary(); + IBuffer buffer = copy.getBuffer(); + if (buffer == null) { + return; + } + char[] bufferContents = buffer.getCharacters(); + int[] thePositions = null; + if (positionses != null) { + // find out which array we need + int i; + for(i=0;i - *
  • NO_ELEMENTS_TO_PROCESS - the compilation unit supplied to the operation is null
  • . - *
  • INVALID_ELEMENT_TYPES - the supplied elements are not an instance of IWorkingCopy
  • . - * - * @return IJavaModelStatus - */ - public IJavaModelStatus verify() { - if (this.elementsToProcess.length != 1) { - return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS); - } - if (this.elementsToProcess[0] == null) { - return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS); - } - if (!(this.elementsToProcess[0] instanceof ICompilationUnit) || !((ICompilationUnit) this.elementsToProcess[0]).isWorkingCopy()) { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this.elementsToProcess[0]); - } - return JavaModelStatus.VERIFIED_OK; - } public static void insert(TextEdit parent, TextEdit edit) { if (!parent.hasChildren()) { @@ -381,4 +379,19 @@ return thisOffset <= otherOffset && otherEnd <= thisEnd; } } + + protected String getMainTaskName() { + return Messages.operation_sortelements; + } + + /** + * Elements must be ICompilationUnits and be working copies, otherwise an + * {@link IJavaModelStatusConstants#INVALID_ELEMENT_TYPES} + * @throws JavaModelException if there is an exception determining the working copy status + */ + protected void verify(IJavaElement element) throws JavaModelException { + if (!(element instanceof ICompilationUnit) || !((ICompilationUnit) element).isWorkingCopy()) { + error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element); + } + } }