]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 2010 IBM Corporation 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 | |
7 | * | |
8 | * Contributors: | |
9 | * IBM Corporation - initial API and implementation | |
10 | *******************************************************************************/ | |
11 | package org.eclipse.jdt.internal.ui.javaeditor; | |
12 | ||
13 | import org.eclipse.core.runtime.CoreException; | |
14 | ||
15 | import org.eclipse.jface.text.IDocument; | |
16 | import org.eclipse.jface.text.TextSelection; | |
17 | ||
18 | import org.eclipse.jdt.core.IJavaElement; | |
19 | import org.eclipse.jdt.core.ITypeRoot; | |
20 | import org.eclipse.jdt.core.JavaModelException; | |
21 | import org.eclipse.jdt.core.dom.ASTNode; | |
22 | import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; | |
23 | import org.eclipse.jdt.core.dom.Annotation; | |
24 | import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; | |
25 | import org.eclipse.jdt.core.dom.BodyDeclaration; | |
26 | import org.eclipse.jdt.core.dom.CompilationUnit; | |
27 | import org.eclipse.jdt.core.dom.SimpleName; | |
28 | import org.eclipse.jdt.core.dom.SingleVariableDeclaration; | |
29 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment; | |
30 | ||
31 | import org.eclipse.jdt.internal.corext.dom.Selection; | |
32 | import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer; | |
33 | import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; | |
34 | ||
35 | import org.eclipse.jdt.ui.SharedASTProvider; | |
36 | import org.eclipse.jdt.ui.actions.FindBreakContinueTargetOccurrencesAction; | |
37 | import org.eclipse.jdt.ui.actions.FindExceptionOccurrencesAction; | |
38 | import org.eclipse.jdt.ui.actions.FindImplementOccurrencesAction; | |
39 | import org.eclipse.jdt.ui.actions.FindMethodExitOccurrencesAction; | |
40 | import org.eclipse.jdt.ui.actions.FindOccurrencesInFileAction; | |
41 | import org.eclipse.jdt.ui.actions.OccurrencesSearchGroup; | |
42 | ||
43 | import org.eclipse.jdt.internal.ui.actions.SelectionConverter; | |
44 | import org.eclipse.jdt.internal.ui.refactoring.actions.RenameJavaElementAction; | |
45 | import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder; | |
46 | import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder; | |
47 | import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder; | |
48 | import org.eclipse.jdt.internal.ui.search.MethodExitsFinder; | |
49 | import org.eclipse.jdt.internal.ui.search.OccurrencesFinder; | |
50 | ||
51 | /** | |
52 | * A special text selection that gives access to the resolved and | |
53 | * enclosing element. | |
54 | */ | |
55 | public class JavaTextSelection extends TextSelection { | |
56 | ||
57 | private ITypeRoot fElement; | |
58 | private IJavaElement[] fResolvedElements; | |
59 | ||
60 | private boolean fEnclosingElementRequested; | |
61 | private IJavaElement fEnclosingElement; | |
62 | ||
63 | private boolean fPartialASTRequested; | |
64 | private CompilationUnit fPartialAST; | |
65 | ||
66 | private boolean fNodesRequested; | |
67 | public ASTNode[] fSelectedNodes; | |
68 | public ASTNode fCoveringNode; | |
69 | ||
70 | private boolean fInMethodBodyRequested; | |
71 | private boolean fInMethodBody; | |
72 | ||
73 | private boolean fInClassInitializerRequested; | |
74 | private boolean fInClassInitializer; | |
75 | ||
76 | private boolean fInVariableInitializerRequested; | |
77 | private boolean fInVariableInitializer; | |
78 | ||
79 | /** | |
80 | * Indicates whether the selection node has been checked to be of type <code>Annotation</code>. | |
81 | * | |
82 | * @since 3.7 | |
83 | */ | |
84 | private boolean fInAnnotationRequested; | |
85 | ||
86 | /** | |
87 | * Indicates whether selection node is of type <code>Annotation</code>. | |
88 | * | |
89 | * @since 3.7 | |
90 | */ | |
91 | private boolean fInAnnotation; | |
92 | ||
93 | /** | |
94 | * Creates a new text selection at the given offset and length. | |
95 | * @param element the root element | |
96 | * @param document the document | |
97 | * @param offset offset of the selection | |
98 | * @param length length of the selection | |
99 | */ | |
100 | public JavaTextSelection(ITypeRoot element, IDocument document, int offset, int length) { | |
101 | super(document, offset, length); | |
102 | fElement= element; | |
103 | } | |
104 | ||
105 | /** | |
106 | * Resolves the <code>IJavaElement</code>s at the current offset. Returns | |
107 | * an empty array if the string under the offset doesn't resolve to a | |
108 | * <code>IJavaElement</code>. | |
109 | * | |
110 | * @return the resolved java elements at the current offset | |
111 | * @throws JavaModelException passed from the underlying code resolve API | |
112 | */ | |
113 | public IJavaElement[] resolveElementAtOffset() throws JavaModelException { | |
114 | if (fResolvedElements != null) | |
115 | return fResolvedElements; | |
116 | // long start= System.currentTimeMillis(); | |
117 | fResolvedElements= SelectionConverter.codeResolve(fElement, this); | |
118 | // System.out.println("Time resolving element: " + (System.currentTimeMillis() - start)); | |
119 | return fResolvedElements; | |
120 | } | |
121 | ||
122 | public IJavaElement resolveEnclosingElement() throws JavaModelException { | |
123 | if (fEnclosingElementRequested) | |
124 | return fEnclosingElement; | |
125 | fEnclosingElementRequested= true; | |
126 | fEnclosingElement= SelectionConverter.resolveEnclosingElement(fElement, this); | |
127 | return fEnclosingElement; | |
128 | } | |
129 | ||
130 | public CompilationUnit resolvePartialAstAtOffset() { | |
131 | if (fPartialASTRequested) | |
132 | return fPartialAST; | |
133 | fPartialASTRequested= true; | |
134 | // long start= System.currentTimeMillis(); | |
135 | fPartialAST= SharedASTProvider.getAST(fElement, SharedASTProvider.WAIT_YES, null); | |
136 | // System.out.println("Time requesting partial AST: " + (System.currentTimeMillis() - start)); | |
137 | return fPartialAST; | |
138 | } | |
139 | ||
140 | public ASTNode[] resolveSelectedNodes() { | |
141 | if (fNodesRequested) | |
142 | return fSelectedNodes; | |
143 | fNodesRequested= true; | |
144 | CompilationUnit root= resolvePartialAstAtOffset(); | |
145 | if (root == null) | |
146 | return null; | |
147 | Selection ds= Selection.createFromStartLength(getOffset(), getLength()); | |
148 | SelectionAnalyzer analyzer= new SelectionAnalyzer(ds, false); | |
149 | return analyzer.generated_5402575718017044544(root, this); | |
150 | } | |
151 | ||
152 | public ASTNode resolveCoveringNode() { | |
153 | if (fNodesRequested) | |
154 | return fCoveringNode; | |
155 | resolveSelectedNodes(); | |
156 | return fCoveringNode; | |
157 | } | |
158 | ||
159 | public boolean resolveInMethodBody() { | |
160 | if (fInMethodBodyRequested) | |
161 | return fInMethodBody; | |
162 | fInMethodBodyRequested= true; | |
163 | resolveSelectedNodes(); | |
164 | ASTNode node= getStartNode(); | |
165 | if (node == null) { | |
166 | fInMethodBody= true; | |
167 | } else { | |
168 | while (node != null) { | |
169 | int nodeType= node.getNodeType(); | |
170 | if (nodeType == ASTNode.BLOCK && node.getParent() instanceof BodyDeclaration) { | |
171 | fInMethodBody= node.getParent().getNodeType() == ASTNode.METHOD_DECLARATION; | |
172 | break; | |
173 | } else if (nodeType == ASTNode.ANONYMOUS_CLASS_DECLARATION) { | |
174 | fInMethodBody= false; | |
175 | break; | |
176 | } | |
177 | node= node.getParent(); | |
178 | } | |
179 | } | |
180 | return fInMethodBody; | |
181 | } | |
182 | ||
183 | public boolean resolveInClassInitializer() { | |
184 | if (fInClassInitializerRequested) | |
185 | return fInClassInitializer; | |
186 | fInClassInitializerRequested= true; | |
187 | resolveSelectedNodes(); | |
188 | ASTNode node= getStartNode(); | |
189 | if (node == null) { | |
190 | fInClassInitializer= true; | |
191 | } else { | |
192 | while (node != null) { | |
193 | int nodeType= node.getNodeType(); | |
194 | if (node instanceof AbstractTypeDeclaration) { | |
195 | fInClassInitializer= false; | |
196 | break; | |
197 | } else if (nodeType == ASTNode.ANONYMOUS_CLASS_DECLARATION) { | |
198 | fInClassInitializer= false; | |
199 | break; | |
200 | } else if (nodeType == ASTNode.INITIALIZER) { | |
201 | fInClassInitializer= true; | |
202 | break; | |
203 | } | |
204 | node= node.getParent(); | |
205 | } | |
206 | } | |
207 | return fInClassInitializer; | |
208 | } | |
209 | ||
210 | public boolean resolveInVariableInitializer() { | |
211 | if (fInVariableInitializerRequested) | |
212 | return fInVariableInitializer; | |
213 | fInVariableInitializerRequested= true; | |
214 | resolveSelectedNodes(); | |
215 | ASTNode node= getStartNode(); | |
216 | ASTNode last= null; | |
217 | while (node != null) { | |
218 | int nodeType= node.getNodeType(); | |
219 | if (node instanceof AbstractTypeDeclaration) { | |
220 | fInVariableInitializer= false; | |
221 | break; | |
222 | } else if (nodeType == ASTNode.ANONYMOUS_CLASS_DECLARATION) { | |
223 | fInVariableInitializer= false; | |
224 | break; | |
225 | } else if (nodeType == ASTNode.VARIABLE_DECLARATION_FRAGMENT && | |
226 | ((VariableDeclarationFragment)node).getInitializer() == last) { | |
227 | fInVariableInitializer= true; | |
228 | break; | |
229 | } else if (nodeType == ASTNode.SINGLE_VARIABLE_DECLARATION && | |
230 | ((SingleVariableDeclaration)node).getInitializer() == last) { | |
231 | fInVariableInitializer= true; | |
232 | break; | |
233 | } else if (nodeType == ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION && | |
234 | ((AnnotationTypeMemberDeclaration)node).getDefault() == last) { | |
235 | fInVariableInitializer= true; | |
236 | break; | |
237 | } | |
238 | last= node; | |
239 | node= node.getParent(); | |
240 | } | |
241 | return fInVariableInitializer; | |
242 | } | |
243 | ||
244 | /** | |
245 | * Resolves the selected nodes and returns <code>true</code> if the node or any of its ancestors | |
246 | * is of type <code>Annotation</code>, <code>false</code> otherwise. | |
247 | * | |
248 | * @return <code>true</code> if the node or any of its ancestors is of type | |
249 | * <code>Annotation</code>, <code>false</code> otherwise | |
250 | * @since 3.7 | |
251 | */ | |
252 | public boolean resolveInAnnotation() { | |
253 | if (fInAnnotationRequested) | |
254 | return fInAnnotation; | |
255 | fInAnnotationRequested= true; | |
256 | resolveSelectedNodes(); | |
257 | ASTNode node= getStartNode(); | |
258 | while (node != null) { | |
259 | if (node instanceof Annotation) { | |
260 | fInAnnotation= true; | |
261 | break; | |
262 | } | |
263 | node= node.getParent(); | |
264 | } | |
265 | return fInAnnotation; | |
266 | } | |
267 | ||
268 | private ASTNode getStartNode() { | |
269 | if (fSelectedNodes != null && fSelectedNodes.length > 0) | |
270 | return fSelectedNodes[0]; | |
271 | else | |
272 | return fCoveringNode; | |
273 | } | |
274 | ||
275 | public void generated_8855172316196997770(FindMethodExitOccurrencesAction findmethodexitoccurrencesaction) { | |
276 | CompilationUnit astRoot= resolvePartialAstAtOffset(); | |
277 | findmethodexitoccurrencesaction.setEnabled(astRoot != null && new MethodExitsFinder().initialize(astRoot, getOffset(), getLength()) == null); | |
278 | } | |
279 | ||
280 | public void generated_3145566121966178754(FindExceptionOccurrencesAction findexceptionoccurrencesaction) { | |
281 | CompilationUnit astRoot= resolvePartialAstAtOffset(); | |
282 | findexceptionoccurrencesaction.setEnabled(astRoot != null && new ExceptionOccurrencesFinder().initialize(astRoot, getOffset(), getLength()) == null); | |
283 | } | |
284 | ||
285 | public void generated_222107235814334127(OccurrencesSearchGroup occurrencessearchgroup) { | |
286 | occurrencessearchgroup.fExceptionOccurrencesAction.update(this); | |
287 | occurrencessearchgroup.fOccurrencesInFileAction.update(this); | |
288 | occurrencessearchgroup.fFindImplementorOccurrencesAction.update(this); | |
289 | occurrencessearchgroup.fBreakContinueTargetOccurrencesAction.update(this); | |
290 | occurrencessearchgroup.fMethodExitOccurrencesAction.update(this); | |
291 | } | |
292 | ||
293 | public void generated_5580689207028800768(FindImplementOccurrencesAction findimplementoccurrencesaction) { | |
294 | CompilationUnit astRoot= resolvePartialAstAtOffset(); | |
295 | findimplementoccurrencesaction.setEnabled(astRoot != null && new ImplementOccurrencesFinder().initialize(astRoot, getOffset(), getLength()) == null); | |
296 | } | |
297 | ||
298 | public void generated_3985285739337536814(FindBreakContinueTargetOccurrencesAction findbreakcontinuetargetoccurrencesaction) { | |
299 | CompilationUnit astRoot= resolvePartialAstAtOffset(); | |
300 | findbreakcontinuetargetoccurrencesaction.setEnabled(astRoot != null && new BreakContinueTargetFinder().initialize(astRoot, getOffset(), getLength()) == null); | |
301 | } | |
302 | ||
303 | public void generated_1787593016729697060(FindOccurrencesInFileAction findoccurrencesinfileaction) { | |
304 | CompilationUnit astRoot= resolvePartialAstAtOffset(); | |
305 | findoccurrencesinfileaction.setEnabled(astRoot != null && new OccurrencesFinder().initialize(astRoot, getOffset(), getLength()) == null); | |
306 | } | |
307 | ||
308 | public void generated_5438255568821321088(RenameJavaElementAction renamejavaelementaction) throws JavaModelException, CoreException { | |
309 | IJavaElement[] elements= resolveElementAtOffset(); | |
310 | if (elements.length == 1) { | |
311 | renamejavaelementaction.setEnabled(RefactoringAvailabilityTester.isRenameElementAvailable(elements[0])); | |
312 | } else { | |
313 | ASTNode node= resolveCoveringNode(); | |
314 | renamejavaelementaction.setEnabled(node instanceof SimpleName); | |
315 | } | |
316 | } | |
317 | } |