use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.
the class ForLoopCanBeForeachRule method visit.
@Override
public Object visit(ASTForStatement node, Object data) {
final ASTForInit init = node.getFirstChildOfType(ASTForInit.class);
final ASTForUpdate update = node.getFirstChildOfType(ASTForUpdate.class);
final ASTExpression guardCondition = node.getFirstChildOfType(ASTExpression.class);
if (init == null && update == null || guardCondition == null) {
return data;
}
Entry<VariableNameDeclaration, List<NameOccurrence>> indexDecl = getIndexVarDeclaration(init, update);
if (indexDecl == null) {
return data;
}
List<NameOccurrence> occurrences = indexDecl.getValue();
VariableNameDeclaration index = indexDecl.getKey();
if (TypeHelper.isA(index, Iterator.class)) {
Entry<VariableNameDeclaration, List<NameOccurrence>> iterableInfo = getIterableDeclOfIteratorLoop(index, node.getScope());
if (iterableInfo != null && isReplaceableIteratorLoop(indexDecl, guardCondition, iterableInfo, node)) {
addViolation(data, node);
}
return data;
}
if (occurrences == null || !"int".equals(index.getTypeImage()) || !indexStartsAtZero(index)) {
return data;
}
String itName = index.getName();
String iterableName = getIterableNameOrNullToAbort(guardCondition, itName);
if (!isForUpdateSimpleEnough(update, itName) || iterableName == null) {
return data;
}
Entry<VariableNameDeclaration, List<NameOccurrence>> iterableInfo = findDeclaration(iterableName, node.getScope());
VariableNameDeclaration iterableDeclaration = iterableInfo == null ? null : iterableInfo.getKey();
if (iterableDeclaration == null) {
return data;
}
if (iterableDeclaration.isArray() && isReplaceableArrayLoop(node, occurrences, iterableDeclaration)) {
addViolation(data, node);
} else if (iterableDeclaration.getTypeImage() != null && iterableDeclaration.getTypeImage().matches("List|ArrayList|LinkedList") && isReplaceableListLoop(node, occurrences, iterableDeclaration)) {
addViolation(data, node);
}
return data;
}
use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.
the class ForLoopCanBeForeachRule method getIndexVarDeclaration.
/* Finds the declaration of the index variable and its occurrences, null to abort */
private Entry<VariableNameDeclaration, List<NameOccurrence>> getIndexVarDeclaration(ASTForInit init, ASTForUpdate update) {
if (init == null) {
return guessIndexVarFromUpdate(update);
}
ASTLocalVariableDeclaration decl = init.getFirstChildOfType(ASTLocalVariableDeclaration.class);
if (decl == null) {
return null;
}
int numDeclaredVars = decl.findChildrenOfType(ASTVariableDeclarator.class).size();
if (numDeclaredVars > 1) {
// will abort in the calling function
return null;
}
Map<VariableNameDeclaration, List<NameOccurrence>> decls = init.getScope().getDeclarations(VariableNameDeclaration.class);
Entry<VariableNameDeclaration, List<NameOccurrence>> indexVarAndOccurrences = null;
for (Entry<VariableNameDeclaration, List<NameOccurrence>> e : decls.entrySet()) {
ASTForInit declInit = e.getKey().getNode().getFirstParentOfType(ASTForInit.class);
if (Objects.equals(declInit, init)) {
indexVarAndOccurrences = e;
break;
}
}
return indexVarAndOccurrences;
}
use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.
the class StatementAndBraceFinder method addForExpressionNode.
/*
* The method handles the special "for" loop. It creates always an
* expression node even if the loop looks like for(;;).
*/
private void addForExpressionNode(Node node, Structure dataFlow) {
ASTForStatement parent = (ASTForStatement) node.jjtGetParent();
boolean hasExpressionChild = false;
boolean hasForInitNode = false;
boolean hasForUpdateNode = false;
for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
if (parent.jjtGetChild(i) instanceof ASTExpression) {
hasExpressionChild = true;
} else if (parent.jjtGetChild(i) instanceof ASTForUpdate) {
hasForUpdateNode = true;
} else if (parent.jjtGetChild(i) instanceof ASTForInit) {
hasForInitNode = true;
}
}
if (!hasExpressionChild) {
if (node instanceof ASTForInit) {
dataFlow.createNewNode(node);
dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
tryToLog(NodeType.FOR_EXPR, node);
} else if (node instanceof ASTForUpdate) {
if (!hasForInitNode) {
dataFlow.createNewNode(node);
dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
tryToLog(NodeType.FOR_EXPR, node);
}
} else if (node instanceof ASTStatement) {
if (!hasForInitNode && !hasForUpdateNode) {
dataFlow.createNewNode(node);
dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
tryToLog(NodeType.FOR_EXPR, node);
}
}
}
}
use of net.sourceforge.pmd.lang.java.ast.ASTForInit in project pmd by pmd.
the class PrematureDeclarationRule method visit.
/**
* @param node
* ASTLocalVariableDeclaration
* @param data
* Object
* @return Object
* @see net.sourceforge.pmd.lang.java.ast.JavaParserVisitor#visit(ASTLocalVariableDeclaration,
* Object)
*/
public Object visit(ASTLocalVariableDeclaration node, Object data) {
// is it part of a for-loop declaration?
if (node.jjtGetParent() instanceof ASTForInit) {
// yes, those don't count
return visit((AbstractJavaNode) node, data);
}
String varName = varNameIn(node);
AbstractJavaNode grandparent = (AbstractJavaNode) node.jjtGetParent().jjtGetParent();
List<ASTBlockStatement> nextBlocks = blocksAfter(grandparent, node);
for (ASTBlockStatement block : nextBlocks) {
if (hasReferencesIn(block, varName) || isLambda(block)) {
break;
}
if (hasExit(block)) {
addViolation(data, node, varName);
break;
}
}
return visit((AbstractJavaNode) node, data);
}
Aggregations