net.sourceforge.pmd.lang.java.internal.JavaDesignerBindings Maven / Gradle / Ivy
The newest version!
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr;
import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression;
import net.sourceforge.pmd.lang.java.ast.ASTClassType;
import net.sourceforge.pmd.lang.java.ast.ASTCompactConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression;
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodReference;
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess;
import net.sourceforge.pmd.lang.java.ast.ASTVariableId;
import net.sourceforge.pmd.lang.java.ast.InvocationNode;
import net.sourceforge.pmd.lang.java.ast.JModifier;
import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.ast.JavaVisitorBase;
import net.sourceforge.pmd.lang.java.ast.ModifierOwner;
import net.sourceforge.pmd.lang.java.ast.TypeNode;
import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol;
import net.sourceforge.pmd.lang.java.types.JTypeMirror;
import net.sourceforge.pmd.lang.rule.xpath.Attribute;
import net.sourceforge.pmd.util.designerbindings.DesignerBindings.DefaultDesignerBindings;
import net.sourceforge.pmd.util.designerbindings.RelatedNodesSelector;
public final class JavaDesignerBindings extends DefaultDesignerBindings {
public static final JavaDesignerBindings INSTANCE = new JavaDesignerBindings();
private JavaDesignerBindings() {
}
@Override
public Attribute getMainAttribute(Node node) {
if (node instanceof JavaNode) {
Attribute attr = node.acceptVisitor(MainAttrVisitor.INSTANCE, null);
if (attr != null) {
return attr;
}
}
return super.getMainAttribute(node);
}
@Override
public TreeIconId getIcon(Node node) {
if (node instanceof ASTFieldDeclaration) {
return TreeIconId.FIELD;
} else if (node instanceof ASTTypeDeclaration) {
return TreeIconId.CLASS;
} else if (node instanceof ASTMethodDeclaration) {
return TreeIconId.METHOD;
} else if (node instanceof ASTConstructorDeclaration
|| node instanceof ASTCompactConstructorDeclaration) {
return TreeIconId.CONSTRUCTOR;
} else if (node instanceof ASTVariableId) {
return TreeIconId.VARIABLE;
}
return super.getIcon(node);
}
@Override
public Collection getAdditionalInfo(Node node) {
List info = new ArrayList<>(super.getAdditionalInfo(node));
if (node instanceof ASTLambdaExpression) {
ASTLambdaExpression lambda = (ASTLambdaExpression) node;
info.add(new AdditionalInfo("Function type: " + lambda.getFunctionalMethod()));
}
if (node instanceof ASTMethodReference) {
ASTMethodReference lambda = (ASTMethodReference) node;
info.add(new AdditionalInfo("Function type: " + lambda.getFunctionalMethod()));
info.add(new AdditionalInfo("CTDecl: " + lambda.getReferencedMethod()));
}
if (node instanceof InvocationNode) {
InvocationNode invoc = (InvocationNode) node;
info.add(new AdditionalInfo("Function: " + invoc.getMethodType()));
info.add(new AdditionalInfo("VarargsCall: " + invoc.getOverloadSelectionInfo().isVarargsCall()));
info.add(new AdditionalInfo("Unchecked: " + invoc.getOverloadSelectionInfo().needsUncheckedConversion()));
info.add(new AdditionalInfo("Failed: " + invoc.getOverloadSelectionInfo().isFailed()));
}
if (node instanceof TypeNode) {
JTypeMirror typeMirror = ((TypeNode) node).getTypeMirror();
info.add(new AdditionalInfo("Type: " + typeMirror));
}
if (node instanceof ModifierOwner) {
String effective = formatModifierSet(((ModifierOwner) node).getModifiers().getEffectiveModifiers());
String explicit = formatModifierSet(((ModifierOwner) node).getModifiers().getExplicitModifiers());
info.add(new AdditionalInfo("pmd-java:modifiers(): " + effective));
info.add(new AdditionalInfo("pmd-java:explicitModifiers(): " + explicit));
}
return info;
}
@NonNull
private String formatModifierSet(Set modifierSet) {
return modifierSet.stream().map(JModifier::toString).collect(Collectors.joining(", ", "(", ")"));
}
@Override
public RelatedNodesSelector getRelatedNodesSelector() {
return n -> {
if (n instanceof ASTNamedReferenceExpr) {
JVariableSymbol sym = ((ASTNamedReferenceExpr) n).getReferencedSym();
if (sym != null && sym.tryGetNode() != null) {
return Collections.unmodifiableList(sym.tryGetNode().getLocalUsages());
}
}
return Collections.emptyList();
};
}
private static final class MainAttrVisitor extends JavaVisitorBase {
private static final MainAttrVisitor INSTANCE = new MainAttrVisitor();
@Override
public Attribute visitJavaNode(JavaNode node, Void data) {
return null; // don't recurse
}
@Override
public Attribute visit(ASTInfixExpression node, Void data) {
return new Attribute(node, "Operator", node.getOperator().toString());
}
@Override
public Attribute visitTypeDecl(ASTTypeDeclaration node, Void data) {
return new Attribute(node, "SimpleName", node.getSimpleName());
}
@Override
public Attribute visit(ASTAnnotation node, Void data) {
return new Attribute(node, "SimpleName", node.getSimpleName());
}
@Override
public Attribute visit(ASTClassType node, Void data) {
return new Attribute(node, "SimpleName", node.getSimpleName());
}
@Override
public Attribute visit(ASTPrimitiveType node, Void data) {
return new Attribute(node, "Kind", node.getKind().getSimpleName());
}
@Override
public Attribute visit(ASTMethodCall node, Void data) {
return new Attribute(node, "MethodName", node.getMethodName());
}
@Override
public Attribute visit(ASTMethodReference node, Void data) {
return new Attribute(node, "MethodName", node.getMethodName());
}
@Override
public Attribute visit(ASTFieldAccess node, Void data) {
return new Attribute(node, "Name", node.getName());
}
@Override
public Attribute visit(ASTVariableAccess node, Void data) {
return new Attribute(node, "Name", node.getName());
}
@Override
public Attribute visit(ASTMethodDeclaration node, Void data) {
return new Attribute(node, "Name", node.getName());
}
@Override
public Attribute visit(ASTVariableId node, Void data) {
return new Attribute(node, "Name", node.getName());
}
@Override
public Attribute visit(ASTAssignmentExpression node, Void data) {
return new Attribute(node, "Operator", node.getOperator().getToken());
}
@Override
public Attribute visit(ASTUnaryExpression node, Void data) {
return new Attribute(node, "Operator", node.getOperator().getToken());
}
}
}