1
/*******************************************************************************
2
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* Markus Schorn - initial API and implementation
10
*******************************************************************************/
12
package org.eclipse.cdt.internal.ui.typehierarchy;
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.IStatus;
17
import org.eclipse.core.runtime.Status;
18
import org.eclipse.core.runtime.jobs.Job;
19
import org.eclipse.jface.text.IRegion;
20
import org.eclipse.jface.text.ITextSelection;
21
import org.eclipse.jface.text.Region;
22
import org.eclipse.swt.widgets.Display;
23
import org.eclipse.ui.IEditorInput;
24
import org.eclipse.ui.IWorkbenchPage;
25
import org.eclipse.ui.IWorkbenchWindow;
26
import org.eclipse.ui.texteditor.ITextEditor;
28
import org.eclipse.cdt.core.CCorePlugin;
29
import org.eclipse.cdt.core.dom.ast.DOMException;
30
import org.eclipse.cdt.core.dom.ast.IASTName;
31
import org.eclipse.cdt.core.dom.ast.IBinding;
32
import org.eclipse.cdt.core.dom.ast.ICompositeType;
33
import org.eclipse.cdt.core.dom.ast.IEnumeration;
34
import org.eclipse.cdt.core.dom.ast.IEnumerator;
35
import org.eclipse.cdt.core.dom.ast.IField;
36
import org.eclipse.cdt.core.dom.ast.IType;
37
import org.eclipse.cdt.core.dom.ast.ITypedef;
38
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
39
import org.eclipse.cdt.core.index.IIndex;
40
import org.eclipse.cdt.core.index.IIndexManager;
41
import org.eclipse.cdt.core.index.IIndexName;
42
import org.eclipse.cdt.core.model.CModelException;
43
import org.eclipse.cdt.core.model.ICElement;
44
import org.eclipse.cdt.core.model.ICProject;
45
import org.eclipse.cdt.core.model.IFunctionDeclaration;
46
import org.eclipse.cdt.ui.CUIPlugin;
48
import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
49
import org.eclipse.cdt.internal.ui.util.StatusLineHandler;
50
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
52
public class TypeHierarchyUI {
53
public static THViewPart open(ICElement input, IWorkbenchWindow window) {
54
if (!isValidInput(input)) {
57
ICElement memberInput= null;
58
if (!isValidTypeInput(input)) {
60
input= memberInput.getParent();
61
if (!isValidTypeInput(input)) {
62
ICElement[] inputs= findInput(memberInput);
65
memberInput= inputs[1];
70
if (isValidTypeInput(input)) {
71
return openInViewPart(window, input, memberInput);
76
private static THViewPart openInViewPart(IWorkbenchWindow window, ICElement input, ICElement member) {
77
IWorkbenchPage page= window.getActivePage();
79
THViewPart result= (THViewPart)page.showView(CUIPlugin.ID_TYPE_HIERARCHY);
80
result.setInput(input, member);
82
} catch (CoreException e) {
83
ExceptionHandler.handle(e, window.getShell(), Messages.TypeHierarchyUI_OpenTypeHierarchy, null);
88
public static ICElement[] getInput(final ITextEditor editor, IRegion region) {
90
final IEditorInput editorInput = editor.getEditorInput();
91
ICElement inputCElement = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editorInput);
92
if (inputCElement != null) {
93
final ICProject project= inputCElement.getCProject();
95
return findInput(project, editorInput, region);
96
} catch (CoreException e) {
104
public static void open(final ITextEditor editor, final ITextSelection sel) {
105
if (editor != null) {
106
ICElement inputCElement = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
107
if (inputCElement != null) {
108
final ICProject project= inputCElement.getCProject();
109
final IEditorInput editorInput = editor.getEditorInput();
110
final Display display= Display.getCurrent();
112
Job job= new Job(Messages.TypeHierarchyUI_OpenTypeHierarchy) {
114
protected IStatus run(IProgressMonitor monitor) {
116
StatusLineHandler.clearStatusLine(editor.getSite());
117
IRegion reg= new Region(sel.getOffset(), sel.getLength());
118
final ICElement[] elems= findInput(project, editorInput, reg);
119
if (elems != null && elems.length == 2) {
120
display.asyncExec(new Runnable() {
122
openInViewPart(editor.getSite().getWorkbenchWindow(), elems[0], elems[1]);
125
StatusLineHandler.showStatusLineMessage(editor.getSite(),
126
Messages.TypeHierarchyUI_OpenFailure_message);
128
return Status.OK_STATUS;
130
catch (CoreException e) {
131
return e.getStatus();
141
private static ICElement[] findInput(ICProject project, IEditorInput editorInput, IRegion sel) throws CoreException {
143
IIndex index= CCorePlugin.getIndexManager().getIndex(project, IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
145
index.acquireReadLock();
147
IASTName name= IndexUI.getSelectedName(editorInput, sel);
149
IBinding binding= name.resolveBinding();
150
if (!isValidInput(binding)) {
153
ICElement member= null;
154
if (!isValidTypeInput(binding)) {
155
member= findDeclaration(project, index, name, binding);
157
binding= findTypeBinding(binding);
159
if (isValidTypeInput(binding)) {
160
ICElement input= findDefinition(project, index, name, binding);
162
return new ICElement[] {input, member};
168
index.releaseReadLock();
171
catch (CoreException e) {
174
catch (InterruptedException e) {
179
private static ICElement[] findInput(ICElement member) {
180
ICProject project= member.getCProject();
182
IIndex index= CCorePlugin.getIndexManager().getIndex(project, IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
183
index.acquireReadLock();
185
IIndexName name= IndexUI.elementToName(index, member);
187
member= IndexUI.getCElementForName(project, index, name);
188
IBinding binding= index.findBinding(name);
189
binding= findTypeBinding(binding);
190
if (isValidTypeInput(binding)) {
191
ICElement input= findDefinition(project, index, null, binding);
193
return new ICElement[] {input, member};
199
index.releaseReadLock();
202
catch (CoreException e) {
205
catch (InterruptedException e) {
210
private static IBinding findTypeBinding(IBinding memberBinding) {
212
if (memberBinding instanceof IEnumerator) {
213
IType type= ((IEnumerator) memberBinding).getType();
214
if (type instanceof IBinding) {
215
return (IBinding) type;
218
else if (memberBinding instanceof ICPPMember) {
219
return ((ICPPMember) memberBinding).getClassOwner();
221
else if (memberBinding instanceof IField) {
222
return ((IField) memberBinding).getCompositeTypeOwner();
224
} catch (DOMException e) {
225
// don't log problem bindings
230
private static ICElement findDefinition(ICProject project, IIndex index, IASTName name, IBinding binding)
231
throws CoreException {
232
if (name != null && name.isDefinition()) {
233
return IndexUI.getCElementForName(project, index, name);
236
ICElement[] elems= IndexUI.findAllDefinitions(index, binding);
237
if (elems.length > 0) {
240
return IndexUI.findAnyDeclaration(index, project, binding);
243
private static ICElement findDeclaration(ICProject project, IIndex index, IASTName name, IBinding binding)
244
throws CoreException {
245
if (name != null && name.isDefinition()) {
246
return IndexUI.getCElementForName(project, index, name);
249
ICElement[] elems= IndexUI.findAllDefinitions(index, binding);
250
if (elems.length > 0) {
253
return IndexUI.findAnyDeclaration(index, project, binding);
256
public static boolean isValidInput(IBinding binding) {
257
if (isValidTypeInput(binding)
258
|| binding instanceof ICPPMember
259
|| binding instanceof IEnumerator
260
|| binding instanceof IField) {
266
public static boolean isValidTypeInput(IBinding binding) {
267
if (binding instanceof ICompositeType
268
|| binding instanceof IEnumeration
269
|| binding instanceof ITypedef) {
275
public static boolean isValidInput(ICElement elem) {
279
if (isValidTypeInput(elem)) {
282
switch (elem.getElementType()) {
283
case ICElement.C_FIELD:
284
case ICElement.C_METHOD:
285
case ICElement.C_METHOD_DECLARATION:
286
case ICElement.C_TEMPLATE_METHOD:
287
case ICElement.C_TEMPLATE_METHOD_DECLARATION:
288
case ICElement.C_ENUMERATOR:
294
public static boolean isValidTypeInput(ICElement elem) {
298
switch (elem.getElementType()) {
299
case ICElement.C_CLASS:
300
case ICElement.C_STRUCT:
301
case ICElement.C_UNION:
302
case ICElement.C_CLASS_DECLARATION:
303
case ICElement.C_STRUCT_DECLARATION:
304
case ICElement.C_UNION_DECLARATION:
305
case ICElement.C_ENUMERATION:
306
case ICElement.C_TYPEDEF:
307
// case ICElement.C_TEMPLATE_CLASS:
308
// case ICElement.C_TEMPLATE_CLASS_DECLARATION:
309
// case ICElement.C_TEMPLATE_STRUCT:
310
// case ICElement.C_TEMPLATE_STRUCT_DECLARATION:
311
// case ICElement.C_TEMPLATE_UNION:
312
// case ICElement.C_TEMPLATE_UNION_DECLARATION:
318
static String getLocalElementSignature(ICElement element) {
319
if (element != null) {
321
switch (element.getElementType()) {
322
case ICElement.C_METHOD:
323
case ICElement.C_METHOD_DECLARATION:
324
return ((IFunctionDeclaration) element).getSignature();
325
case ICElement.C_FIELD:
326
return element.getElementName();
328
} catch (CModelException e) {