KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > util > StatementAnalyzer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.corext.refactoring.util;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.core.runtime.CoreException;
19
20 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
21 import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
22
23 import org.eclipse.jdt.core.ICompilationUnit;
24 import org.eclipse.jdt.core.ISourceRange;
25 import org.eclipse.jdt.core.JavaModelException;
26 import org.eclipse.jdt.core.dom.ASTNode;
27 import org.eclipse.jdt.core.dom.CatchClause;
28 import org.eclipse.jdt.core.dom.CompilationUnit;
29 import org.eclipse.jdt.core.dom.DoStatement;
30 import org.eclipse.jdt.core.dom.ForStatement;
31 import org.eclipse.jdt.core.dom.SwitchCase;
32 import org.eclipse.jdt.core.dom.SwitchStatement;
33 import org.eclipse.jdt.core.dom.SynchronizedStatement;
34 import org.eclipse.jdt.core.dom.TryStatement;
35 import org.eclipse.jdt.core.dom.WhileStatement;
36
37 import org.eclipse.jdt.internal.corext.SourceRange;
38 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
39 import org.eclipse.jdt.internal.corext.dom.Selection;
40 import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer;
41 import org.eclipse.jdt.internal.corext.dom.TokenScanner;
42 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
43 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
44
45 /**
46  * Analyzer to check if a selection covers a valid set of statements of an abstract syntax
47  * tree. The selection is valid iff
48  * <ul>
49  * <li>it does not start or end in the middle of a comment.</li>
50  * <li>no extract characters except the empty statement ";" is included in the selection.</li>
51  * </ul>
52  */

