1 4 package net.sourceforge.pmd.rules.design; 5 6 import net.sourceforge.pmd.AbstractRule; 7 import net.sourceforge.pmd.ast.ASTConditionalAndExpression; 8 import net.sourceforge.pmd.ast.ASTConditionalExpression; 9 import net.sourceforge.pmd.ast.ASTConditionalOrExpression; 10 import net.sourceforge.pmd.ast.ASTEqualityExpression; 11 import net.sourceforge.pmd.ast.ASTExpression; 12 import net.sourceforge.pmd.ast.ASTIfStatement; 13 import net.sourceforge.pmd.ast.ASTPrimaryExpression; 14 import net.sourceforge.pmd.ast.ASTPrimaryPrefix; 15 import net.sourceforge.pmd.ast.ASTUnaryExpressionNotPlusMinus; 16 import net.sourceforge.pmd.ast.SimpleNode; 17 18 39 public class ConfusingTernary extends AbstractRule { 40 41 public Object visit(ASTIfStatement node, Object data) { 42 if (node.jjtGetNumChildren() == 3) { 44 SimpleNode inode = (SimpleNode) node.jjtGetChild(0); 45 if (inode instanceof ASTExpression && 46 inode.jjtGetNumChildren() == 1) { 47 SimpleNode jnode = (SimpleNode) inode.jjtGetChild(0); 48 if (isMatch(jnode)) { 49 addViolation(data, node); 50 } 51 } 52 } 53 return super.visit(node, data); 54 } 55 56 public Object visit(ASTConditionalExpression node, Object data) { 57 if (node.jjtGetNumChildren() > 0) { 59 SimpleNode inode = (SimpleNode) node.jjtGetChild(0); 60 if (isMatch(inode)) { 61 addViolation(data, node); 62 } 63 } 64 return super.visit(node, data); 65 } 66 67 private static boolean isMatch(SimpleNode node) { 69 return 70 isUnaryNot(node) || 71 isNotEquals(node) || 72 isConditionalWithAllMatches(node) || 73 isParenthesisAroundMatch(node); 74 } 75 76 private static boolean isUnaryNot(SimpleNode node) { 77 return 79 node instanceof ASTUnaryExpressionNotPlusMinus && 80 "!".equals(node.getImage()); 81 } 82 83 private static boolean isNotEquals(SimpleNode node) { 84 return 86 node instanceof ASTEqualityExpression && 87 "!=".equals(node.getImage()); 88 } 89 90 private static boolean isConditionalWithAllMatches(SimpleNode node) { 91 if (!(node instanceof ASTConditionalAndExpression) && 93 !(node instanceof ASTConditionalOrExpression)) { 94 return false; 95 } 96 int i_max = node.jjtGetNumChildren(); 97 if (i_max <= 0) { 98 return false; 99 } 100 for (int i = 0; i < i_max; i++) { 101 SimpleNode inode = (SimpleNode) node.jjtGetChild(i); 102 if (!isMatch(inode)) { 104 return false; 105 } 106 } 107 return true; 109 } 110 111 private static boolean isParenthesisAroundMatch(SimpleNode node) { 112 if (!(node instanceof ASTPrimaryExpression) || 114 (node.jjtGetNumChildren() != 1)) { 115 return false; 116 } 117 SimpleNode inode = (SimpleNode) node.jjtGetChild(0); 118 if (!(inode instanceof ASTPrimaryPrefix) || 119 (inode.jjtGetNumChildren() != 1)) { 120 return false; 121 } 122 SimpleNode jnode = (SimpleNode) inode.jjtGetChild(0); 123 if (!(jnode instanceof ASTExpression) || 124 (jnode.jjtGetNumChildren() != 1)) { 125 return false; 126 } 127 SimpleNode knode = (SimpleNode) jnode.jjtGetChild(0); 128 return isMatch(knode); 130 } 131 } 132 | Popular Tags |