View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.symboltable;
5   
6   import net.sourceforge.pmd.IPositionProvider;
7   import net.sourceforge.pmd.ast.ASTAssignmentOperator;
8   import net.sourceforge.pmd.ast.ASTExpression;
9   import net.sourceforge.pmd.ast.ASTName;
10  import net.sourceforge.pmd.ast.ASTPostfixExpression;
11  import net.sourceforge.pmd.ast.ASTPreDecrementExpression;
12  import net.sourceforge.pmd.ast.ASTPreIncrementExpression;
13  import net.sourceforge.pmd.ast.ASTPrimaryExpression;
14  import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
15  import net.sourceforge.pmd.ast.ASTStatementExpression;
16  import net.sourceforge.pmd.ast.Node;
17  import net.sourceforge.pmd.ast.SimpleNode;
18  
19  public class NameOccurrence implements IPositionProvider {
20  
21      private SimpleNode location;
22      private String image;
23      private NameOccurrence qualifiedName;
24      private boolean isMethodOrConstructorInvocation;
25  
26      public NameOccurrence(SimpleNode location, String image) {
27          this.location = location;
28          this.image = image;
29      }
30  
31      public void setIsMethodOrConstructorInvocation() {
32          isMethodOrConstructorInvocation = true;
33      }
34  
35      public boolean isMethodOrConstructorInvocation() {
36          return isMethodOrConstructorInvocation;
37      }
38  
39      public void setNameWhichThisQualifies(NameOccurrence qualifiedName) {
40          this.qualifiedName = qualifiedName;
41      }
42  
43      public NameOccurrence getNameForWhichThisIsAQualifier() {
44          return qualifiedName;
45      }
46  
47      public boolean isPartOfQualifiedName() {
48          return qualifiedName != null;
49      }
50  
51      public SimpleNode getLocation() {
52          return location;
53      }
54  
55      public boolean isOnRightHandSide() {
56          SimpleNode node = (SimpleNode) location.jjtGetParent().jjtGetParent().jjtGetParent();
57          return node instanceof ASTExpression && node.jjtGetNumChildren() == 3;
58      }
59  
60      public boolean isOnLeftHandSide() {
61          SimpleNode primaryExpression;
62          if (location.jjtGetParent() instanceof ASTPrimaryExpression) {
63              primaryExpression = (SimpleNode) location.jjtGetParent().jjtGetParent();
64          } else if (location.jjtGetParent().jjtGetParent() instanceof ASTPrimaryExpression) {
65              primaryExpression = (SimpleNode) location.jjtGetParent().jjtGetParent().jjtGetParent();
66          } else {
67              throw new RuntimeException("Found a NameOccurrence that didn't have an ASTPrimary Expression as parent or grandparent.  Parent = " + location.jjtGetParent() + " and grandparent = " + location.jjtGetParent().jjtGetParent());
68          }
69  
70          if (isStandAlonePostfix(primaryExpression))  {
71              return true;
72          }
73  
74          if (primaryExpression.jjtGetNumChildren() <= 1) {
75              return false;
76          }
77  
78          if (!(primaryExpression.jjtGetChild(1) instanceof ASTAssignmentOperator)) {
79              return false;
80          }
81  
82          if (isPartOfQualifiedName() /* or is an array type */) {
83              return false;
84          }
85  
86          if (isCompoundAssignment(primaryExpression)) {
87              return false;
88          }
89  
90          return true;
91      }
92  
93      private boolean isCompoundAssignment(SimpleNode primaryExpression) {
94          return ((ASTAssignmentOperator) (primaryExpression.jjtGetChild(1))).isCompound();
95      }
96  
97      private boolean isStandAlonePostfix(SimpleNode primaryExpression) {
98          if (!(primaryExpression instanceof ASTPostfixExpression) || !(primaryExpression.jjtGetParent() instanceof ASTStatementExpression)) {
99              return false;
100         }
101 
102         ASTPrimaryPrefix pf = (ASTPrimaryPrefix)((ASTPrimaryExpression)primaryExpression.jjtGetChild(0)).jjtGetChild(0);
103         if (pf.usesThisModifier()) {
104             return true;
105         }
106 
107         return thirdChildHasDottedName(primaryExpression);
108     }
109 
110     private boolean thirdChildHasDottedName(SimpleNode primaryExpression) {
111         Node thirdChild = primaryExpression.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
112         return thirdChild instanceof ASTName && ((ASTName)thirdChild).getImage().indexOf(".") == -1;
113     }
114 
115     public boolean isSelfAssignment() {
116         if (location.jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTPreDecrementExpression || location.jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTPreIncrementExpression || location.jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTPostfixExpression) {
117             return true;
118         }
119 
120         if (location.jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTStatementExpression) {
121             ASTStatementExpression exp = (ASTStatementExpression)location.jjtGetParent().jjtGetParent().jjtGetParent();
122             if (exp.jjtGetNumChildren() >= 2 && exp.jjtGetChild(1) instanceof ASTAssignmentOperator) {
123                 ASTAssignmentOperator op = (ASTAssignmentOperator)exp.jjtGetChild(1);
124                 if (op.isCompound()) {
125                     return true;
126                 }
127             }
128         }
129         return false;
130     }
131 
132     public Scope getScope() {
133         return location.getScope();
134     }
135 
136     public int getBeginLine() {
137         return location.getBeginLine();
138     }
139 
140     public boolean isThisOrSuper() {
141         return image.equals("this") || image.equals("super");
142     }
143 
144     public boolean equals(Object o) {
145         NameOccurrence n = (NameOccurrence) o;
146         return n.getImage().equals(getImage());
147     }
148 
149     public String getImage() {
150         return image;
151     }
152 
153     public int hashCode() {
154         return getImage().hashCode();
155     }
156 
157     public String toString() {
158         return getImage() + ":" + location.getBeginLine() + ":" + location.getClass();
159     }
160 
161     /***
162      * @see net.sourceforge.pmd.IPositionProvider#getEndLine()
163      */
164     public int getEndLine() {
165         return location.getEndLine();
166     }
167 
168     /***
169      * @see net.sourceforge.pmd.IPositionProvider#getBeginColumn()
170      */
171     public int getBeginColumn() {
172         return location.getBeginColumn();
173     }
174 
175     /***
176      * @see net.sourceforge.pmd.IPositionProvider#getEndColumn()
177      */
178     public int getEndColumn() {
179         return location.getEndColumn();
180     }
181 
182 }