53 public class StatementAnalyzer extends SelectionAnalyzer {
54
55     protected ICompilationUnit fCUnit;
56     private TokenScanner fScanner;
57     private RefactoringStatus fStatus;
58
59     public StatementAnalyzer(ICompilationUnit cunit, Selection selection, boolean traverseSelectedNode) throws JavaModelException {
60         super(selection, traverseSelectedNode);
61         Assert.isNotNull(cunit);
62         fCUnit= cunit;
63         fStatus= new RefactoringStatus();
64         fScanner= new TokenScanner(fCUnit);
65     }
66     
67     protected void checkSelectedNodes() {
68         ASTNode[] nodes= getSelectedNodes();
69         if (nodes.length == 0)
70             return;
71         
72         ASTNode node= nodes[0];
73         int selectionOffset= getSelection().getOffset();
74         try {
75             int pos= fScanner.getNextStartOffset(selectionOffset, true);
76             if (pos == node.getStartPosition()) {
77                 int lastNodeEnd= ASTNodes.getExclusiveEnd(nodes[nodes.length - 1]);
78                 
79                 pos= fScanner.getNextStartOffset(lastNodeEnd, true);
80                 int selectionEnd= getSelection().getInclusiveEnd();
81                 if (pos <= selectionEnd) {
82                     ISourceRange range= new SourceRange(lastNodeEnd, pos - lastNodeEnd);
83                     invalidSelection(RefactoringCoreMessages.StatementAnalyzer_end_of_selection, JavaStatusContext.create(fCUnit, range));
84                 }
85                 return; // success
86
}
87         } catch (CoreException e) {
88             // fall through
89
}
90         ISourceRange range= new SourceRange(selectionOffset, node.getStartPosition() - selectionOffset + 1);
91         invalidSelection(RefactoringCoreMessages.StatementAnalyzer_beginning_of_selection, JavaStatusContext.create(fCUnit, range));
92     }
93     
94     public RefactoringStatus getStatus() {
95         return fStatus;
96     }
97     
98     protected ICompilationUnit getCompilationUnit() {
99         return fCUnit;
100     }
101     
102     protected TokenScanner getTokenScanner() {
103         return fScanner;
104     }
105     
106     /* (non-Javadoc)
107      * Method declared in ASTVisitor
108      */

109     public void endVisit(CompilationUnit node) {
110         if (!hasSelectedNodes()) {
111             super.endVisit(node);
112             return;
113         }
114         ASTNode selectedNode= getFirstSelectedNode();
115         Selection selection= getSelection();
116         if (node != selectedNode) {
117             ASTNode parent= selectedNode.getParent();
118             fStatus.merge(CommentAnalyzer.perform(selection, fScanner.getScanner(), parent.getStartPosition(), parent.getLength()));
119         }
120         if (!fStatus.hasFatalError())
121             checkSelectedNodes();
122         super.endVisit(node);
123     }
124     
125     /* (non-Javadoc)
126      * Method declared in ASTVisitor
127      */

128     public void endVisit(DoStatement node) {
129         ASTNode[] selectedNodes= getSelectedNodes();
130         if (doAfterValidation(node, selectedNodes)) {
131             if (contains(selectedNodes, node.getBody()) && contains(selectedNodes, node.getExpression())) {
132                 invalidSelection(RefactoringCoreMessages.StatementAnalyzer_do_body_expression);
133             }
134         }
135         super.endVisit(node);
136     }
137     
138     /* (non-Javadoc)
139      * Method declared in ASTVisitor
140      */

141     public void endVisit(ForStatement node) {
142         ASTNode[] selectedNodes= getSelectedNodes();
143         if (doAfterValidation(node, selectedNodes)) {
144             boolean containsExpression= contains(selectedNodes, node.getExpression());
145             boolean containsUpdaters= contains(selectedNodes, node.updaters());
146             if (contains(selectedNodes, node.initializers()) && containsExpression) {
147                 invalidSelection(RefactoringCoreMessages.StatementAnalyzer_for_initializer_expression);
148             } else if (containsExpression && containsUpdaters) {
149                 invalidSelection(RefactoringCoreMessages.StatementAnalyzer_for_expression_updater);
150             } else if (containsUpdaters && contains(selectedNodes, node.getBody())) {
151                 invalidSelection(RefactoringCoreMessages.StatementAnalyzer_for_updater_body);
152             }
153         }
154         super.endVisit(node);
155     }
156
157     /* (non-Javadoc)
158      * Method declared in ASTVisitor
159      */

160     public void endVisit(SwitchStatement node) {
161         ASTNode[] selectedNodes= getSelectedNodes();
162         if (doAfterValidation(node, selectedNodes)) {
163             List JavaDoc cases= getSwitchCases(node);
164             for (int i= 0; i < selectedNodes.length; i++) {
165                 ASTNode topNode= selectedNodes[i];
166                 if (cases.contains(topNode)) {
167                     invalidSelection(RefactoringCoreMessages.StatementAnalyzer_switch_statement);
168                     break;
169                 }
170             }
171         }
172         super.endVisit(node);
173     }
174
175     /* (non-Javadoc)
176      * Method declared in ASTVisitor
177      */

178     public void endVisit(SynchronizedStatement node) {
179         ASTNode firstSelectedNode= getFirstSelectedNode();
180         if (getSelection().getEndVisitSelectionMode(node) == Selection.SELECTED) {
181             if (firstSelectedNode == node.getBody()) {
182                 invalidSelection(RefactoringCoreMessages.StatementAnalyzer_synchronized_statement);
183             }
184         }
185         super.endVisit(node);
186     }
187
188     /* (non-Javadoc)
189      * Method declared in ASTVisitor
190      */

191     public void endVisit(TryStatement node) {
192         ASTNode firstSelectedNode= getFirstSelectedNode();
193         if (getSelection().getEndVisitSelectionMode(node) == Selection.AFTER) {
194             if (firstSelectedNode == node.getBody() || firstSelectedNode == node.getFinally()) {
195                 invalidSelection(RefactoringCoreMessages.StatementAnalyzer_try_statement);
196             } else {
197                 List JavaDoc catchClauses= node.catchClauses();
198                 for (Iterator JavaDoc iterator= catchClauses.iterator(); iterator.hasNext();) {
199                     CatchClause element= (CatchClause)iterator.next();
200                     if (element == firstSelectedNode || element.getBody() == firstSelectedNode) {
201                         invalidSelection(RefactoringCoreMessages.StatementAnalyzer_try_statement);
202                     } else if (element.getException() == firstSelectedNode) {
203                         invalidSelection(RefactoringCoreMessages.StatementAnalyzer_catch_argument);
204                     }
205                 }
206             }
207         }
208         super.endVisit(node);
209     }
210     
211     /* (non-Javadoc)
212      * Method declared in ASTVisitor
213      */

214     public void endVisit(WhileStatement node) {
215         ASTNode[] selectedNodes= getSelectedNodes();
216         if (doAfterValidation(node, selectedNodes)) {
217             if (contains(selectedNodes, node.getExpression()) && contains(selectedNodes, node.getBody())) {
218                 invalidSelection(RefactoringCoreMessages.StatementAnalyzer_while_expression_body);
219             }
220         }
221         super.endVisit(node);
222     }
223     
224     private boolean doAfterValidation(ASTNode node, ASTNode[] selectedNodes) {
225         return selectedNodes.length > 0 && node == selectedNodes[0].getParent() && getSelection().getEndVisitSelectionMode(node) == Selection.AFTER;
226     }
227     
228     protected void invalidSelection(String JavaDoc message) {
229         fStatus.addFatalError(message);
230         reset();
231     }
232     
233     protected void invalidSelection(String JavaDoc message, RefactoringStatusContext context) {
234         fStatus.addFatalError(message, context);
235         reset();
236     }
237     
238     private static List JavaDoc getSwitchCases(SwitchStatement node) {
239         List JavaDoc result= new ArrayList JavaDoc();
240         for (Iterator JavaDoc iter= node.statements().iterator(); iter.hasNext(); ) {
241             Object JavaDoc element= iter.next();
242             if (element instanceof SwitchCase)
243                 result.add(element);
244         }
245         return result;
246     }
247     
248     protected static boolean contains(ASTNode[] nodes, ASTNode node) {
249         for (int i = 0; i < nodes.length; i++) {
250             if (nodes[i] == node)
251                 return true;
252         }
253         return false;
254     }
255     
256     protected static boolean contains(ASTNode[] nodes, List JavaDoc list) {
257         for (int i = 0; i < nodes.length; i++) {
258             if (list.contains(nodes[i]))
259                 return true;
260         }
261         return false;
262     }
263 }
264
Popular Tags