Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 288464 | Differences between
and this patch

Collapse All | Expand All

(-)ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkImplementationDetector.java (-1 / +1 lines)
Lines 40-46 Link Here
40
	 */
40
	 */
41
	protected IHyperlink createHyperlink(IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, ITextEditor editor) {
41
	protected IHyperlink createHyperlink(IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, ITextEditor editor) {
42
		if (element.getElementType() == IJavaElement.METHOD && canBeOverridden((IMethod)element)) {
42
		if (element.getElementType() == IJavaElement.METHOD && canBeOverridden((IMethod)element)) {
43
			return new JavaElementImplementationHyperlink(wordRegion, openAction, element, qualify, editor);
43
			return new JavaElementImplementationHyperlink(wordRegion, openAction, (IMethod)element, qualify, editor);
44
		}
44
		}
45
		return null;
45
		return null;
46
	}
46
	}
(-)ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementImplementationHyperlink.java (-22 / +69 lines)
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

Return to bug 288464