1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Type Hierarchy: fix refresh after deleting input

This commit is contained in:
Markus Schorn 2007-01-22 14:29:36 +00:00
parent 1f146e629b
commit d66c6bfc64
8 changed files with 222 additions and 173 deletions

View file

@ -40,7 +40,7 @@ import org.eclipse.jface.text.IRegion;
public class CElementHandleFactory {
private CElementHandleFactory() {}
public static ICElement create(ITranslationUnit tu, IBinding binding,
public static ICElementHandle create(ITranslationUnit tu, IBinding binding,
IRegion region, long timestamp) throws CoreException, DOMException {
ICElement parentElement= create(tu, binding.getScope());

View file

@ -17,6 +17,8 @@ public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.typehierarchy.messages"; //$NON-NLS-1$
public static String OpenTypeHierarchyAction_label;
public static String OpenTypeHierarchyAction_tooltip;
public static String THGraph_error_elementNotFound;
public static String THHierarchyModel_errorComputingHierarchy;
public static String THHierarchyModel_Job_title;
public static String THHistoryDropDownAction_ClearHistory;
public static String THHistoryDropDownAction_tooltip;

View file

@ -18,36 +18,54 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
public class THGraph {
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
class THGraph {
private THGraphNode fInputNode= null;
private HashSet fRootNodes= new HashSet();
private HashSet fLeaveNodes= new HashSet();
private HashMap fNodes= new HashMap();
public void clear() {
fRootNodes.clear();
fLeaveNodes.clear();
fNodes.clear();
public THGraph() {
}
public THGraphNode getInputNode() {
return fInputNode;
}
public THGraphNode getNode(ICElement elem) {
return (THGraphNode) fNodes.get(elem);
}
public THGraphNode addNode(ICElement elem) {
THGraphNode node= (THGraphNode) fNodes.get(elem);
private THGraphNode addNode(ICElement input) {
THGraphNode node= (THGraphNode) fNodes.get(input);
if (node == null) {
node= new THGraphNode(elem);
fNodes.put(elem, node);
node= new THGraphNode(input);
fNodes.put(input, node);
fRootNodes.add(node);
fLeaveNodes.add(node);
}
return node;
}
public THGraphEdge addEdge(THGraphNode from, THGraphNode to) {
private THGraphEdge addEdge(THGraphNode from, THGraphNode to) {
if (createsLoop(from, to)) {
return null;
}
@ -92,4 +110,160 @@ public class THGraph {
public Collection getLeaveNodes() {
return fLeaveNodes;
}
public void defineInputNode(IIndex index, ICElement input) {
if (input instanceof ICElementHandle) {
fInputNode= addNode(input);
}
else if (input != null) {
try {
IIndexName name= IndexUI.elementToName(index, input);
if (name != null) {
ICElementHandle inputHandle= IndexUI.getCElementForName(input.getCProject(), index, name);
fInputNode= addNode(inputHandle);
}
else {
fInputNode= addNode(input);
}
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
} catch (DOMException e) {
CUIPlugin.getDefault().log(e);
}
}
}
public void addSuperClasses(IIndex index, IProgressMonitor monitor) {
if (fInputNode == null) {
return;
}
HashSet handled= new HashSet();
ArrayList stack= new ArrayList();
stack.add(fInputNode.getElement());
handled.add(fInputNode.getElement());
while (!stack.isEmpty()) {
if (monitor.isCanceled()) {
return;
}
ICElement elem= (ICElement) stack.remove(stack.size()-1);
THGraphNode graphNode= addNode(elem);
try {
IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) binding;
addMembers(index, graphNode, ct);
ICPPBase[] bases= ct.getBases();
for (int i = 0; i < bases.length; i++) {
if (monitor.isCanceled()) {
return;
}
ICPPBase base= bases[i];
IBinding basecl= base.getBaseClass();
ICElementHandle[] baseElems= IndexUI.findRepresentative(index, basecl);
if (baseElems.length > 0) {
ICElementHandle baseElem= baseElems[0];
THGraphNode baseGraphNode= addNode(baseElem);
addMembers(index, baseGraphNode, basecl);
addEdge(graphNode, baseGraphNode);
if (handled.add(baseElem)) {
stack.add(baseElem);
}
}
}
}
} catch (DOMException e) {
CUIPlugin.getDefault().log(e);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
}
public void addSubClasses(IIndex index, IProgressMonitor monitor) {
if (fInputNode == null) {
return;
}
HashSet handled= new HashSet();
ArrayList stack= new ArrayList();
ICElement element = fInputNode.getElement();
stack.add(element);
handled.add(element);
while (!stack.isEmpty()) {
if (monitor.isCanceled()) {
return;
}
ICElement elem= (ICElement) stack.remove(stack.size()-1);
THGraphNode graphNode= addNode(elem);
try {
IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding instanceof ICPPClassType) {
IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES);
for (int i = 0; i < names.length; i++) {
if (monitor.isCanceled()) {
return;
}
IIndexName indexName = names[i];
if (indexName.isBaseSpecifier()) {
IIndexName subClassDef= indexName.getEnclosingDefinition();
if (subClassDef != null) {
IBinding subClass= index.findBinding(subClassDef);
ICElementHandle[] subClassElems= IndexUI.findRepresentative(index, subClass);
if (subClassElems.length > 0) {
ICElementHandle subClassElem= subClassElems[0];
THGraphNode subGraphNode= addNode(subClassElem);
addMembers(index, subGraphNode, subClass);
addEdge(subGraphNode, graphNode);
if (handled.add(subClassElem)) {
stack.add(subClassElem);
}
}
}
}
}
}
} catch (DOMException e) {
CUIPlugin.getDefault().log(e);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
}
private void addMembers(IIndex index, THGraphNode graphNode, IBinding binding) throws DOMException, CoreException {
if (graphNode.getMembers(false) == null) {
if (binding instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) binding;
ArrayList memberList= new ArrayList();
IBinding[] members= ct.getDeclaredFields();
addMemberElements(index, members, memberList);
members= ct.getDeclaredMethods();
addMemberElements(index, members, memberList);
graphNode.setMembers(memberList.toArray());
}
else if (binding instanceof ICompositeType) {
ICompositeType ct= (ICompositeType) binding;
ArrayList memberList= new ArrayList();
IBinding[] members= ct.getFields();
addMemberElements(index, members, memberList);
graphNode.setMembers(memberList.toArray());
}
else if (binding instanceof IEnumeration) {
IEnumeration ct= (IEnumeration) binding;
ArrayList memberList= new ArrayList();
IBinding[] members= ct.getEnumerators();
addMemberElements(index, members, memberList);
graphNode.setMembers(memberList.toArray());
}
}
}
private void addMemberElements(IIndex index, IBinding[] members, ArrayList memberList) throws CoreException, DOMException {
for (int i = 0; i < members.length; i++) {
IBinding binding = members[i];
ICElement[] elems= IndexUI.findRepresentative(index, binding);
if (elems.length > 0) {
memberList.add(elems[0]);
}
}
}
}

View file

@ -21,10 +21,11 @@ import java.util.List;
import org.eclipse.cdt.core.model.ICElement;
class THGraphNode {
private static final Object[] NO_MEMBERS= new Object[0];
private List fOutgoing= Collections.EMPTY_LIST;
private List fIncoming= Collections.EMPTY_LIST;
private ICElement fElement;
private Object[] fMembers;
private Object[] fMembers= NO_MEMBERS;
THGraphNode(ICElement element) {
fElement= element;

View file

@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.ui.typehierarchy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@ -28,22 +27,13 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
public class THHierarchyModel {
class THHierarchyModel {
public class BackgroundJob extends Job {
public BackgroundJob() {
super(Messages.THHierarchyModel_Job_title);
@ -152,10 +142,11 @@ public class THHierarchyModel {
try {
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
addSuperClasses(graph, index, monitor);
graph.defineInputNode(index, fInput);
graph.addSuperClasses(index, monitor);
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
addSubClasses(graph, index, monitor);
graph.addSubClasses(index, monitor);
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
}
@ -173,139 +164,7 @@ public class THHierarchyModel {
return Status.OK_STATUS;
}
private void addSuperClasses(THGraph graph, IIndex index, IProgressMonitor monitor) {
if (fInput == null) {
return;
}
HashSet handled= new HashSet();
ArrayList stack= new ArrayList();
stack.add(fInput);
handled.add(fInput);
while (!stack.isEmpty()) {
if (monitor.isCanceled()) {
return;
}
ICElement elem= (ICElement) stack.remove(stack.size()-1);
THGraphNode graphNode= graph.addNode(elem);
try {
IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) binding;
addMembers(index, graphNode, ct);
ICPPBase[] bases= ct.getBases();
for (int i = 0; i < bases.length; i++) {
if (monitor.isCanceled()) {
return;
}
ICPPBase base= bases[i];
IBinding basecl= base.getBaseClass();
ICElement[] baseElems= IndexUI.findRepresentative(index, basecl);
if (baseElems.length > 0) {
ICElement baseElem= baseElems[0];
THGraphNode baseGraphNode= graph.addNode(baseElem);
addMembers(index, baseGraphNode, basecl);
graph.addEdge(graphNode, baseGraphNode);
if (handled.add(baseElem)) {
stack.add(baseElem);
}
}
}
}
} catch (DOMException e) {
CUIPlugin.getDefault().log(e);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
}
private void addMembers(IIndex index, THGraphNode graphNode, IBinding binding) throws DOMException, CoreException {
if (graphNode.getMembers(false) == null) {
if (binding instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) binding;
ArrayList memberList= new ArrayList();
IBinding[] members= ct.getDeclaredFields();
addMemberElements(index, members, memberList);
members= ct.getDeclaredMethods();
addMemberElements(index, members, memberList);
graphNode.setMembers(memberList.toArray());
}
else if (binding instanceof ICompositeType) {
ICompositeType ct= (ICompositeType) binding;
ArrayList memberList= new ArrayList();
IBinding[] members= ct.getFields();
addMemberElements(index, members, memberList);
graphNode.setMembers(memberList.toArray());
}
else if (binding instanceof IEnumeration) {
IEnumeration ct= (IEnumeration) binding;
ArrayList memberList= new ArrayList();
IBinding[] members= ct.getEnumerators();
addMemberElements(index, members, memberList);
graphNode.setMembers(memberList.toArray());
}
}
}
private void addMemberElements(IIndex index, IBinding[] members, ArrayList memberList) throws CoreException, DOMException {
for (int i = 0; i < members.length; i++) {
IBinding binding = members[i];
ICElement[] elems= IndexUI.findRepresentative(index, binding);
if (elems.length > 0) {
memberList.add(elems[0]);
}
}
}
private void addSubClasses(THGraph graph, IIndex index, IProgressMonitor monitor) {
if (fInput == null) {
return;
}
HashSet handled= new HashSet();
ArrayList stack= new ArrayList();
stack.add(fInput);
handled.add(fInput);
while (!stack.isEmpty()) {
if (monitor.isCanceled()) {
return;
}
ICElement elem= (ICElement) stack.remove(stack.size()-1);
THGraphNode graphNode= graph.addNode(elem);
try {
IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding instanceof ICPPClassType) {
IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES);
for (int i = 0; i < names.length; i++) {
if (monitor.isCanceled()) {
return;
}
IIndexName indexName = names[i];
if (indexName.isBaseSpecifier()) {
IIndexName subClassDef= indexName.getEnclosingDefinition();
if (subClassDef != null) {
IBinding subClass= index.findBinding(subClassDef);
ICElement[] subClassElems= IndexUI.findRepresentative(index, subClass);
if (subClassElems.length > 0) {
ICElement subClassElem= subClassElems[0];
THGraphNode subGraphNode= graph.addNode(subClassElem);
addMembers(index, subGraphNode, subClass);
graph.addEdge(subGraphNode, graphNode);
if (handled.add(subClassElem)) {
stack.add(subClassElem);
}
}
}
}
}
}
} catch (DOMException e) {
CUIPlugin.getDefault().log(e);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
}
protected void computeNodes() {
if (fGraph == null) {
return;
@ -321,7 +180,7 @@ public class THHierarchyModel {
groots= fGraph.getLeaveNodes();
}
else {
THGraphNode node= fGraph.getNode(fInput);
THGraphNode node= fGraph.getInputNode();
if (node != null) {
groots= Collections.singleton(node);
}
@ -386,6 +245,16 @@ public class THHierarchyModel {
fDisplay.asyncExec(new Runnable(){
public void run() {
fGraph= graph;
THGraphNode inputNode= fGraph.getInputNode();
if (inputNode == null) {
fView.setMessage(Messages.THHierarchyModel_errorComputingHierarchy);
}
else {
if (fHierarchySelectionToRestore == fInput) {
fHierarchySelectionToRestore= inputNode.getElement();
}
fInput= inputNode.getElement();
}
computeNodes();
notifyEvent(END_OF_COMPUTATION);
}

View file

@ -185,7 +185,7 @@ public class THViewPart extends ViewPart {
updateActionEnablement();
}
public void setInput(ICElement input) {
void setInput(ICElement input) {
if (input == null) {
setMessage(Messages.THViewPart_instruction);
fHierarchyTreeViewer.setInput(null);
@ -935,7 +935,7 @@ public class THViewPart extends ViewPart {
fHistoryEntries.addAll(Arrays.asList(remaining));
}
public ICElement getInput() {
ICElement getInput() {
Object input= fModel.getInput();
if (input instanceof ICElement) {
return (ICElement) input;

View file

@ -16,6 +16,7 @@ THHistoryDropDownAction_tooltip=Show History List
THViewPart_AutomaticOrientation=Automatic View Orientation
THHistoryListAction_Remove=Remove
THHierarchyModel_Job_title=Open Type Hierarchy
THHierarchyModel_errorComputingHierarchy=The hierarchy could not be computed, see the log for details.
THViewPart_Refresh_tooltip=Refresh
THHistoryListAction_label=Open History...
THViewPart_instruction=To display the type hierarchy, select a type or member and select the 'Open Type Hierarchy' menu option.
@ -33,6 +34,7 @@ THViewPart_SubtypeHierarchy_tooltip=Show the Subtype Hierarchy
THViewPart_SupertypeHierarchy=Supertype Hieararchy
THViewPart_HideFields_tooltip=Hide Fields
THViewPart_HideStatic_tooltip=Hide Static Fields and Methods
THGraph_error_elementNotFound=Cannot find element ''{0}'' in index.
THViewPart_Open=Open
THViewPart_Open_tooltip=Open
THViewPart_ShowFileNames=Show File Names

View file

@ -46,10 +46,11 @@ import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
public class IndexUI {
private static final ICElement[] EMPTY_ELEMENTS = new ICElement[0];
private static final ICElementHandle[] EMPTY_ELEMENTS = new ICElementHandle[0];
public static IIndexBinding elementToBinding(IIndex index, ICElement element) throws CoreException {
IIndexName name= elementToName(index, element);
@ -90,37 +91,37 @@ public class IndexUI {
return null;
}
public static ICElement[] findRepresentative(IIndex index, IBinding binding)
public static ICElementHandle[] findRepresentative(IIndex index, IBinding binding)
throws CoreException, DOMException {
ICElement[] defs = IndexUI.findAllDefinitions(index, binding);
ICElementHandle[] defs = IndexUI.findAllDefinitions(index, binding);
if (defs.length == 0) {
ICElement elem = IndexUI.findAnyDeclaration(index, null, binding);
ICElementHandle elem = IndexUI.findAnyDeclaration(index, null, binding);
if (elem != null) {
defs = new ICElement[] { elem };
defs = new ICElementHandle[] { elem };
}
}
return defs;
}
public static ICElement[] findAllDefinitions(IIndex index, IBinding binding) throws CoreException, DOMException {
public static ICElementHandle[] findAllDefinitions(IIndex index, IBinding binding) throws CoreException, DOMException {
if (binding != null) {
IIndexName[] defs= index.findDefinitions(binding);
ArrayList result= new ArrayList();
for (int i = 0; i < defs.length; i++) {
IIndexName in = defs[i];
ICElement definition= getCElementForName(null, index, in);
ICElementHandle definition= getCElementForName(null, index, in);
if (definition != null) {
result.add(definition);
}
}
return (ICElement[]) result.toArray(new ICElement[result.size()]);
return (ICElementHandle[]) result.toArray(new ICElementHandle[result.size()]);
}
return EMPTY_ELEMENTS;
}
public static ICElement getCElementForName(ICProject preferProject, IIndex index, IASTName declName) throws CoreException, DOMException {
public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IASTName declName) throws CoreException, DOMException {
assert !declName.isReference();
IBinding binding= declName.resolveBinding();
if (binding != null) {
@ -150,7 +151,7 @@ public class IndexUI {
}
}
public static ICElement getCElementForName(ICProject preferProject, IIndex index, IIndexName declName) throws CoreException, DOMException {
public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IIndexName declName) throws CoreException, DOMException {
assert !declName.isReference();
ITranslationUnit tu= getTranslationUnit(preferProject, declName);
if (tu != null) {
@ -161,11 +162,11 @@ public class IndexUI {
return null;
}
public static ICElement findAnyDeclaration(IIndex index, ICProject preferProject, IBinding binding) throws CoreException, DOMException {
public static ICElementHandle findAnyDeclaration(IIndex index, ICProject preferProject, IBinding binding) throws CoreException, DOMException {
if (binding != null) {
IIndexName[] names= index.findNames(binding, IIndex.FIND_DECLARATIONS);
for (int i = 0; i < names.length; i++) {
ICElement elem= getCElementForName(preferProject, index, names[i]);
ICElementHandle elem= getCElementForName(preferProject, index, names[i]);
if (elem != null) {
return elem;
}