Index: core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java,v retrieving revision 1.6 diff -u -r1.6 AddUnimplementedMethodsOperation.java --- core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java 31 Dec 2008 21:13:16 -0000 1.6 +++ core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java 30 Jun 2009 14:12:37 -0000 @@ -11,6 +11,8 @@ package org.eclipse.jdt.internal.corext.fix; +import java.util.Arrays; + import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; @@ -36,6 +38,7 @@ import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix.CompilationUnitRewriteOperation; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; import org.eclipse.jdt.internal.corext.util.Messages; +import org.eclipse.jdt.internal.corext.util.MethodsSourcePositionComparator; import org.eclipse.jdt.ui.JavaElementLabels; @@ -153,6 +156,8 @@ if (binding == null) return new IMethodBinding[0]; - return StubUtility2.getUnimplementedMethods(binding, implementAbstractsOfInput); + IMethodBinding[] unimplementedMethods= StubUtility2.getUnimplementedMethods(binding, implementAbstractsOfInput); + Arrays.sort(unimplementedMethods, new MethodsSourcePositionComparator(binding)); + return unimplementedMethods; } } Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java,v retrieving revision 1.40 diff -u -r1.40 AddUnimplementedMethodsOperation.java --- core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java 31 Dec 2008 21:13:24 -0000 1.40 +++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java 30 Jun 2009 14:12:37 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jdt.internal.corext.codemanipulation; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.CoreException; @@ -41,6 +42,7 @@ import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; +import org.eclipse.jdt.internal.corext.util.MethodsSourcePositionComparator; import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; @@ -193,6 +195,8 @@ methodsToImplement= StubUtility2.getUnimplementedMethods(currTypeBinding); } + Arrays.sort(methodsToImplement, new MethodsSourcePositionComparator(fType)); + ImportRewriteContext context= null; int insertionPosition= fInsertPos; if (insertionPosition == -1 && fASTRoot.types().size() > 0) { Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddDelegateMethodsOperation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddDelegateMethodsOperation.java,v retrieving revision 1.34 diff -u -r1.34 AddDelegateMethodsOperation.java --- core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddDelegateMethodsOperation.java 11 Sep 2008 11:59:48 -0000 1.34 +++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddDelegateMethodsOperation.java 30 Jun 2009 14:12:36 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jdt.internal.corext.codemanipulation; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.Assert; @@ -40,6 +41,7 @@ import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; +import org.eclipse.jdt.internal.corext.util.DelegateEntryComparator; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.ui.CodeStyleConfiguration; @@ -173,6 +175,8 @@ ContextSensitiveImportRewriteContext context= new ContextSensitiveImportRewriteContext(fASTRoot, typeDecl.getStartPosition(), importRewrite); + Arrays.sort(fDelegatesToCreate, new DelegateEntryComparator()); + for (int i= 0; i < fDelegatesToCreate.length; i++) { IMethodBinding delegateMethod= fDelegatesToCreate[i].delegateMethod; IVariableBinding field= fDelegatesToCreate[i].field; Index: core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddGetterSetterOperation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddGetterSetterOperation.java,v retrieving revision 1.48 diff -u -r1.48 AddGetterSetterOperation.java --- core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddGetterSetterOperation.java 11 Sep 2008 11:59:47 -0000 1.48 +++ core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddGetterSetterOperation.java 30 Jun 2009 14:12:37 -0000 @@ -10,6 +10,10 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.codemanipulation; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -308,28 +312,31 @@ } fSkipAllExisting= (fSkipExistingQuery == null); - if (!fSort) { - for (int index= 0; index < fAccessorFields.length; index++) { - generateGetterMethod(fAccessorFields[index], listRewriter); - generateSetterMethod(fAccessorFields[index], astRewrite, listRewriter); + + Set accessors = new HashSet(Arrays.asList(fAccessorFields)); + Set getters = new HashSet(Arrays.asList(fGetterFields)); + Set setters= new HashSet(Arrays.asList(fSetterFields)); + IField[] fields= fType.getFields(); + for (int i= 0; i < fields.length; i++) { + if (accessors.contains(fields[i])) { + generateGetterMethod(fields[i], listRewriter); + generateSetterMethod(fields[i], astRewrite, listRewriter); + monitor.worked(1); + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } else if (getters.contains(fields[i])) { + generateGetterMethod(fields[i], listRewriter); + monitor.worked(1); + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } else if (setters.contains(fields[i])) { + generateSetterMethod(fields[i], astRewrite, listRewriter); monitor.worked(1); if (monitor.isCanceled()) { throw new OperationCanceledException(); } - } - } - for (int index= 0; index < fGetterFields.length; index++) { - generateGetterMethod(fGetterFields[index], listRewriter); - monitor.worked(1); - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } - for (int index= 0; index < fSetterFields.length; index++) { - generateSetterMethod(fSetterFields[index], astRewrite, listRewriter); - monitor.worked(1); - if (monitor.isCanceled()) { - throw new OperationCanceledException(); } } fEdit= astRewrite.rewriteAST(); Index: core extension/org/eclipse/jdt/internal/corext/util/DelegateEntryComparator.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/util/DelegateEntryComparator.java diff -N core extension/org/eclipse/jdt/internal/corext/util/DelegateEntryComparator.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/util/DelegateEntryComparator.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,72 @@ +package org.eclipse.jdt.internal.corext.util; + +import java.util.Comparator; + +import org.eclipse.jdt.core.IField; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.ISourceRange; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.IVariableBinding; + +import org.eclipse.jdt.internal.corext.codemanipulation.AddDelegateMethodsOperation.DelegateEntry; + +/** + * A comparator which sorts instances of DelegateEntry according to order in which delegate methods + * should be generated in a type. More formally, if T is a class and d1 + * and d2 are two DelegateEntries representing delegate methods which are about to be + * added to T then according to this comparator d1 is less than + * d2 iff one of following holds: + * + */ +public class DelegateEntryComparator implements Comparator { + + public DelegateEntryComparator() { + } + + public int compare(Object o1, Object o2) { + if (!(o1 instanceof DelegateEntry)) { + return -1; + } + if (!(o2 instanceof DelegateEntry)) { + return -1; + } + DelegateEntry firstEntry= (DelegateEntry)o1; + DelegateEntry secondEntry= (DelegateEntry)o2; + IVariableBinding firstVariable= firstEntry.field; + IVariableBinding secondVariable= secondEntry.field; + + if (firstVariable.equals(secondVariable)) { + try { + IMethod firstMethod= (IMethod)firstEntry.delegateMethod.getJavaElement(); + IMethod secondMethod= (IMethod)secondEntry.delegateMethod.getJavaElement(); + ISourceRange firstSourceRange= firstMethod.getSourceRange(); + ISourceRange secondSourceRange= secondMethod.getSourceRange(); + if (firstSourceRange == null || secondSourceRange == null) { + return firstMethod.getElementName().compareTo(secondMethod.getElementName()); + } else { + return firstSourceRange.getOffset() - secondSourceRange.getOffset(); + } + } catch (JavaModelException e) { + return -1; + } + } + + IField firstField= (IField)firstVariable.getJavaElement(); + IField secondField= (IField)secondVariable.getJavaElement(); + try { + return firstField.getSourceRange().getOffset() - secondField.getSourceRange().getOffset(); + } catch (JavaModelException e) { + return -1; + } + } +} Index: core extension/org/eclipse/jdt/internal/corext/util/MethodsSourcePositionComparator.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/util/MethodsSourcePositionComparator.java diff -N core extension/org/eclipse/jdt/internal/corext/util/MethodsSourcePositionComparator.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/util/MethodsSourcePositionComparator.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,120 @@ +package org.eclipse.jdt.internal.corext.util; + +import java.util.Comparator; + +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.ISourceRange; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; + +/** + * A comparator which sorts methods (IMethodBinding) of a type passed as constructor argument, + * according to their order in source files. More formally, if m1 and m2 + * are methods of type T then according to this comparator m1 is less than + * m2 iff one of following holds: + * + */ +public class MethodsSourcePositionComparator implements Comparator { + + private final ITypeBinding fTypeBinding; + + public MethodsSourcePositionComparator(ITypeBinding typeBinding) { + if (typeBinding == null) { + throw new IllegalArgumentException(); + } + fTypeBinding= typeBinding; + } + + public int compare(Object o1, Object o2) { + if (!(o1 instanceof IMethodBinding)) { + return -1; + } + if (!(o2 instanceof IMethodBinding)) { + return -1; + } + IMethodBinding firstMethodBinding= (IMethodBinding)o1; + IMethodBinding secondMethodBinding= (IMethodBinding)o2; + ITypeBinding firstMethodType= firstMethodBinding.getDeclaringClass(); + ITypeBinding secondMethodType= secondMethodBinding.getDeclaringClass(); + + if (firstMethodType.equals(secondMethodType)) { + return compareInTheSameType(firstMethodBinding, secondMethodBinding); + } + + if (firstMethodType.equals(fTypeBinding)) { + return -1; + } + if (secondMethodType.equals(fTypeBinding)) { + return 1; + } + + ITypeBinding type= fTypeBinding; + int count= 0, firstCount= -1, secondCount= -1; + while ((type= type.getSuperclass()) != null) { + if (firstMethodType.equals(type)) { + firstCount= count; + } + if (secondMethodType.equals(type)) { + secondCount= count; + } + count++; + } + if (firstCount != -1 && secondCount != -1) { + return -(firstCount - secondCount); + } + if (firstCount != -1 && secondCount == -1) { + return -1; + } + if (firstCount == -1 && secondCount != -1) { + return 1; + } + + ITypeBinding[] interfaces= fTypeBinding.getInterfaces(); + for (int i= 0; i < interfaces.length; i++) { + if (firstMethodType.equals(interfaces[i])) { + return -1; + } + if (secondMethodType.equals(interfaces[i])) { + return 1; + } + } + return 0; + } + + private int compareInTheSameType(IMethodBinding firstMethodBinding, IMethodBinding secondMethodBinding) { + try { + IMethod firstMethod= (IMethod)firstMethodBinding.getJavaElement(); + IMethod secondMethod= (IMethod)secondMethodBinding.getJavaElement(); + if (firstMethod == null || secondMethod == null) { + return -1; + } + ISourceRange firstSourceRange= firstMethod.getSourceRange(); + ISourceRange secondSourceRange= secondMethod.getSourceRange(); + + if (firstSourceRange == null || secondSourceRange == null) { + return firstMethod.getElementName().compareTo(secondMethod.getElementName()); + } else { + return firstSourceRange.getOffset() - secondSourceRange.getOffset(); + } + } catch (JavaModelException e) { + return -1; + } + } +}