KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hammurapi > inspectors > ForLoopControlVariablesRule


1 /*
2  * Hammurapi
3  * Automated Java code review system.
4  * Copyright (C) 2004 Hammurapi Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * URL: http://www.hammurapi.org
21  * e-Mail: support@hammurapi.biz
22  */

23 package org.hammurapi.inspectors;
24
25 import java.util.Collection JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Iterator JavaDoc;
28
29 import org.hammurapi.InspectorBase;
30 import org.hammurapi.HammurapiException;
31 import org.hammurapi.InspectorContext;
32
33 import com.pavelvlasov.jsel.Declaration;
34 import com.pavelvlasov.jsel.VariableDefinition;
35 import com.pavelvlasov.jsel.expressions.AssignmentExpression;
36 import com.pavelvlasov.jsel.expressions.ConditionalExpression;
37 import com.pavelvlasov.jsel.expressions.Expression;
38 import com.pavelvlasov.jsel.expressions.ExpressionList;
39 import com.pavelvlasov.jsel.expressions.Ident;
40 import com.pavelvlasov.jsel.expressions.LogicalOr;
41 import com.pavelvlasov.jsel.statements.ForStatement;
42 import com.pavelvlasov.review.SourceMarker;
43 import com.pavelvlasov.util.AccumulatingVisitorExceptionSink;
44 import com.pavelvlasov.util.DispatchingVisitor;
45 import com.pavelvlasov.util.Visitable;
46
47 /**
48  * ER-098
49  * Do not assign loop control variables in the body of a "for" loop
50  * @author Janos Czako
51  * @author Pavel Vlasov
52  * @version $Revision: 1.5 $
53  */

54 public class ForLoopControlVariablesRule extends InspectorBase {
55     
56     /**
57      * The chained visitor class which searches after assigning
58      * the loop control variable.
59      */

60     public static class Snooper {
61
62         /**
63          * The name of the loop control variable, searched for.
64          */

65         private Collection JavaDoc names;
66         private InspectorContext context;
67         
68         /**
69          * Constructor, takes the name searched for.
70          *
71          * @param theIdentName the name of the variable searched for.
72          */

73         public Snooper(final Collection JavaDoc names, InspectorContext context) {
74             this.names=names;
75             this.context=context;
76         }
77
78         /**
79          * Reviews the assignments.
80          *
81          * @param element the assignment to be reviewed.
82          */

83         public void visit(AssignmentExpression element) {
84             if (!(element instanceof LogicalOr || element instanceof ConditionalExpression)) {
85                 if (element.getOperand(0) instanceof Ident) {
86                     Ident ident = (Ident) element.getOperand(0);
87                     if (names.contains(ident.getText())) {
88                         context.reportViolation((SourceMarker) element);
89                     }
90                 }
91             }
92         }
93     }
94     
95     /**
96      * The error text for exceptions in the chained visitor.
97      */

98     private static final String JavaDoc CHAINED_ERRS = "There have been exceptions (see above)";
99
100     /**
101      * Reviews the for statement if it violates agains the rule
102      *
103      * @param element the fro statement
104      * @throws HammurapiException in case of any exception in the chained visitor
105      */

106     public void visit(ForStatement element) throws HammurapiException {
107         Collection JavaDoc names=new HashSet JavaDoc();
108         if (element.getInitializer()!=null) {
109             if (element.getInitializer() instanceof Declaration) {
110                 getNames((Declaration) element.getInitializer(), names);
111             } else if (element.getInitializer() instanceof ExpressionList) {
112                 getNames((ExpressionList) element.getInitializer(), names);
113             }
114         }
115         
116         if (!names.isEmpty()) {
117             Snooper rs = new Snooper(names, context);
118             // TODO Don't use DispatchingVisitor, use plain visitor
119
// TODO Use Scope.getVariableNamespace().find() to make sure that
120
// first operand of assignment expression is control variable
121
AccumulatingVisitorExceptionSink es = new AccumulatingVisitorExceptionSink();
122             ((Visitable) element.getStatement()).accept(new DispatchingVisitor(rs, es));
123     
124             if (!es.getExceptions().isEmpty()) {
125                 es.dump();
126                 throw new HammurapiException(CHAINED_ERRS);
127             }
128         }
129     }
130     
131     /**
132      * Gets the control variable name in for loop
133      * if it is declared in the for statement
134      *
135      * @param element the declaration
136      * @return the name of the variable
137      */

138     private void getNames(Declaration element, Collection JavaDoc names) {
139         Iterator JavaDoc it=element.iterator();
140         while (it.hasNext()) {
141             VariableDefinition vd = (VariableDefinition) it.next();
142             names.add(vd.getName());
143         }
144     }
145     
146     /**
147      * Gets the control variable name in for loop
148      * if it is declared not in the for statement
149      *
150      * @param element the assigment expression from the for statement
151      * @return the assignment expression
152      */

153     private void getNames(ExpressionList element, Collection JavaDoc names) {
154         Iterator JavaDoc it=element.iterator();
155         while (it.hasNext()) {
156             Object JavaDoc o=it.next();
157             if (o instanceof AssignmentExpression
158                     && !(o instanceof LogicalOr || o instanceof ConditionalExpression)
159                     && ((Expression) o).getOperand(0) instanceof Ident) {
160                 names.add(((Ident) ((Expression) o).getOperand(0)).getText());
161             }
162         }
163     }
164 }
165
Popular Tags