KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > rules > design > UnnecessaryLocalBeforeReturn


1 package net.sourceforge.pmd.rules.design;
2
3 import java.util.Iterator JavaDoc;
4 import java.util.List JavaDoc;
5 import java.util.Map JavaDoc;
6
7 import net.sourceforge.pmd.AbstractRule;
8 import net.sourceforge.pmd.ast.ASTExpression;
9 import net.sourceforge.pmd.ast.ASTMethodDeclaration;
10 import net.sourceforge.pmd.ast.ASTName;
11 import net.sourceforge.pmd.ast.ASTPrimaryExpression;
12 import net.sourceforge.pmd.ast.ASTPrimarySuffix;
13 import net.sourceforge.pmd.ast.ASTReturnStatement;
14 import net.sourceforge.pmd.symboltable.NameOccurrence;
15 import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
16
17 public class UnnecessaryLocalBeforeReturn extends AbstractRule {
18
19     public Object JavaDoc visit(ASTMethodDeclaration meth, Object JavaDoc data) {
20         // skip void/abstract/native method
21
if (meth.isVoid() || meth.isAbstract() || meth.isNative()) {
22             return data;
23         }
24         return super.visit(meth, data);
25     }
26
27     public Object JavaDoc visit(ASTReturnStatement rtn, Object JavaDoc data) {
28         // skip returns of literals
29
ASTName name = (ASTName) rtn.getFirstChildOfType(ASTName.class);
30         if (name == null) {
31             return data;
32         }
33
34         // skip 'complicated' expressions
35
if (rtn.findChildrenOfType(ASTExpression.class).size() > 1 || rtn.findChildrenOfType(ASTPrimaryExpression.class).size() > 1 || isMethodCall(rtn)) {
36             return data;
37         }
38
39         Map JavaDoc vars = name.getScope().getVariableDeclarations();
40         for (Iterator JavaDoc i = vars.entrySet().iterator(); i.hasNext();) {
41             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
42             VariableNameDeclaration key = (VariableNameDeclaration) entry.getKey();
43             List JavaDoc usages = (List JavaDoc) entry.getValue();
44             for (Iterator JavaDoc j = usages.iterator(); j.hasNext();) {
45                 NameOccurrence occ = (NameOccurrence) j.next();
46                 if (occ.getLocation().equals(name)) {
47                     // only check declarations that occur one line earlier
48
if (key.getNode().getBeginLine() == name.getBeginLine() - 1) {
49                         String JavaDoc var = name.getImage();
50                         if (var.indexOf('.') != -1) {
51                             var = var.substring(0, var.indexOf('.'));
52                         }
53                         addViolation(data, rtn, var);
54                     }
55                 }
56             }
57         }
58         return data;
59     }
60     
61     /**
62      * Determine if the given return statement has any embedded method calls.
63      *
64      * @param rtn
65      * return statement to analyze
66      * @return true if any method calls are made within the given return
67      */

68     private boolean isMethodCall(ASTReturnStatement rtn) {
69      List JavaDoc suffix = rtn.findChildrenOfType( ASTPrimarySuffix.class );
70      for ( Iterator JavaDoc iter = suffix.iterator(); iter.hasNext(); ) {
71         ASTPrimarySuffix element = (ASTPrimarySuffix) iter.next();
72         if ( element.isArguments() ) {
73           return true;
74         }
75       }
76       return false;
77     }
78 }
79
Popular Tags