|
Lines 39-45
Link Here
|
| 39 |
import org.eclipse.jdt.core.IJavaElement; |
39 |
import org.eclipse.jdt.core.IJavaElement; |
| 40 |
import org.eclipse.jdt.core.IMethod; |
40 |
import org.eclipse.jdt.core.IMethod; |
| 41 |
import org.eclipse.jdt.core.IType; |
41 |
import org.eclipse.jdt.core.IType; |
|
|
42 |
import org.eclipse.jdt.core.ITypeHierarchy; |
| 42 |
import org.eclipse.jdt.core.ITypeRoot; |
43 |
import org.eclipse.jdt.core.ITypeRoot; |
|
|
44 |
import org.eclipse.jdt.core.JavaModelException; |
| 43 |
import org.eclipse.jdt.core.dom.ASTNode; |
45 |
import org.eclipse.jdt.core.dom.ASTNode; |
| 44 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
46 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
| 45 |
import org.eclipse.jdt.core.dom.Expression; |
47 |
import org.eclipse.jdt.core.dom.Expression; |
|
Lines 50-55
Link Here
|
| 50 |
import org.eclipse.jdt.core.dom.SimpleName; |
52 |
import org.eclipse.jdt.core.dom.SimpleName; |
| 51 |
import org.eclipse.jdt.core.dom.SuperMethodInvocation; |
53 |
import org.eclipse.jdt.core.dom.SuperMethodInvocation; |
| 52 |
import org.eclipse.jdt.core.search.IJavaSearchConstants; |
54 |
import org.eclipse.jdt.core.search.IJavaSearchConstants; |
|
|
55 |
import org.eclipse.jdt.core.search.IJavaSearchScope; |
| 53 |
import org.eclipse.jdt.core.search.SearchEngine; |
56 |
import org.eclipse.jdt.core.search.SearchEngine; |
| 54 |
import org.eclipse.jdt.core.search.SearchMatch; |
57 |
import org.eclipse.jdt.core.search.SearchMatch; |
| 55 |
import org.eclipse.jdt.core.search.SearchParticipant; |
58 |
import org.eclipse.jdt.core.search.SearchParticipant; |
|
Lines 59-64
Link Here
|
| 59 |
import org.eclipse.jdt.internal.corext.dom.Bindings; |
62 |
import org.eclipse.jdt.internal.corext.dom.Bindings; |
| 60 |
import org.eclipse.jdt.internal.corext.util.JdtFlags; |
63 |
import org.eclipse.jdt.internal.corext.util.JdtFlags; |
| 61 |
import org.eclipse.jdt.internal.corext.util.Messages; |
64 |
import org.eclipse.jdt.internal.corext.util.Messages; |
|
|
65 |
import org.eclipse.jdt.internal.corext.util.MethodOverrideTester; |
| 62 |
|
66 |
|
| 63 |
import org.eclipse.jdt.ui.JavaElementLabels; |
67 |
import org.eclipse.jdt.ui.JavaElementLabels; |
| 64 |
import org.eclipse.jdt.ui.SharedASTProvider; |
68 |
import org.eclipse.jdt.ui.SharedASTProvider; |
|
Lines 74-82
Link Here
|
| 74 |
*/ |
78 |
*/ |
| 75 |
public class JavaElementImplementationHyperlink implements IHyperlink { |
79 |
public class JavaElementImplementationHyperlink implements IHyperlink { |
| 76 |
|
80 |
|
|
|
81 |
/** |
| 82 |
* Indicates whether the search scope needs to be restricted to sub types in the hierarchy. |
| 83 |
* |
| 84 |
* @since 3.6 |
| 85 |
*/ |
| 86 |
private static boolean fCreateSubtypeHierarchyScope; |
| 77 |
private final IRegion fRegion; |
87 |
private final IRegion fRegion; |
| 78 |
private final SelectionDispatchAction fOpenAction; |
88 |
private final SelectionDispatchAction fOpenAction; |
| 79 |
private final IJavaElement fElement; |
89 |
private final IMethod fMethod; |
| 80 |
private final boolean fQualify; |
90 |
private final boolean fQualify; |
| 81 |
|
91 |
|
| 82 |
/** |
92 |
/** |
|
Lines 89-109
Link Here
|
| 89 |
* |
99 |
* |
| 90 |
* @param region the region of the link |
100 |
* @param region the region of the link |
| 91 |
* @param openAction the action to use to open the java elements |
101 |
* @param openAction the action to use to open the java elements |
| 92 |
* @param element the java element to open |
102 |
* @param method the method to open |
| 93 |
* @param qualify <code>true</code> if the hyperlink text should show a qualified name for |
103 |
* @param qualify <code>true</code> if the hyperlink text should show a qualified name for |
| 94 |
* element. |
104 |
* element. |
| 95 |
* @param editor the active java editor |
105 |
* @param editor the active java editor |
| 96 |
*/ |
106 |
*/ |
| 97 |
public JavaElementImplementationHyperlink(IRegion region, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, ITextEditor editor) { |
107 |
public JavaElementImplementationHyperlink(IRegion region, SelectionDispatchAction openAction, IMethod method, boolean qualify, ITextEditor editor) { |
| 98 |
Assert.isNotNull(openAction); |
108 |
Assert.isNotNull(openAction); |
| 99 |
Assert.isNotNull(region); |
109 |
Assert.isNotNull(region); |
| 100 |
Assert.isNotNull(element); |
110 |
Assert.isNotNull(method); |
| 101 |
|
111 |
|
| 102 |
fRegion= region; |
112 |
fRegion= region; |
| 103 |
fOpenAction= openAction; |
113 |
fOpenAction= openAction; |
| 104 |
fElement= element; |
114 |
fMethod= method; |
| 105 |
fQualify= qualify; |
115 |
fQualify= qualify; |
| 106 |
fEditor= editor; |
116 |
fEditor= editor; |
|
|
117 |
fCreateSubtypeHierarchyScope= true; |
| 107 |
} |
118 |
} |
| 108 |
|
119 |
|
| 109 |
/* |
120 |
/* |
|
Lines 118-125
Link Here
|
| 118 |
*/ |
129 |
*/ |
| 119 |
public String getHyperlinkText() { |
130 |
public String getHyperlinkText() { |
| 120 |
if (fQualify) { |
131 |
if (fQualify) { |
| 121 |
String elementLabel= JavaElementLabels.getElementLabel(fElement, JavaElementLabels.ALL_FULLY_QUALIFIED); |
132 |
String methodLabel= JavaElementLabels.getElementLabel(fMethod, JavaElementLabels.ALL_FULLY_QUALIFIED); |
| 122 |
return Messages.format(JavaEditorMessages.JavaElementImplementationHyperlink_hyperlinkText_qualified, new Object[] { elementLabel }); |
133 |
return Messages.format(JavaEditorMessages.JavaElementImplementationHyperlink_hyperlinkText_qualified, new Object[] { methodLabel }); |
| 123 |
} else { |
134 |
} else { |
| 124 |
return JavaEditorMessages.JavaElementImplementationHyperlink_hyperlinkText; |
135 |
return JavaEditorMessages.JavaElementImplementationHyperlink_hyperlinkText; |
| 125 |
} |
136 |
} |
|
Lines 140-146
Link Here
|
| 140 |
* </p> |
151 |
* </p> |
| 141 |
*/ |
152 |
*/ |
| 142 |
public void open() { |
153 |
public void open() { |
| 143 |
openImplementations(fEditor, fRegion, fElement, fOpenAction); |
154 |
openImplementations(fEditor, fRegion, fMethod, fOpenAction); |
| 144 |
} |
155 |
} |
| 145 |
|
156 |
|
| 146 |
/** |
157 |
/** |
|
Lines 150-162
Link Here
|
| 150 |
* Quick Hierarchy is opened. |
161 |
* Quick Hierarchy is opened. |
| 151 |
* </p> |
162 |
* </p> |
| 152 |
* |
163 |
* |
| 153 |
* @param openAction the action to use to open the java elements |
164 |
* @param openAction the action to use to open the methods |
| 154 |
* @param javaElement the java element |
165 |
* @param method the method |
| 155 |
* @param region the region of the selection |
166 |
* @param region the region of the selection |
| 156 |
* @param editor the active java editor |
167 |
* @param editor the active java editor |
| 157 |
* @since 3.6 |
168 |
* @since 3.6 |
| 158 |
*/ |
169 |
*/ |
| 159 |
public static void openImplementations(IEditorPart editor, IRegion region, final IJavaElement javaElement, SelectionDispatchAction openAction) { |
170 |
public static void openImplementations(IEditorPart editor, IRegion region, final IMethod method, SelectionDispatchAction openAction) { |
| 160 |
ITypeRoot editorInput= EditorUtility.getEditorInputJavaElement(editor, false); |
171 |
ITypeRoot editorInput= EditorUtility.getEditorInputJavaElement(editor, false); |
| 161 |
|
172 |
|
| 162 |
CompilationUnit ast= SharedASTProvider.getAST(editorInput, SharedASTProvider.WAIT_ACTIVE_ONLY, null); |
173 |
CompilationUnit ast= SharedASTProvider.getAST(editorInput, SharedASTProvider.WAIT_ACTIVE_ONLY, null); |
|
Lines 178-191
Link Here
|
| 178 |
} |
189 |
} |
| 179 |
} else if (parent instanceof SuperMethodInvocation) { |
190 |
} else if (parent instanceof SuperMethodInvocation) { |
| 180 |
// Directly go to the super method definition |
191 |
// Directly go to the super method definition |
| 181 |
openAction.run(new StructuredSelection(javaElement)); |
192 |
openAction.run(new StructuredSelection(method)); |
| 182 |
return; |
193 |
return; |
| 183 |
} else if (parent instanceof MethodDeclaration) { |
194 |
} else if (parent instanceof MethodDeclaration) { |
| 184 |
parentTypeBinding= Bindings.getBindingOfParentType(node); |
195 |
parentTypeBinding= Bindings.getBindingOfParentType(node); |
| 185 |
} |
196 |
} |
| 186 |
} |
197 |
} |
| 187 |
final IType type= parentTypeBinding != null ? (IType) parentTypeBinding.getJavaElement() : null; |
198 |
final IType receiverType= parentTypeBinding != null ? (IType)parentTypeBinding.getJavaElement() : null; |
| 188 |
if (type == null) { |
199 |
if (receiverType == null) { |
| 189 |
openQuickHierarchy(editor); |
200 |
openQuickHierarchy(editor); |
| 190 |
return; |
201 |
return; |
| 191 |
} |
202 |
} |
|
Lines 199-211
Link Here
|
| 199 |
monitor= new NullProgressMonitor(); |
210 |
monitor= new NullProgressMonitor(); |
| 200 |
} |
211 |
} |
| 201 |
try { |
212 |
try { |
| 202 |
String methodLabel= JavaElementLabels.getElementLabel(javaElement, JavaElementLabels.DEFAULT_QUALIFIED); |
213 |
String methodLabel= JavaElementLabels.getElementLabel(method, JavaElementLabels.DEFAULT_QUALIFIED); |
| 203 |
monitor.beginTask(Messages.format(JavaEditorMessages.JavaElementImplementationHyperlink_search_method_implementors, methodLabel), 100); |
214 |
monitor.beginTask(Messages.format(JavaEditorMessages.JavaElementImplementationHyperlink_search_method_implementors, methodLabel), 10); |
|
|
215 |
ITypeHierarchy superTypeHierarchy= receiverType.newSupertypeHierarchy(new SubProgressMonitor(monitor, 3)); |
| 216 |
IType type; |
| 217 |
type= findTypeDefiningSearchScope(superTypeHierarchy, method, receiverType, links); |
| 218 |
|
| 204 |
SearchRequestor requestor= new SearchRequestor() { |
219 |
SearchRequestor requestor= new SearchRequestor() { |
| 205 |
public void acceptSearchMatch(SearchMatch match) throws CoreException { |
220 |
public void acceptSearchMatch(SearchMatch match) throws CoreException { |
| 206 |
if (match.getAccuracy() == SearchMatch.A_ACCURATE) { |
221 |
if (match.getAccuracy() == SearchMatch.A_ACCURATE) { |
| 207 |
IJavaElement element= (IJavaElement)match.getElement(); |
222 |
IJavaElement element= (IMethod)match.getElement(); |
| 208 |
if (element instanceof IMethod && !JdtFlags.isAbstract((IMethod)element)) { |
223 |
if (element instanceof IMethod && !JdtFlags.isAbstract((IMethod)element) && !links.contains(element)) { |
| 209 |
links.add(element); |
224 |
links.add(element); |
| 210 |
if (links.size() > 1) { |
225 |
if (links.size() > 1) { |
| 211 |
throw new OperationCanceledException(dummyString); |
226 |
throw new OperationCanceledException(dummyString); |
|
Lines 215-226
Link Here
|
| 215 |
} |
230 |
} |
| 216 |
}; |
231 |
}; |
| 217 |
int limitTo= IJavaSearchConstants.DECLARATIONS | IJavaSearchConstants.IGNORE_DECLARING_TYPE | IJavaSearchConstants.IGNORE_RETURN_TYPE; |
232 |
int limitTo= IJavaSearchConstants.DECLARATIONS | IJavaSearchConstants.IGNORE_DECLARING_TYPE | IJavaSearchConstants.IGNORE_RETURN_TYPE; |
| 218 |
SearchPattern pattern= SearchPattern.createPattern(javaElement, limitTo); |
233 |
SearchPattern pattern= SearchPattern.createPattern(method, limitTo); |
| 219 |
Assert.isNotNull(pattern); |
234 |
Assert.isNotNull(pattern); |
| 220 |
SearchParticipant[] participants= new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }; |
235 |
SearchParticipant[] participants= new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }; |
| 221 |
SearchEngine engine= new SearchEngine(); |
236 |
SearchEngine engine= new SearchEngine(); |
| 222 |
engine.search(pattern, participants, SearchEngine.createHierarchyScope(type), requestor, new SubProgressMonitor(monitor, 100)); |
237 |
IJavaSearchScope hierarchyScope; |
| 223 |
|
238 |
if (fCreateSubtypeHierarchyScope) { |
|
|
239 |
hierarchyScope= SearchEngine.createHierarchyScope(null, type, true, false, null); |
| 240 |
} else { |
| 241 |
hierarchyScope= SearchEngine.createHierarchyScope(type); |
| 242 |
} |
| 243 |
engine.search(pattern, participants, hierarchyScope, requestor, new SubProgressMonitor(monitor, 7)); |
| 224 |
if (monitor.isCanceled()) { |
244 |
if (monitor.isCanceled()) { |
| 225 |
throw new OperationCanceledException(); |
245 |
throw new OperationCanceledException(); |
| 226 |
} |
246 |
} |
|
Lines 237-243
Link Here
|
| 237 |
context.run(true, true, runnable); |
257 |
context.run(true, true, runnable); |
| 238 |
} catch (InvocationTargetException e) { |
258 |
} catch (InvocationTargetException e) { |
| 239 |
IStatus status= new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, |
259 |
IStatus status= new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, |
| 240 |
Messages.format(JavaEditorMessages.JavaElementImplementationHyperlink_error_status_message, javaElement.getElementName()), e.getCause()); |
260 |
Messages.format(JavaEditorMessages.JavaElementImplementationHyperlink_error_status_message, method.getElementName()), e.getCause()); |
| 241 |
JavaPlugin.log(status); |
261 |
JavaPlugin.log(status); |
| 242 |
ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), |
262 |
ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), |
| 243 |
JavaEditorMessages.JavaElementImplementationHyperlink_hyperlinkText, |
263 |
JavaEditorMessages.JavaElementImplementationHyperlink_hyperlinkText, |
|
Lines 256-261
Link Here
|
| 256 |
} |
276 |
} |
| 257 |
|
277 |
|
| 258 |
/** |
278 |
/** |
|
|
279 |
* Finds the type which defines the scope to search for implementors. Returns the receiver type |
| 280 |
* if its a class, else return the declaring type of the method. |
| 281 |
* |
| 282 |
* @param superTypeHierarchy the type hierarchy |
| 283 |
* @param method the method |
| 284 |
* @param receiverType the receiver type |
| 285 |
* @param links the list of implementors |
| 286 |
* @return the receiver type if its a class, else the declaring type of the method. |
| 287 |
* @throws JavaModelException if the java element does not exist or if an exception occurs while |
| 288 |
* accessing its corresponding resource |
| 289 |
* @since 3.6 |
| 290 |
*/ |
| 291 |
private static IType findTypeDefiningSearchScope(ITypeHierarchy superTypeHierarchy, IMethod method, IType receiverType, ArrayList links) throws JavaModelException { |
| 292 |
if (receiverType.isClass()) { |
| 293 |
MethodOverrideTester methodOverrideTester= new MethodOverrideTester(receiverType, superTypeHierarchy); |
| 294 |
IMethod methodInReceiver= methodOverrideTester.findOverriddenMethodInType(receiverType, method); |
| 295 |
if (methodInReceiver == null || JdtFlags.isAbstract(methodInReceiver)) { |
| 296 |
fCreateSubtypeHierarchyScope= false; |
| 297 |
} else { |
| 298 |
links.add(methodInReceiver); |
| 299 |
} |
| 300 |
return receiverType; |
| 301 |
} |
| 302 |
return method.getDeclaringType(); |
| 303 |
} |
| 304 |
|
| 305 |
/** |
| 259 |
* Opens the quick type hierarchy for the given editor. |
306 |
* Opens the quick type hierarchy for the given editor. |
| 260 |
* |
307 |
* |
| 261 |
* @param editor the editor for which to open the quick hierarchy |
308 |
* @param editor the editor for which to open the quick hierarchy |