From 2e199def93ab51d3e462518bfa96bd98c8ad4ec7 Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Thu, 30 Oct 2008 08:21:41 +0000 Subject: [PATCH] Bug 204092 - Improve lexicographical sort order in the Outline view --- .../ui/editor/LexicalSortingAction.java | 91 +---- .../ui/text/COutlineInformationControl.java | 121 +------ .../org/eclipse/cdt/ui/CElementSorter.java | 342 +++++++++++------- 3 files changed, 220 insertions(+), 334 deletions(-) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/LexicalSortingAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/LexicalSortingAction.java index eace029e09d..168f4731f4c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/LexicalSortingAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/LexicalSortingAction.java @@ -14,10 +14,9 @@ package org.eclipse.cdt.internal.ui.editor; import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.ui.CElementGrouping; +import org.eclipse.cdt.ui.CElementSorter; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.ui.CPluginImages; @@ -26,12 +25,16 @@ import org.eclipse.cdt.internal.ui.CPluginImages; public class LexicalSortingAction extends Action { private static final String ACTION_NAME= "LexicalSortingAction"; //$NON-NLS-1$ - private static final String DIALOG_STORE_KEY= ACTION_NAME + ".sort"; //$NON-NLS-1$ - - private LexicalCSorter fSorter; - private TreeViewer fTreeViewer; + private final ViewerComparator fSorter; + private final TreeViewer fTreeViewer; + private final String fStoreKey; + public LexicalSortingAction(TreeViewer treeViewer) { + this(treeViewer, ".sort"); //$NON-NLS-1$ + } + + public LexicalSortingAction(TreeViewer treeViewer, String storeKeySuffix) { super(CUIPlugin.getResourceString(ACTION_NAME + ".label")); //$NON-NLS-1$ setDescription(CUIPlugin.getResourceString(ACTION_NAME + ".description")); //$NON-NLS-1$ @@ -40,9 +43,10 @@ public class LexicalSortingAction extends Action { CPluginImages.setImageDescriptors(this, CPluginImages.T_LCL, CPluginImages.IMG_ALPHA_SORTING); fTreeViewer= treeViewer; - fSorter= new LexicalCSorter(); - - boolean checked= CUIPlugin.getDefault().getDialogSettings().getBoolean(DIALOG_STORE_KEY); + fSorter= new CElementSorter(); + fStoreKey= ACTION_NAME + storeKeySuffix; + + boolean checked= CUIPlugin.getDefault().getDialogSettings().getBoolean(fStoreKey); valueChanged(checked, false); } @@ -53,76 +57,13 @@ public class LexicalSortingAction extends Action { private void valueChanged(boolean on, boolean store) { setChecked(on); - fTreeViewer.setSorter(on ? fSorter : null); + fTreeViewer.setComparator(on ? fSorter : null); String key= ACTION_NAME + ".tooltip" + (on ? ".on" : ".off"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ setToolTipText(CUIPlugin.getResourceString(key)); if (store) { - CUIPlugin.getDefault().getDialogSettings().put(DIALOG_STORE_KEY, on); - } - } - - private class LexicalCSorter extends ViewerSorter { - public boolean isSorterProperty(Object element, Object property) { - return true; - } - - @Override - public int category(Object obj) { - if (obj instanceof ICElement) { - ICElement elem= (ICElement)obj; - switch (elem.getElementType()) { - case ICElement.C_MACRO: - return 2; - case ICElement.C_INCLUDE: - return 3; - case ICElement.C_USING: - return 4; - - case ICElement.C_TYPEDEF: - return 10; - case ICElement.C_CLASS: - case ICElement.C_CLASS_DECLARATION: - case ICElement.C_TEMPLATE_CLASS: - case ICElement.C_TEMPLATE_CLASS_DECLARATION: - return 11; - case ICElement.C_STRUCT: - case ICElement.C_STRUCT_DECLARATION: - case ICElement.C_TEMPLATE_STRUCT: - case ICElement.C_TEMPLATE_STRUCT_DECLARATION: - return 12; - case ICElement.C_UNION: - case ICElement.C_UNION_DECLARATION: - case ICElement.C_TEMPLATE_UNION: - case ICElement.C_TEMPLATE_UNION_DECLARATION: - return 13; - case ICElement.C_ENUMERATION: - return 14; - - case ICElement.C_VARIABLE: - case ICElement.C_VARIABLE_DECLARATION: - return 20; - case ICElement.C_FIELD: - return 21; - case ICElement.C_FUNCTION: - case ICElement.C_FUNCTION_DECLARATION: - case ICElement.C_TEMPLATE_FUNCTION: - case ICElement.C_TEMPLATE_FUNCTION_DECLARATION: - return 22; - case ICElement.C_METHOD: - case ICElement.C_METHOD_DECLARATION: - case ICElement.C_TEMPLATE_METHOD: - case ICElement.C_TEMPLATE_METHOD_DECLARATION: - return 23; - - case ICElement.C_NAMESPACE: - return 30; - } - } else if (obj instanceof CElementGrouping) { - return 0; - } - return 100; + CUIPlugin.getDefault().getDialogSettings().put(fStoreKey, on); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java index ba27bb47d4c..0624cf7abbe 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/COutlineInformationControl.java @@ -12,29 +12,20 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.PlatformUI; - import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.util.CElementBaseLabels; -import org.eclipse.cdt.ui.CElementGrouping; - -import org.eclipse.cdt.internal.ui.CPluginImages; -import org.eclipse.cdt.internal.ui.ICHelpContextIds; -import org.eclipse.cdt.internal.ui.actions.ActionMessages; import org.eclipse.cdt.internal.ui.editor.CContentOutlinerProvider; +import org.eclipse.cdt.internal.ui.editor.LexicalSortingAction; import org.eclipse.cdt.internal.ui.util.ProblemTreeViewer; import org.eclipse.cdt.internal.ui.viewsupport.AppearanceAwareLabelProvider; import org.eclipse.cdt.internal.ui.viewsupport.DecoratingCLabelProvider; @@ -81,7 +72,7 @@ public class COutlineInformationControl extends AbstractInformationControl { tree.setLayoutData(new GridData(GridData.FILL_BOTH)); fOutlineContentProvider = new CContentOutlinerProvider(treeViewer); treeViewer.setContentProvider(fOutlineContentProvider); - fSortingAction= new LexicalSortingAction(treeViewer); + fSortingAction= new LexicalSortingAction(treeViewer, ".isChecked"); //$NON-NLS-1$ treeViewer.addFilter(new NamePatternFilter()); treeViewer.setLabelProvider(new DecoratingCLabelProvider( new AppearanceAwareLabelProvider(TEXT_FLAGS, IMAGE_FLAGS), true)); @@ -125,112 +116,4 @@ public class COutlineInformationControl extends AbstractInformationControl { viewMenu.add(fSortingAction); } - - private class LexicalCSorter extends ViewerComparator { - public boolean isSorterProperty(Object element, Object property) { - return true; - } - - @Override - public int category(Object obj) { - if (obj instanceof ICElement) { - ICElement elem= (ICElement)obj; - switch (elem.getElementType()) { - case ICElement.C_MACRO: - return 2; - case ICElement.C_INCLUDE: - return 3; - case ICElement.C_USING: - return 4; - - case ICElement.C_TYPEDEF: - return 10; - case ICElement.C_CLASS: - case ICElement.C_CLASS_DECLARATION: - case ICElement.C_TEMPLATE_CLASS: - case ICElement.C_TEMPLATE_CLASS_DECLARATION: - return 11; - case ICElement.C_STRUCT: - case ICElement.C_STRUCT_DECLARATION: - case ICElement.C_TEMPLATE_STRUCT: - case ICElement.C_TEMPLATE_STRUCT_DECLARATION: - return 12; - case ICElement.C_UNION: - case ICElement.C_UNION_DECLARATION: - case ICElement.C_TEMPLATE_UNION: - case ICElement.C_TEMPLATE_UNION_DECLARATION: - return 13; - case ICElement.C_ENUMERATION: - return 14; - - case ICElement.C_VARIABLE: - case ICElement.C_VARIABLE_DECLARATION: - return 20; - case ICElement.C_FIELD: - return 21; - case ICElement.C_FUNCTION: - case ICElement.C_FUNCTION_DECLARATION: - case ICElement.C_TEMPLATE_FUNCTION: - case ICElement.C_TEMPLATE_FUNCTION_DECLARATION: - return 22; - case ICElement.C_METHOD: - case ICElement.C_METHOD_DECLARATION: - case ICElement.C_TEMPLATE_METHOD: - case ICElement.C_TEMPLATE_METHOD_DECLARATION: - return 23; - - case ICElement.C_NAMESPACE: - return 30; - } - } else if (obj instanceof CElementGrouping) { - return 0; - } - return 100; - } - } - - /** - * - * The view menu's Sort action. - * - * @author P.Tomaszewski - */ - private class LexicalSortingAction extends Action { - - private static final String STORE_LEXICAL_SORTING_CHECKED= "LexicalSortingAction.isChecked"; //$NON-NLS-1$ - - /** The tree viewer */ - private TreeViewer fOutlineViewer; - /** Sorter for tree viewer. */ - private LexicalCSorter fSorter; - - /** - * Creates new action. - */ - public LexicalSortingAction(TreeViewer treeViewer) { - super(ActionMessages.getString("COutlineInformationControl.viewMenu.sort.label"), IAction.AS_CHECK_BOX); //$NON-NLS-1$ - CPluginImages.setLocalImageDescriptors(this, CPluginImages.IMG_ALPHA_SORTING); - PlatformUI.getWorkbench().getHelpSystem().setHelp(this, ICHelpContextIds.LEXICAL_SORTING_BROWSING_ACTION); - - fOutlineViewer= treeViewer; - fSorter= new LexicalCSorter(); - - boolean checked= getDialogSettings().getBoolean(STORE_LEXICAL_SORTING_CHECKED); - setChecked(checked); - - if (checked && fOutlineViewer != null) { - fOutlineViewer.setComparator(fSorter); - } - } - - /* - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - final boolean on= isChecked(); - fOutlineViewer.setComparator(on ? fSorter : null); - getDialogSettings().put(STORE_LEXICAL_SORTING_CHECKED, on); - } - } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementSorter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementSorter.java index a33e0033a5c..603d8f9092c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementSorter.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CElementSorter.java @@ -14,9 +14,7 @@ package org.eclipse.cdt.ui; import java.util.Comparator; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; @@ -30,31 +28,14 @@ import org.eclipse.ui.model.IWorkbenchAdapter; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.IArchive; import org.eclipse.cdt.core.model.IArchiveContainer; -import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBinaryContainer; -import org.eclipse.cdt.core.model.ICContainer; import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.ICModel; -import org.eclipse.cdt.core.model.ICProject; -import org.eclipse.cdt.core.model.IFunction; -import org.eclipse.cdt.core.model.IFunctionDeclaration; -import org.eclipse.cdt.core.model.IInclude; import org.eclipse.cdt.core.model.IIncludeReference; import org.eclipse.cdt.core.model.ILibraryReference; -import org.eclipse.cdt.core.model.IMacro; -import org.eclipse.cdt.core.model.IMethod; +import org.eclipse.cdt.core.model.IMember; import org.eclipse.cdt.core.model.IMethodDeclaration; -import org.eclipse.cdt.core.model.INamespace; import org.eclipse.cdt.core.model.ISourceRoot; -import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.core.model.IUsing; -import org.eclipse.cdt.core.model.IVariable; -import org.eclipse.cdt.core.model.IVariableDeclaration; - -import org.eclipse.cdt.internal.ui.cview.IncludeRefContainer; -import org.eclipse.cdt.internal.ui.cview.LibraryRefContainer; /** * A sorter to sort the file and the folders in the C viewer in the following order: @@ -71,7 +52,6 @@ public class CElementSorter extends ViewerSorter { protected static final int CMODEL = 0; protected static final int PROJECTS = 10; - //protected static final int OUTPUTREFCONTAINER = 11; protected static final int BINARYCONTAINER = 12; protected static final int ARCHIVECONTAINER = 13; protected static final int INCLUDEREFCONTAINER = 14; @@ -110,7 +90,23 @@ public class CElementSorter extends ViewerSorter { protected static final int RESOURCES= 201; protected static final int STORAGE= 202; protected static final int OTHERS= 500; - + + + /* + * Constants added for names starting with '_' or '__' + */ + private static final int NORMAL = 0; + private static final int RESERVED = 1; + private static final int SYSTEM = 2; + + /* + * Constants for ordering different member kinds. + */ + private static final int STATIC_MEMBER = 0; + private static final int CONSTRUCTOR = 1; + private static final int DESTRUCTOR = 2; + private static final int MEMBER = 3; + /** * Flag indicating whether header files and source files should be separated. * If true, header files will be sorted before source files, @@ -128,116 +124,128 @@ public class CElementSorter extends ViewerSorter { @Override public int category (Object element) { - if (element instanceof ICModel) { - return CMODEL; - } else if (element instanceof ICProject) { - return PROJECTS; - } else if (element instanceof ISourceRoot) { - return SOURCEROOTS; - } else if (element instanceof IBinaryContainer) { - return BINARYCONTAINER; - } else if (element instanceof IArchiveContainer) { - return ARCHIVECONTAINER; - } else if (element instanceof ICContainer) { - return CCONTAINERS; - } else if (element instanceof ITranslationUnit) { - ITranslationUnit tu = (ITranslationUnit)element; - if (fSeparateHeaderAndSource) { - if (CoreModel.isValidHeaderUnitName(tu.getCProject().getProject(), tu.getElementName())) { - return TRANSLATIONUNIT_HEADERS; + if (element instanceof ICElement) { + ICElement cElement = (ICElement) element; + switch (cElement.getElementType()) { + case ICElement.C_MODEL: + return CMODEL; + case ICElement.C_PROJECT: + return PROJECTS; + case ICElement.C_CCONTAINER: + if (element instanceof ISourceRoot) { + return SOURCEROOTS; } - if (CoreModel.isValidSourceUnitName(tu.getCProject().getProject(), tu.getElementName())) { - return TRANSLATIONUNIT_SOURCE; + return CCONTAINERS; + case ICElement.C_VCONTAINER: + if (element instanceof IBinaryContainer) { + return BINARYCONTAINER; + } else if (element instanceof IArchiveContainer) { + return ARCHIVECONTAINER; + } else if (element instanceof ILibraryReference) { + return LIBRARYREFERENCES; + } else if (element instanceof IIncludeReference) { + return INCLUDEREFERENCES; } - } - return TRANSLATIONUNITS; - } else if (element instanceof IInclude) { - return INCLUDES; - } else if (element instanceof IMacro) { - return MACROS; - } else if (element instanceof INamespace) { - String name = ((ICElement)element).getElementName(); - if( name.length() > 0 ) { - if (name.startsWith("__")) { //$NON-NLS-1$ - return NAMESPACES_SYSTEM; - } - if (name.charAt(0) == '_') { - return NAMESPACES_RESERVED; + return CCONTAINERS; + case ICElement.C_UNIT: + if (fSeparateHeaderAndSource) { + if (CoreModel.isValidHeaderUnitName(cElement.getCProject().getProject(), cElement.getElementName())) { + return TRANSLATIONUNIT_HEADERS; + } + if (CoreModel.isValidSourceUnitName(cElement.getCProject().getProject(), cElement.getElementName())) { + return TRANSLATIONUNIT_SOURCE; + } } + return TRANSLATIONUNITS; + case ICElement.C_INCLUDE: + return INCLUDES; + case ICElement.C_MACRO: + return MACROS; + case ICElement.C_NAMESPACE: + return NAMESPACES + getNameKind(cElement.getElementName()); + case ICElement.C_USING: + return USINGS; + case ICElement.C_TYPEDEF: + case ICElement.C_CLASS: + case ICElement.C_CLASS_DECLARATION: + case ICElement.C_TEMPLATE_CLASS: + case ICElement.C_TEMPLATE_CLASS_DECLARATION: + case ICElement.C_STRUCT: + case ICElement.C_STRUCT_DECLARATION: + case ICElement.C_TEMPLATE_STRUCT: + case ICElement.C_TEMPLATE_STRUCT_DECLARATION: + case ICElement.C_UNION: + case ICElement.C_UNION_DECLARATION: + case ICElement.C_TEMPLATE_UNION: + case ICElement.C_TEMPLATE_UNION_DECLARATION: + case ICElement.C_ENUMERATION: + // TODO need own categories + return NAMESPACES; + case ICElement.C_FUNCTION_DECLARATION: + case ICElement.C_TEMPLATE_FUNCTION_DECLARATION: + return FUNCTIONDECLARATIONS; + case ICElement.C_METHOD_DECLARATION: + case ICElement.C_TEMPLATE_METHOD_DECLARATION: + return METHODDECLARATIONS; + case ICElement.C_VARIABLE_DECLARATION: + return VARIABLEDECLARATIONS; + case ICElement.C_VARIABLE: + case ICElement.C_TEMPLATE_VARIABLE: + case ICElement.C_FIELD: + return VARIABLES + getNameKind(cElement.getElementName()); + case ICElement.C_FUNCTION: + case ICElement.C_TEMPLATE_FUNCTION: + case ICElement.C_METHOD: + case ICElement.C_TEMPLATE_METHOD: + return FUNCTIONS + getNameKind(cElement.getElementName()); + case ICElement.C_ARCHIVE: + return ARCHIVES; + case ICElement.C_BINARY: + return BINARIES; + default: + return CELEMENTS + getNameKind(cElement.getElementName()); } - return NAMESPACES; - } else if (element instanceof IUsing) { - return USINGS; - } else if (element instanceof IFunctionDeclaration && ! (element instanceof IFunction)) { - return FUNCTIONDECLARATIONS; - } else if (element instanceof IMethodDeclaration && !(element instanceof IMethod)) { - return METHODDECLARATIONS; - } else if (element instanceof IVariableDeclaration) { - return VARIABLEDECLARATIONS; - } else if (element instanceof IVariable) { - String name = ((ICElement)element).getElementName(); - if (name.startsWith("__")) { //$NON-NLS-1$ - return VARIABLES_SYSTEM; + } else if (element instanceof IResource) { + IResource resource = (IResource) element; + switch (resource.getType()) { + case IResource.PROJECT: + return PROJECTS; + case IResource.FOLDER: + return RESOURCEFOLDERS; + default: + return RESOURCES; } - if (name.charAt(0) == '_') { - return VARIABLES_RESERVED; - } - return VARIABLES; - } else if (element instanceof IFunction) { - String name = ((ICElement)element).getElementName(); - if (name.startsWith("__")) { //$NON-NLS-1$ - return FUNCTIONS_SYSTEM; - } - if (name.charAt(0) == '_') { - return FUNCTIONS_RESERVED; - } - return FUNCTIONS; - } else if (element instanceof IArchive) { - return ARCHIVES; - } else if (element instanceof IBinary) { - return BINARIES; - } else if (element instanceof ILibraryReference) { - return LIBRARYREFERENCES; - } else if (element instanceof IIncludeReference) { - return INCLUDEREFERENCES; - } else if (element instanceof ICElement) { - String name = ((ICElement)element).getElementName(); - if( name.length() > 0 ) { - if (name.startsWith("__")) { //$NON-NLS-1$ - return CELEMENTS_SYSTEM; - } - if (name.charAt(0) == '_') { - return CELEMENTS_RESERVED; - } - } - return CELEMENTS; - } else if (element instanceof IFile) { - return RESOURCES; - } else if (element instanceof IProject) { - return PROJECTS; - } else if (element instanceof IContainer) { - return RESOURCEFOLDERS; } else if (element instanceof IStorage) { return STORAGE; - } else if (element instanceof LibraryRefContainer) { - return LIBRARYREFCONTAINER; - } else if (element instanceof IncludeRefContainer) { - return INCLUDEREFCONTAINER; } else if (element instanceof CElementGrouping) { int type = ((CElementGrouping)element).getType(); - if (type == CElementGrouping.INCLUDES_GROUPING) { + switch (type) { + case CElementGrouping.INCLUDES_GROUPING: return INCLUDES; - } else if (type == CElementGrouping.CLASS_GROUPING) { + case CElementGrouping.CLASS_GROUPING: return VARIABLES; - } else if (type == CElementGrouping.NAMESPACE_GROUPING) { + case CElementGrouping.NAMESPACE_GROUPING: return NAMESPACES; + case CElementGrouping.LIBRARY_REF_CONTAINER: + return LIBRARYREFCONTAINER; + case CElementGrouping.INCLUDE_REF_CONTAINER: + return INCLUDEREFCONTAINER; } } return OTHERS; } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) - */ + + private int getNameKind(String name) { + int length = name.length(); + if (length > 0 && name.charAt(0) == '_') { + if (length > 1 && name.charAt(1) == '_') { + return SYSTEM; + } + return RESERVED; + } + return NORMAL; + } + @Override public int compare(Viewer viewer, Object e1, Object e2) { int cat1 = category(e1); @@ -281,48 +289,102 @@ public class CElementSorter extends ViewerSorter { return compareWithLabelProvider(viewer, e1, e2); } + if (cat1 == NAMESPACES) { + // workaround for missing category for classes, structs, etc. + int type1 = ((ICElement) e1).getElementType(); + int type2 = ((ICElement) e2).getElementType(); + if (type1 != type2) { + if (type1 == ICElement.C_NAMESPACE || type2 == ICElement.C_NAMESPACE) { + return type1 - type2; + } + } + } + + String ns1 = ""; //$NON-NLS-1$ + String ns2 = ns1; + String name1; - boolean e1destructor = false; String name2; - boolean e2destructor = false; if (e1 instanceof ICElement) { name1 = ((ICElement)e1).getElementName(); - if (e1 instanceof IMethodDeclaration) { - IMethodDeclaration method = (IMethodDeclaration)e1; - try { - if (method.isDestructor()) { - name1 = ((ICElement)e1).getElementName().substring(1); - e1destructor = true; - } - } catch (CModelException e) { - } + int idx = name1.lastIndexOf("::"); //$NON-NLS-1$ + if (idx >= 0) { + ns1 = name1.substring(0, idx); + name1 = name1.substring(idx + 2); + } + if (name1.length() > 0 && name1.charAt(0) == '~') { + name1 = name1.substring(1); } } else { name1 = e1.toString(); } if (e2 instanceof ICElement) { name2 = ((ICElement)e2).getElementName(); - if (e2 instanceof IMethodDeclaration) { - IMethodDeclaration method = (IMethodDeclaration)e2; - try { - if (method.isDestructor()) { - name2 = ((ICElement)e2).getElementName().substring(1); - e2destructor = true; - } - } catch (CModelException e) { - } + int idx = name2.lastIndexOf("::"); //$NON-NLS-1$ + if (idx >= 0) { + ns2 = name2.substring(0, idx); + name2 = name2.substring(idx + 2); + } + if (name2.length() > 0 && name2.charAt(0) == '~') { + name2 = name1.substring(1); } } else { name2 = e2.toString(); } - int result = comparator.compare(name1, name2); - if (result == 0 && (e1destructor != e2destructor)) { - result = e1destructor ? 1 : -1; + + // compare namespace + int result = comparator.compare(ns1, ns2); + if (result != 0) { + return result; + } + + // compare method/member kind + if (e1 instanceof IMethodDeclaration && e2 instanceof IMethodDeclaration) { + result = getMethodKind((IMethodDeclaration) e1) - getMethodKind((IMethodDeclaration) e2); + } else if (e1 instanceof IMember && e2 instanceof IMember) { + result = getMemberKind((IMember) e1) - getMemberKind((IMember) e2); + } + if (result != 0) { + return result; + } + + // compare simple name + result = comparator.compare(name1, name2); + if (result != 0) { + return result; } return result; } + private int getMethodKind(IMethodDeclaration method) { + try { + if (method.isStatic()) { + return STATIC_MEMBER; + } + if (method.isConstructor()) { + return CONSTRUCTOR; + } + if (method.isDestructor()) { + return DESTRUCTOR; + } + } catch (CModelException exc) { + // ignore + } + return MEMBER; + } + + private int getMemberKind(IMember member) { + try { + if (member.isStatic()) { + return STATIC_MEMBER; + } + } catch (CModelException exc) { + // ignore + } + return MEMBER; + } + private ISourceRoot getSourceRoot(Object element) { ICElement celement = (ICElement)element; while (! (celement instanceof ISourceRoot) && celement != null) {