1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.codehaus.groovy.classgen;
47
48 import java.util.Iterator;
49 import java.util.List;
50
51 import org.codehaus.groovy.ast.ASTNode;
52 import org.codehaus.groovy.ast.CodeVisitorSupport;
53 import org.codehaus.groovy.ast.stmt.ForStatement;
54 import org.codehaus.groovy.ast.expr.BinaryExpression;
55 import org.codehaus.groovy.ast.expr.Expression;
56 import org.codehaus.groovy.ast.expr.ListExpression;
57 import org.codehaus.groovy.ast.expr.MapEntryExpression;
58 import org.codehaus.groovy.ast.expr.MethodCallExpression;
59 import org.codehaus.groovy.ast.expr.PropertyExpression;
60 import org.codehaus.groovy.ast.expr.FieldExpression;
61 import org.codehaus.groovy.ast.expr.VariableExpression;
62 import org.codehaus.groovy.syntax.RuntimeParserException;
63 import org.objectweb.asm.Opcodes;
64
65 /***
66 * Verifies the method code
67 *
68 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
69 * @version $Revision: 4032 $
70 */
71 public class VerifierCodeVisitor extends CodeVisitorSupport implements Opcodes {
72
73 private Verifier verifier;
74
75 VerifierCodeVisitor(Verifier verifier) {
76 this.verifier = verifier;
77 }
78
79 public void visitMethodCallExpression(MethodCallExpression call) {
80 super.visitMethodCallExpression(call);
81 }
82
83 public void visitForLoop(ForStatement expression) {
84 assertValidIdentifier(expression.getVariable().getName(), "for loop variable name", expression);
85 super.visitForLoop(expression);
86 }
87
88 public void visitPropertyExpression(PropertyExpression expression) {
89
90 super.visitPropertyExpression(expression);
91 }
92
93 public void visitFieldExpression(FieldExpression expression) {
94 assertValidIdentifier(expression.getFieldName(), "field name", expression);
95 super.visitFieldExpression(expression);
96 }
97
98 public void visitVariableExpression(VariableExpression expression) {
99 assertValidIdentifier(expression.getName(), "variable name", expression);
100 super.visitVariableExpression(expression);
101 }
102
103 public void visitBinaryExpression(BinaryExpression expression) {
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 super.visitBinaryExpression(expression);
120 }
121
122 public static void assertValidIdentifier(String name, String message, ASTNode node) {
123 int size = name.length();
124 if (size <= 0) {
125 throw new RuntimeParserException("Invalid " + message + ". Identifier must not be empty", node);
126 }
127 char firstCh = name.charAt(0);
128 if (!Character.isJavaIdentifierStart(firstCh) || firstCh == '$') {
129 throw new RuntimeParserException("Invalid " + message + ". Must start with a letter but was: " + name, node);
130 }
131
132 for (int i = 1; i < size; i++) {
133 char ch = name.charAt(i);
134 if (!Character.isJavaIdentifierPart(ch)) {
135 throw new RuntimeParserException("Invalid " + message + ". Invalid character at position: " + (i + 1) + " of value: " + ch + " in name: " + name, node);
136 }
137 }
138 }
139
140 public void visitListExpression(ListExpression expression) {
141 List expressions = expression.getExpressions();
142 for (Iterator iter = expressions.iterator(); iter.hasNext();) {
143 Object element = iter.next();
144 if (element instanceof MapEntryExpression) {
145 throw new RuntimeParserException ("no map entry allowed at this place",(Expression) element);
146 }
147 }
148 super.visitListExpression(expression);
149 }
150 }