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