-
Notifications
You must be signed in to change notification settings - Fork 78
/
OpenCallHierarchyAction.java
155 lines (132 loc) · 5.17 KB
/
OpenCallHierarchyAction.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*******************************************************************************
* Copyright (c) 2000, 2011 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation
* (report 36180: Callers/Callees view)
*******************************************************************************/
package org.eclipse.jdt.internal.ui.callhierarchy;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IInitializer;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy;
import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.actions.ActionMessages;
import org.eclipse.jdt.internal.ui.actions.ActionUtil;
import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
/**
* This action opens a call hierarchy on the selected members.
*/
public class OpenCallHierarchyAction extends SelectionDispatchAction {
private JavaEditor fEditor;
/**
* Creates a new <code>OpenCallHierarchyAction</code>. The action requires
* that the selection provided by the site's selection provider is of type
* <code>org.eclipse.jface.viewers.IStructuredSelection</code>.
*
* @param site the site providing context information for this action
*/
public OpenCallHierarchyAction(IWorkbenchSite site) {
super(site);
setText(CallHierarchyMessages.OpenCallHierarchyAction_label);
setToolTipText(CallHierarchyMessages.OpenCallHierarchyAction_tooltip);
setDescription(CallHierarchyMessages.OpenCallHierarchyAction_description);
PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.CALL_HIERARCHY_OPEN_ACTION);
}
/**
* Note: This constructor is for internal use only. Clients should not call this constructor.
* @param editor internal
*/
public OpenCallHierarchyAction(JavaEditor editor) {
this(editor.getEditorSite());
fEditor= editor;
setEnabled(SelectionConverter.canOperateOn(fEditor));
}
@Override
public void selectionChanged(ITextSelection selection) {
// Do nothing
}
@Override
public void selectionChanged(IStructuredSelection selection) {
setEnabled(CallHierarchy.arePossibleInputElements(selection.toList()));
}
@Override
public void run(ITextSelection selection) {
ITypeRoot input= SelectionConverter.getInput(fEditor);
if (!ActionUtil.isProcessable(getShell(), input))
return;
try {
IJavaElement[] elements= SelectionConverter.codeResolveOrInputForked(fEditor);
if (elements == null)
return;
List<IJavaElement> candidates= new ArrayList<>(elements.length);
for (IJavaElement element : elements) {
if (CallHierarchy.isPossibleInputElement(element)) {
candidates.add(element);
}
}
if (candidates.isEmpty()) {
IJavaElement enclosingMethod= getEnclosingMethod(input, selection);
if (enclosingMethod != null) {
candidates.add(enclosingMethod);
}
}
CallHierarchyUI.openSelectionDialog(candidates.toArray(new IMember[candidates.size()]), getSite().getWorkbenchWindow());
} catch (InvocationTargetException e) {
ExceptionHandler.handle(e, getShell(),
CallHierarchyMessages.OpenCallHierarchyAction_dialog_title,
ActionMessages.SelectionConverter_codeResolve_failed);
} catch (InterruptedException e) {
// cancelled
}
}
private IJavaElement getEnclosingMethod(ITypeRoot input, ITextSelection selection) {
if (input == null) {
return null;
}
try {
IJavaElement enclosingElement= input.getElementAt(selection.getOffset());
if (enclosingElement instanceof IMethod || enclosingElement instanceof IInitializer || enclosingElement instanceof IField) {
// opening on the enclosing type would be too confusing (since the type resolves to the constructors)
return enclosingElement;
}
} catch (JavaModelException e) {
JavaPlugin.log(e);
}
return null;
}
@Override
public void run(IStructuredSelection selection) {
List<?> elements= selection.toList();
if (!CallHierarchy.arePossibleInputElements(elements)) {
elements= Collections.EMPTY_LIST;
}
IMember[] members= elements.toArray(new IMember[elements.size()]);
if (!ActionUtil.areProcessable(getShell(), members))
return;
CallHierarchyUI.openView(members, getSite().getWorkbenchWindow());
}
}