use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.
the class VariableAccessVisitor method markUsages.
private List<VariableAccess> markUsages(DataFlowNode inode) {
// undefinitions was once a field... seems like it works fine as a local
List<VariableAccess> undefinitions = new ArrayList<>();
Set<Map<VariableNameDeclaration, List<NameOccurrence>>> variableDeclarations = collectDeclarations(inode);
for (Map<VariableNameDeclaration, List<NameOccurrence>> declarations : variableDeclarations) {
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : declarations.entrySet()) {
VariableNameDeclaration vnd = entry.getKey();
if (vnd.getAccessNodeParent() instanceof ASTFormalParameter) {
// no definition/undefinition/references for parameters
continue;
} else if (vnd.getAccessNodeParent().getFirstDescendantOfType(ASTVariableInitializer.class) != null) {
// add definition for initialized variables
addVariableAccess(vnd.getNode(), new VariableAccess(VariableAccess.DEFINITION, vnd.getImage()), inode.getFlow());
}
undefinitions.add(new VariableAccess(VariableAccess.UNDEFINITION, vnd.getImage()));
for (NameOccurrence occurrence : entry.getValue()) {
addAccess((JavaNameOccurrence) occurrence, inode);
}
}
}
return undefinitions;
}
use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.
the class CompareObjectsWithEqualsRule method visit.
public Object visit(ASTEqualityExpression node, Object data) {
Node c0 = node.jjtGetChild(0).jjtGetChild(0);
Node c1 = node.jjtGetChild(1).jjtGetChild(0);
// equals expression is correct
if (isAllocation(c0) || isAllocation(c1)) {
addViolation(data, node);
return data;
}
// skip if either child is not a simple name
if (!hasName(c0) || !hasName(c1)) {
return data;
}
// skip if either is a qualified name
if (isQualifiedName(c0.jjtGetChild(0)) || isQualifiedName(c1.jjtGetChild(0))) {
return data;
}
// skip if either is part of a qualified name
if (isPartOfQualifiedName(node.jjtGetChild(0)) || isPartOfQualifiedName(node.jjtGetChild(1))) {
return data;
}
// skip static initializers... missing some cases here
if (!node.getParentsOfType(ASTInitializer.class).isEmpty()) {
return data;
}
ASTName n0 = (ASTName) c0.jjtGetChild(0);
ASTName n1 = (ASTName) c1.jjtGetChild(0);
if (n0.getNameDeclaration() instanceof VariableNameDeclaration && n1.getNameDeclaration() instanceof VariableNameDeclaration) {
VariableNameDeclaration nd0 = (VariableNameDeclaration) n0.getNameDeclaration();
VariableNameDeclaration nd1 = (VariableNameDeclaration) n1.getNameDeclaration();
// FIXME catch comparisons btwn array elements of reference types
if (nd0.isArray() || nd1.isArray()) {
return data;
}
if (nd0.isReferenceType() && nd1.isReferenceType()) {
ASTReferenceType type0 = ((Node) nd0.getAccessNodeParent()).getFirstDescendantOfType(ASTReferenceType.class);
ASTReferenceType type1 = ((Node) nd1.getAccessNodeParent()).getFirstDescendantOfType(ASTReferenceType.class);
// skip, if it is an enum
if (type0.getType() != null && type0.getType().equals(type1.getType()) && // It may be a custom enum class or an explicit Enum class usage
(type0.getType().isEnum() || type0.getType() == java.lang.Enum.class)) {
return data;
}
addViolation(data, node);
}
}
return data;
}
use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.
the class ImmutableFieldRule method visit.
@Override
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
Object result = super.visit(node, data);
Map<VariableNameDeclaration, List<NameOccurrence>> vars = node.getScope().getDeclarations(VariableNameDeclaration.class);
List<ASTConstructorDeclaration> constructors = findAllConstructors(node);
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : vars.entrySet()) {
VariableNameDeclaration field = entry.getKey();
AccessNode accessNodeParent = field.getAccessNodeParent();
if (accessNodeParent.isStatic() || !accessNodeParent.isPrivate() || accessNodeParent.isFinal() || accessNodeParent.isVolatile() || hasClassLombokAnnotation()) {
continue;
}
FieldImmutabilityType type = initializedInConstructor(entry.getValue(), new HashSet<>(constructors));
if (type == FieldImmutabilityType.MUTABLE) {
continue;
}
if (type == FieldImmutabilityType.IMMUTABLE || type == FieldImmutabilityType.CHECKDECL && initializedWhenDeclared(field)) {
addViolation(data, field.getNode(), field.getImage());
}
}
return result;
}
use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.
the class ClassTypeResolver method getTypeDefinitionOfVariableFromScope.
/**
* Search for a field by it's image stating from a scope and taking into account if it's visible from the
* accessingClass Class. The method takes into account that Nested inherited fields shadow outer scope fields.
*
* @param scope The scope to start the search from.
* @param image The name of the field, local variable or method parameter.
* @param accessingClass The Class (which is defined in the current ACU) that is trying to access the field.
* @return Type def. of the field, or null if it could not be resolved.
*/
private JavaTypeDefinition getTypeDefinitionOfVariableFromScope(Scope scope, String image, Class<?> accessingClass) {
if (accessingClass == null) {
return null;
}
for (; /* empty */
scope != null; scope = scope.getParent()) {
// search each enclosing scope one by one
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : scope.getDeclarations(VariableNameDeclaration.class).entrySet()) {
if (entry.getKey().getImage().equals(image)) {
ASTType typeNode = entry.getKey().getDeclaratorId().getTypeNode();
if (typeNode == null) {
// TODO : Type is infered, ie, this is a lambda such as (var) -> var.equals(other)
return null;
}
if (typeNode.jjtGetChild(0) instanceof ASTReferenceType) {
return ((TypeNode) typeNode.jjtGetChild(0)).getTypeDefinition();
} else {
// primitive type
return JavaTypeDefinition.forClass(typeNode.getType());
}
}
}
// Nested class' inherited fields shadow enclosing variables
if (scope instanceof ClassScope) {
try {
// get the superclass type def. ot the Class the ClassScope belongs to
JavaTypeDefinition superClass = getSuperClassTypeDefinition(((ClassScope) scope).getClassDeclaration().getNode(), null);
// TODO: check if anonymous classes are class scope
// try searching this type def.
JavaTypeDefinition foundTypeDef = getFieldType(superClass, image, accessingClass);
if (foundTypeDef != null) {
// if null, then it's not an inherited field
return foundTypeDef;
}
} catch (ClassCastException ignored) {
// if there is an anonymous class, getClassDeclaration().getType() will throw
// TODO: maybe there is a better way to handle this, maybe this hides bugs
}
}
}
// will return null if not found
return searchImportedStaticFields(image);
}
use of net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration in project pmd by pmd.
the class AvoidReassigningParametersRule method lookForViolation.
private void lookForViolation(Map<VariableNameDeclaration, List<NameOccurrence>> params, Object data) {
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : params.entrySet()) {
VariableNameDeclaration decl = entry.getKey();
List<NameOccurrence> usages = entry.getValue();
for (NameOccurrence occ : usages) {
JavaNameOccurrence jocc = (JavaNameOccurrence) occ;
if ((jocc.isOnLeftHandSide() || jocc.isSelfAssignment()) && jocc.getNameForWhichThisIsAQualifier() == null && !jocc.useThisOrSuper() && !decl.isVarargs() && (!decl.isArray() || jocc.getLocation().jjtGetParent().jjtGetParent().jjtGetNumChildren() == 1)) {
// not an array or no primary suffix to access the array
// values
addViolation(data, decl.getNode(), decl.getImage());
}
}
}
}
Aggregations