PageRenderTime 2312ms CodeModel.GetById 38ms RepoModel.GetById 1ms app.codeStats 0ms

/src/test/org/codehaus/groovy/ast/LineColumnChecker.java

https://github.com/evoturvey/groovy
Java | 459 lines | 354 code | 68 blank | 37 comment | 25 complexity | 13bcc7f58e12f272d4e9ef0ac7a357f4 MD5 | raw file
  1. package org.codehaus.groovy.ast;
  2. import java.util.Collection;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import org.codehaus.groovy.ast.expr.ArgumentListExpression;
  6. import org.codehaus.groovy.ast.expr.ArrayExpression;
  7. import org.codehaus.groovy.ast.expr.AttributeExpression;
  8. import org.codehaus.groovy.ast.expr.BinaryExpression;
  9. import org.codehaus.groovy.ast.expr.BitwiseNegationExpression;
  10. import org.codehaus.groovy.ast.expr.BooleanExpression;
  11. import org.codehaus.groovy.ast.expr.CastExpression;
  12. import org.codehaus.groovy.ast.expr.ClassExpression;
  13. import org.codehaus.groovy.ast.expr.ClosureExpression;
  14. import org.codehaus.groovy.ast.expr.ClosureListExpression;
  15. import org.codehaus.groovy.ast.expr.ConstantExpression;
  16. import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
  17. import org.codehaus.groovy.ast.expr.DeclarationExpression;
  18. import org.codehaus.groovy.ast.expr.ElvisOperatorExpression;
  19. import org.codehaus.groovy.ast.expr.Expression;
  20. import org.codehaus.groovy.ast.expr.FieldExpression;
  21. import org.codehaus.groovy.ast.expr.GStringExpression;
  22. import org.codehaus.groovy.ast.expr.ListExpression;
  23. import org.codehaus.groovy.ast.expr.MapEntryExpression;
  24. import org.codehaus.groovy.ast.expr.MapExpression;
  25. import org.codehaus.groovy.ast.expr.MethodCallExpression;
  26. import org.codehaus.groovy.ast.expr.MethodPointerExpression;
  27. import org.codehaus.groovy.ast.expr.NotExpression;
  28. import org.codehaus.groovy.ast.expr.PostfixExpression;
  29. import org.codehaus.groovy.ast.expr.PrefixExpression;
  30. import org.codehaus.groovy.ast.expr.PropertyExpression;
  31. import org.codehaus.groovy.ast.expr.RangeExpression;
  32. import org.codehaus.groovy.ast.expr.RegexExpression;
  33. import org.codehaus.groovy.ast.expr.SpreadExpression;
  34. import org.codehaus.groovy.ast.expr.SpreadMapExpression;
  35. import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
  36. import org.codehaus.groovy.ast.expr.TernaryExpression;
  37. import org.codehaus.groovy.ast.expr.TupleExpression;
  38. import org.codehaus.groovy.ast.expr.UnaryMinusExpression;
  39. import org.codehaus.groovy.ast.expr.UnaryPlusExpression;
  40. import org.codehaus.groovy.ast.expr.VariableExpression;
  41. import org.codehaus.groovy.ast.stmt.Statement;
  42. import org.codehaus.groovy.control.SourceUnit;
  43. /**
  44. * Tests the LineColumn information of the groovy source obtained in the
  45. * source parameter of the constructor
  46. *
  47. * @author <a href="mailto:martin.kempf@gmail.com">Martin Kempf</a>
  48. *
  49. */
  50. public class LineColumnChecker extends ASTTest {
  51. private LineCheckVisitor visitor;
  52. private String name;
  53. private String source;
  54. private String[] expected;
  55. public LineColumnChecker(String name, String source, String expected) {
  56. this.name = name;
  57. this.source = source;
  58. this.expected = expected.split(";");
  59. // Set Method to call for JUnit
  60. setName("testLineColumn");
  61. }
  62. public void setUp() {
  63. visitor = new LineCheckVisitor();
  64. }
  65. public String getName() {
  66. return name;
  67. }
  68. public void testLineColumn() {
  69. visitor.visitModuleNode(getAST(source));
  70. String was = visitor.getASTString();
  71. //comment out next line to view the output of the visitor
  72. //System.out.println(name + ": " + was);
  73. for (int i = 0; i < expected.length; i++) {
  74. assertTrue("'"+ expected[i] + "' not found in '" + was + "'", was.indexOf(expected[i].trim()) != -1);
  75. }
  76. }
  77. }
  78. /**
  79. *
  80. * Visitor to write for each visited node a string like:
  81. * [<NodeType>,(<line>:<column>),(<lastLine>:<lastColumn>)]
  82. *
  83. */
  84. class LineCheckVisitor extends ClassCodeVisitorSupport {
  85. private StringBuffer astString = new StringBuffer();
  86. public String getASTString() {
  87. return astString.toString();
  88. }
  89. protected void visitStatement(Statement statement) {
  90. visitNode(statement);
  91. }
  92. protected void visitType(ClassNode node) {
  93. visitNode(node);
  94. visitGenerics(node);
  95. }
  96. protected void visitTypes(ClassNode[] classNodes) {
  97. if (classNodes != null) {
  98. for(int i = 0; i < classNodes.length; i++){
  99. visitType(classNodes[i]);
  100. }
  101. }
  102. }
  103. protected void visitGenerics(ClassNode node) {
  104. if (node.isUsingGenerics()) {
  105. GenericsType[] generics = node.getGenericsTypes();
  106. for (int i = 0; i < generics.length; i++) {
  107. GenericsType genericType = generics[i];
  108. visitNode(genericType);
  109. visitType(genericType.getType());
  110. if (genericType.getLowerBound() != null) {
  111. visitType(genericType.getLowerBound());
  112. }
  113. visitTypes(genericType.getUpperBounds());
  114. }
  115. }
  116. }
  117. protected void visitNodes(ASTNode[] nodes) {
  118. if (nodes != null) {
  119. for(int i = 0; i < nodes.length; i++){
  120. visitNode(nodes[i]);
  121. }
  122. }
  123. }
  124. protected void visitNode(ASTNode node) {
  125. String nodeName = node.getClass().getName();
  126. //get classname without package
  127. nodeName = nodeName.substring(nodeName.lastIndexOf(".") + 1,nodeName.length());
  128. astString.append("[");
  129. astString.append(nodeName);
  130. astString.append(",(");
  131. astString.append(node.getLineNumber());
  132. astString.append(":");
  133. astString.append(node.getColumnNumber());
  134. astString.append("),(");
  135. astString.append(node.getLastLineNumber());
  136. astString.append(":");
  137. astString.append(node.getLastColumnNumber());
  138. astString.append(")]");
  139. //String of each node looks like: [AssertStatement,(1:1),(1:20)]
  140. }
  141. public SourceUnit getSourceUnit() {
  142. return null;
  143. }
  144. public void visitModuleNode(ModuleNode moduleNode) {
  145. //visit imports like import java.io.File and import java.io.File as MyFile
  146. Object[] imports = moduleNode.getImports().toArray();
  147. for (int i = 0; i < imports.length; i++) {
  148. visitNode(((ImportNode)imports[i]).getType());
  149. }
  150. //visit static imports like import java.lang.Math.*
  151. Collection staticImportClasses = moduleNode.getStaticImportClasses().values();
  152. for (Iterator staticClassIt = staticImportClasses.iterator(); staticClassIt.hasNext();) {
  153. ClassNode staticClass = (ClassNode)staticClassIt.next();
  154. visitNode(staticClass);
  155. }
  156. //visit static imports like import java.lang.Math.cos
  157. Collection staticImportAliases = moduleNode.getStaticImportAliases().values();
  158. for (Iterator staticAliasesIt = staticImportAliases.iterator(); staticAliasesIt.hasNext();) {
  159. ClassNode staticAlias = (ClassNode)staticAliasesIt.next();
  160. visitNode(staticAlias);
  161. }
  162. List classes = moduleNode.getClasses();
  163. for (Iterator classIt = classes.iterator(); classIt.hasNext();) {
  164. ClassNode classNode = (ClassNode)classIt.next();
  165. if (!classNode.isScript()) {
  166. visitClass(classNode);
  167. } else {
  168. List methods = moduleNode.getMethods();
  169. for (Iterator methodIt = methods.iterator(); methodIt.hasNext();) {
  170. MethodNode method = (MethodNode)methodIt.next();
  171. visitMethod(method);
  172. }
  173. }
  174. }
  175. //visit Statements that are not inside a class
  176. if (!moduleNode.getStatementBlock().isEmpty()) {
  177. visitBlockStatement(moduleNode.getStatementBlock());
  178. }
  179. }
  180. public void visitClass(ClassNode node) {
  181. visitType(node);
  182. visitType(node.getUnresolvedSuperClass());
  183. visitTypes(node.getInterfaces());
  184. super.visitClass(node);
  185. }
  186. public void visitAnnotations(AnnotatedNode node) {
  187. List annotionMap = node.getAnnotations();
  188. if (annotionMap.isEmpty()) return;
  189. visitNode(node);
  190. Iterator it = annotionMap.iterator();
  191. while (it.hasNext()) {
  192. AnnotationNode an = (AnnotationNode) it.next();
  193. visitNode(an);
  194. }
  195. }
  196. protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
  197. visitAnnotations(node);
  198. analyseMethodHead(node);
  199. Statement code = node.getCode();
  200. visitClassCodeContainer(code);
  201. }
  202. private void analyseMethodHead(MethodNode node) {
  203. visitNode(node.getReturnType());
  204. analyseParameters(node.getParameters());
  205. visitNodes(node.getExceptions());
  206. }
  207. private void analyseParameters(Parameter[] parameters) {
  208. for (int i = 0; i < parameters.length; i++) {
  209. Parameter parameter = parameters[i];
  210. visitType(parameter.getOriginType());
  211. if (parameter.hasInitialExpression()) {
  212. parameter.getInitialExpression().visit(this);
  213. }
  214. }
  215. }
  216. public void visitConstructor(ConstructorNode node) {
  217. visitNode(node);
  218. super.visitConstructor(node);
  219. }
  220. public void visitMethod(MethodNode node) {
  221. visitNode(node);
  222. super.visitMethod(node);
  223. }
  224. public void visitField(FieldNode node) {
  225. // Do not visit fields which are manually added due to optimization
  226. if (!node.getName().startsWith("$")) {
  227. visitType(node.getOriginType());
  228. visitNode(node);
  229. super.visitField(node);
  230. }
  231. }
  232. public void visitProperty(PropertyNode node) {
  233. // do nothing, also visited as FieldNode
  234. }
  235. /*
  236. * Statements
  237. *
  238. * Statements not written here are visited in ClassCodeVisitorSupport and call there
  239. * visitStatement(Statement statement) which is overridden in this class
  240. */
  241. /*
  242. * Expressions
  243. */
  244. public void visitMethodCallExpression(MethodCallExpression call) {
  245. visitNode(call);
  246. super.visitMethodCallExpression(call);
  247. }
  248. public void visitStaticMethodCallExpression(StaticMethodCallExpression call) {
  249. visitNode(call);
  250. super.visitStaticMethodCallExpression(call);
  251. }
  252. public void visitConstructorCallExpression(ConstructorCallExpression call) {
  253. visitNode(call);
  254. visitType(call.getType());
  255. super.visitConstructorCallExpression(call);
  256. }
  257. public void visitBinaryExpression(BinaryExpression expression) {
  258. visitNode(expression);
  259. super.visitBinaryExpression(expression);
  260. }
  261. public void visitTernaryExpression(TernaryExpression expression) {
  262. visitNode(expression);
  263. super.visitTernaryExpression(expression);
  264. }
  265. public void visitPostfixExpression(PostfixExpression expression) {
  266. visitNode(expression);
  267. super.visitPostfixExpression(expression);
  268. }
  269. public void visitPrefixExpression(PrefixExpression expression) {
  270. visitNode(expression);
  271. super.visitPrefixExpression(expression);
  272. }
  273. public void visitBooleanExpression(BooleanExpression expression) {
  274. visitNode(expression);
  275. super.visitBooleanExpression(expression);
  276. }
  277. public void visitNotExpression(NotExpression expression) {
  278. visitNode(expression);
  279. super.visitNotExpression(expression);
  280. }
  281. public void visitClosureExpression(ClosureExpression expression) {
  282. visitNode(expression);
  283. super.visitClosureExpression(expression);
  284. }
  285. public void visitTupleExpression(TupleExpression expression) {
  286. visitNode(expression);
  287. super.visitTupleExpression(expression);
  288. }
  289. public void visitListExpression(ListExpression expression) {
  290. visitNode(expression);
  291. super.visitListExpression(expression);
  292. }
  293. public void visitArrayExpression(ArrayExpression expression) {
  294. visitNode(expression);
  295. visitNode(expression.getElementType());
  296. super.visitArrayExpression(expression);
  297. }
  298. public void visitMapExpression(MapExpression expression) {
  299. visitNode(expression);
  300. super.visitMapExpression(expression);
  301. }
  302. public void visitMapEntryExpression(MapEntryExpression expression) {
  303. visitNode(expression);
  304. super.visitMapEntryExpression(expression);
  305. }
  306. public void visitRangeExpression(RangeExpression expression) {
  307. visitNode(expression);
  308. super.visitRangeExpression(expression);
  309. }
  310. public void visitSpreadExpression(SpreadExpression expression) {
  311. visitNode(expression);
  312. super.visitSpreadExpression(expression);
  313. }
  314. public void visitSpreadMapExpression(SpreadMapExpression expression) {
  315. visitNode(expression);
  316. super.visitSpreadMapExpression(expression);
  317. }
  318. public void visitMethodPointerExpression(MethodPointerExpression expression) {
  319. visitNode(expression);
  320. super.visitMethodPointerExpression(expression);
  321. }
  322. public void visitBitwiseNegationExpression(
  323. BitwiseNegationExpression expression) {
  324. visitNode(expression);
  325. super.visitBitwiseNegationExpression(expression);
  326. }
  327. public void visitCastExpression(CastExpression expression) {
  328. visitNode(expression);
  329. visitType(expression.getType());
  330. super.visitCastExpression(expression);
  331. }
  332. public void visitConstantExpression(ConstantExpression expression) {
  333. visitNode(expression);
  334. super.visitConstantExpression(expression);
  335. }
  336. public void visitClassExpression(ClassExpression expression) {
  337. visitNode(expression);
  338. super.visitClassExpression(expression);
  339. }
  340. public void visitVariableExpression(VariableExpression expression) {
  341. visitNode(expression);
  342. super.visitVariableExpression(expression);
  343. }
  344. public void visitDeclarationExpression(DeclarationExpression expression) {
  345. //visitNode(expression); is visited afterwards in BinaryExpression. Because
  346. //super.visitDeclarationExpression calls visitBinaryExpression
  347. visitType(expression.getLeftExpression().getType());
  348. super.visitDeclarationExpression(expression);
  349. }
  350. public void visitPropertyExpression(PropertyExpression expression) {
  351. visitNode(expression);
  352. super.visitPropertyExpression(expression);
  353. }
  354. public void visitAttributeExpression(AttributeExpression expression) {
  355. visitNode(expression);
  356. super.visitAttributeExpression(expression);
  357. }
  358. public void visitFieldExpression(FieldExpression expression) {
  359. visitNode(expression);
  360. super.visitFieldExpression(expression);
  361. }
  362. public void visitRegexExpression(RegexExpression expression) {
  363. visitNode(expression);
  364. super.visitRegexExpression(expression);
  365. }
  366. public void visitGStringExpression(GStringExpression expression) {
  367. visitNode(expression);
  368. super.visitGStringExpression(expression);
  369. }
  370. public void visitArgumentlistExpression(ArgumentListExpression ale) {
  371. //visitNode(ale); is visited afterwards in TupleExpression. Because
  372. //super.visitArgumentlistExpression calls visitTupleExpression
  373. super.visitArgumentlistExpression(ale);
  374. }
  375. public void visitShortTernaryExpression(ElvisOperatorExpression expression) {
  376. visitNode(expression);
  377. super.visitShortTernaryExpression(expression);
  378. }
  379. public void visitUnaryPlusExpression(UnaryPlusExpression expression) {
  380. visitNode(expression);
  381. super.visitUnaryPlusExpression(expression);
  382. }
  383. public void visitUnaryMinusExpression(UnaryMinusExpression expression) {
  384. visitNode(expression);
  385. super.visitUnaryMinusExpression(expression);
  386. }
  387. public void visitClosureListExpression(ClosureListExpression cle) {
  388. visitNode(cle);
  389. super.visitClosureListExpression(cle);
  390. }
  391. }