/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.lang.java.rule.basic; import java.io.InputStream; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression; import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence; import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; public class CheckSkipResultRule extends AbstractJavaRule { @Override public Object visit(ASTVariableDeclaratorId node, Object data) { ASTType typeNode = node.getTypeNode(); if (typeNode == null || !TypeHelper.isA(typeNode, InputStream.class)) { return data; } for (NameOccurrence occ : node.getUsages()) { JavaNameOccurrence jocc = (JavaNameOccurrence) occ; NameOccurrence qualifier = jocc.getNameForWhichThisIsAQualifier(); if (qualifier != null && "skip".equals(qualifier.getImage())) { Node loc = jocc.getLocation(); if (loc != null) { ASTPrimaryExpression exp = loc.getFirstParentOfType(ASTPrimaryExpression.class); while (exp != null) { if (exp.jjtGetParent() instanceof ASTStatementExpression) { // if exp is in a bare statement, // the returned value is not used addViolation(data, occ.getLocation()); break; } else if (exp.jjtGetParent() instanceof ASTExpression && exp.jjtGetParent().jjtGetParent() instanceof ASTPrimaryPrefix) { // if exp is enclosed in a pair of parenthesis // let's have a look at the enclosing expression // we'll see if it's in a bare statement exp = exp.getFirstParentOfType(ASTPrimaryExpression.class); } else { // if exp is neither in a bare statement // or between a pair of parentheses, // it's in some other kind of statement // or assignement so the returned value is used break; } } } } } return data; } }