PageRenderTime 42ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.jdt.ui.source_3.7.1.r371_v20110824-0800/org/eclipse/jdt/internal/corext/refactoring/util/StatementAnalyzer.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 277 lines | 211 code | 26 blank | 40 comment | 65 complexity | e4e84e53c10baf0385295310eaa804b3 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2011 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. import java.util.ArrayList;
  13. import java.util.Iterator;
  14. import java.util.List;
  15. import org.eclipse.core.runtime.Assert;
  16. import org.eclipse.core.runtime.CoreException;
  17. import org.eclipse.ltk.core.refactoring.RefactoringStatus;
  18. import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
  19. import org.eclipse.jdt.core.ICompilationUnit;
  20. import org.eclipse.jdt.core.ISourceRange;
  21. import org.eclipse.jdt.core.SourceRange;
  22. import org.eclipse.jdt.core.compiler.IScanner;
  23. import org.eclipse.jdt.core.dom.ASTNode;
  24. import org.eclipse.jdt.core.dom.CatchClause;
  25. import org.eclipse.jdt.core.dom.CompilationUnit;
  26. import org.eclipse.jdt.core.dom.DoStatement;
  27. import org.eclipse.jdt.core.dom.Expression;
  28. import org.eclipse.jdt.core.dom.ForStatement;
  29. import org.eclipse.jdt.core.dom.Statement;
  30. import org.eclipse.jdt.core.dom.SwitchCase;
  31. import org.eclipse.jdt.core.dom.SwitchStatement;
  32. import org.eclipse.jdt.core.dom.SynchronizedStatement;
  33. import org.eclipse.jdt.core.dom.TryStatement;
  34. import org.eclipse.jdt.core.dom.WhileStatement;
  35. import org.eclipse.jdt.internal.corext.dom.ASTNodes;
  36. import org.eclipse.jdt.internal.corext.dom.Selection;
  37. import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer;
  38. import org.eclipse.jdt.internal.corext.dom.TokenScanner;
  39. import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
  40. import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
  41. /**
  42. * Analyzer to check if a selection covers a valid set of statements of an abstract syntax
  43. * tree. The selection is valid iff
  44. * <ul>
  45. * <li>it does not start or end in the middle of a comment.</li>
  46. * <li>no extract characters except the empty statement ";" is included in the selection.</li>
  47. * </ul>
  48. */
  49. public class StatementAnalyzer extends SelectionAnalyzer {
  50. protected ICompilationUnit fCUnit;
  51. private TokenScanner fScanner;
  52. private RefactoringStatus fStatus;
  53. public StatementAnalyzer(ICompilationUnit cunit, Selection selection, boolean traverseSelectedNode) throws CoreException {
  54. super(selection, traverseSelectedNode);
  55. Assert.isNotNull(cunit);
  56. fCUnit= cunit;
  57. fStatus= new RefactoringStatus();
  58. fScanner= new TokenScanner(fCUnit);
  59. }
  60. protected void checkSelectedNodes() {
  61. ASTNode[] nodes= getSelectedNodes();
  62. if (nodes.length == 0)
  63. return;
  64. ASTNode node= nodes[0];
  65. int selectionOffset= getSelection().getOffset();
  66. try {
  67. int start= fScanner.getNextStartOffset(selectionOffset, true);
  68. if (start == node.getStartPosition()) {
  69. int lastNodeEnd= ASTNodes.getExclusiveEnd(nodes[nodes.length - 1]);
  70. int pos= fScanner.getNextStartOffset(lastNodeEnd, true);
  71. int selectionEnd= getSelection().getInclusiveEnd();
  72. if (pos <= selectionEnd) {
  73. IScanner scanner= fScanner.getScanner();
  74. char[] token= scanner.getCurrentTokenSource(); //see https://bugs.eclipse.org/324237
  75. if (start < lastNodeEnd && token.length == 1 && (token[0] == ';' || token[0] == ',')) {
  76. setSelection(Selection.createFromStartEnd(start, lastNodeEnd - 1));
  77. } else {
  78. ISourceRange range= new SourceRange(lastNodeEnd, pos - lastNodeEnd);
  79. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_end_of_selection, JavaStatusContext.create(fCUnit, range));
  80. }
  81. }
  82. return; // success
  83. }
  84. } catch (CoreException e) {
  85. // fall through
  86. }
  87. ISourceRange range= new SourceRange(selectionOffset, node.getStartPosition() - selectionOffset + 1);
  88. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_beginning_of_selection, JavaStatusContext.create(fCUnit, range));
  89. }
  90. public RefactoringStatus getStatus() {
  91. return fStatus;
  92. }
  93. protected ICompilationUnit getCompilationUnit() {
  94. return fCUnit;
  95. }
  96. protected TokenScanner getTokenScanner() {
  97. return fScanner;
  98. }
  99. /* (non-Javadoc)
  100. * Method declared in ASTVisitor
  101. */
  102. @Override
  103. public void endVisit(CompilationUnit node) {
  104. if (!hasSelectedNodes()) {
  105. super.endVisit(node);
  106. return;
  107. }
  108. ASTNode selectedNode= getFirstSelectedNode();
  109. Selection selection= getSelection();
  110. if (node != selectedNode) {
  111. ASTNode parent= selectedNode.getParent();
  112. fStatus.merge(CommentAnalyzer.perform(selection, fScanner.getScanner(), parent.getStartPosition(), parent.getLength()));
  113. }
  114. if (!fStatus.hasFatalError())
  115. checkSelectedNodes();
  116. super.endVisit(node);
  117. }
  118. /* (non-Javadoc)
  119. * Method declared in ASTVisitor
  120. */
  121. @Override
  122. public void endVisit(DoStatement node) {
  123. ASTNode[] selectedNodes= getSelectedNodes();
  124. if (doAfterValidation(node, selectedNodes)) {
  125. if (contains(selectedNodes, node.getBody()) && contains(selectedNodes, node.getExpression())) {
  126. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_do_body_expression);
  127. }
  128. }
  129. super.endVisit(node);
  130. }
  131. /* (non-Javadoc)
  132. * Method declared in ASTVisitor
  133. */
  134. @Override
  135. public void endVisit(ForStatement node) {
  136. ASTNode[] selectedNodes= getSelectedNodes();
  137. if (doAfterValidation(node, selectedNodes)) {
  138. boolean containsExpression= contains(selectedNodes, node.getExpression());
  139. boolean containsUpdaters= contains(selectedNodes, node.updaters());
  140. if (contains(selectedNodes, node.initializers()) && containsExpression) {
  141. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_for_initializer_expression);
  142. } else if (containsExpression && containsUpdaters) {
  143. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_for_expression_updater);
  144. } else if (containsUpdaters && contains(selectedNodes, node.getBody())) {
  145. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_for_updater_body);
  146. }
  147. }
  148. super.endVisit(node);
  149. }
  150. /* (non-Javadoc)
  151. * Method declared in ASTVisitor
  152. */
  153. @Override
  154. public void endVisit(SwitchStatement node) {
  155. ASTNode[] selectedNodes= getSelectedNodes();
  156. if (doAfterValidation(node, selectedNodes)) {
  157. List<SwitchCase> cases= getSwitchCases(node);
  158. for (int i= 0; i < selectedNodes.length; i++) {
  159. ASTNode topNode= selectedNodes[i];
  160. if (cases.contains(topNode)) {
  161. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_switch_statement);
  162. break;
  163. }
  164. }
  165. }
  166. super.endVisit(node);
  167. }
  168. /* (non-Javadoc)
  169. * Method declared in ASTVisitor
  170. */
  171. @Override
  172. public void endVisit(SynchronizedStatement node) {
  173. ASTNode firstSelectedNode= getFirstSelectedNode();
  174. if (getSelection().getEndVisitSelectionMode(node) == Selection.SELECTED) {
  175. if (firstSelectedNode == node.getBody()) {
  176. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_synchronized_statement);
  177. }
  178. }
  179. super.endVisit(node);
  180. }
  181. /* (non-Javadoc)
  182. * Method declared in ASTVisitor
  183. */
  184. @Override
  185. public void endVisit(TryStatement node) {
  186. ASTNode firstSelectedNode= getFirstSelectedNode();
  187. if (getSelection().getEndVisitSelectionMode(node) == Selection.AFTER) {
  188. if (firstSelectedNode == node.getBody() || firstSelectedNode == node.getFinally()) {
  189. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_try_statement);
  190. } else {
  191. List<CatchClause> catchClauses= node.catchClauses();
  192. for (Iterator<CatchClause> iterator= catchClauses.iterator(); iterator.hasNext();) {
  193. CatchClause element= iterator.next();
  194. if (element == firstSelectedNode || element.getBody() == firstSelectedNode) {
  195. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_try_statement);
  196. } else if (element.getException() == firstSelectedNode) {
  197. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_catch_argument);
  198. }
  199. }
  200. }
  201. }
  202. super.endVisit(node);
  203. }
  204. /* (non-Javadoc)
  205. * Method declared in ASTVisitor
  206. */
  207. @Override
  208. public void endVisit(WhileStatement node) {
  209. ASTNode[] selectedNodes= getSelectedNodes();
  210. if (doAfterValidation(node, selectedNodes)) {
  211. if (contains(selectedNodes, node.getExpression()) && contains(selectedNodes, node.getBody())) {
  212. invalidSelection(RefactoringCoreMessages.StatementAnalyzer_while_expression_body);
  213. }
  214. }
  215. super.endVisit(node);
  216. }
  217. private boolean doAfterValidation(ASTNode node, ASTNode[] selectedNodes) {
  218. return selectedNodes.length > 0 && node == selectedNodes[0].getParent() && getSelection().getEndVisitSelectionMode(node) == Selection.AFTER;
  219. }
  220. protected void invalidSelection(String message) {
  221. fStatus.addFatalError(message);
  222. reset();
  223. }
  224. protected void invalidSelection(String message, RefactoringStatusContext context) {
  225. fStatus.addFatalError(message, context);
  226. reset();
  227. }
  228. private static List<SwitchCase> getSwitchCases(SwitchStatement node) {
  229. List<SwitchCase> result= new ArrayList<SwitchCase>();
  230. for (Iterator<Statement> iter= node.statements().iterator(); iter.hasNext(); ) {
  231. Object element= iter.next();
  232. if (element instanceof SwitchCase)
  233. result.add((SwitchCase) element);
  234. }
  235. return result;
  236. }
  237. protected static boolean contains(ASTNode[] nodes, ASTNode node) {
  238. for (int i = 0; i < nodes.length; i++) {
  239. if (nodes[i] == node)
  240. return true;
  241. }
  242. return false;
  243. }
  244. protected static boolean contains(ASTNode[] nodes, List<Expression> list) {
  245. for (int i = 0; i < nodes.length; i++) {
  246. if (list.contains(nodes[i]))
  247. return true;
  248. }
  249. return false;
  250. }
  251. }