
de.is24.javaparser.Nodes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of deadcode4j-maven-plugin Show documentation
Show all versions of deadcode4j-maven-plugin Show documentation
Finds unused classes of a project
package de.is24.javaparser;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.Node;
import japa.parser.ast.body.ClassOrInterfaceDeclaration;
import japa.parser.ast.body.EnumDeclaration;
import japa.parser.ast.body.TypeDeclaration;
import japa.parser.ast.expr.NameExpr;
import japa.parser.ast.expr.ObjectCreationExpr;
import japa.parser.ast.expr.QualifiedNameExpr;
import japa.parser.ast.stmt.TypeDeclarationStmt;
import javax.annotation.Nonnull;
import java.util.Deque;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newLinkedList;
import static de.is24.deadcode4j.Utils.isEmpty;
/**
* Provides convenience methods for dealing with {@link japa.parser.ast.Node}s.
*
* @since 2.0.0
*/
public class Nodes {
private Nodes() {}
@Nonnull
public static CompilationUnit getCompilationUnit(@Nonnull Node node) {
Node loopNode = node;
for (; ; ) {
if (CompilationUnit.class.isInstance(loopNode)) {
return CompilationUnit.class.cast(loopNode);
}
loopNode = loopNode.getParentNode();
if (loopNode == null) {
throw new RuntimeException("Couldn't locate CompilationUnit for [" + node + "]!");
}
}
}
@Nonnull
public static String getTypeName(@Nonnull Node node) {
List anonymousClasses = newArrayList();
StringBuilder buffy = new StringBuilder();
Node loopNode = node;
for (; ; ) {
if (ObjectCreationExpr.class.isInstance(loopNode)) {
if (!isEmpty(ObjectCreationExpr.class.cast(loopNode).getAnonymousClassBody())) {
anonymousClasses.add(loopNode);
}
} else if (TypeDeclarationStmt.class.isInstance(loopNode)) {
anonymousClasses.add(loopNode);
} else if (TypeDeclaration.class.isInstance(loopNode)
&& !TypeDeclarationStmt.class.isInstance(loopNode.getParentNode())) {
TypeDeclaration typeDeclaration = TypeDeclaration.class.cast(loopNode);
prependSeparatorIfNecessary('$', buffy).insert(0, typeDeclaration.getName());
appendAnonymousClasses(anonymousClasses, typeDeclaration, buffy);
} else if (CompilationUnit.class.isInstance(loopNode)) {
if (buffy.length() == 0) {
buffy.append("package-info");
}
final CompilationUnit compilationUnit = CompilationUnit.class.cast(loopNode);
if (compilationUnit.getPackage() != null) {
prepend(compilationUnit.getPackage().getName(), buffy);
}
}
loopNode = loopNode.getParentNode();
if (loopNode == null) {
return buffy.toString();
}
}
}
private static void appendAnonymousClasses(@Nonnull final List anonymousClasses,
@Nonnull TypeDeclaration typeDeclaration,
@Nonnull final StringBuilder buffy) {
if (anonymousClasses.isEmpty()) {
return;
}
Boolean typeResolved = typeDeclaration.accept(new FixedGenericVisitorAdapter() {
private Deque indexOfAnonymousClasses = newLinkedList();
private Deque indexOfNamedAnonymousClasses = newLinkedList();
private int indexOfNodeToFind = anonymousClasses.size() - 1;
@Override
public Boolean visit(ObjectCreationExpr node, Void arg) {
if (isEmpty(node.getAnonymousClassBody())) {
return super.visit(node, arg);
}
int currentIndex = indexOfAnonymousClasses.removeLast() + 1;
indexOfAnonymousClasses.addLast(currentIndex);
if (anonymousClasses.get(indexOfNodeToFind) == node) {
buffy.append('$').append(indexOfAnonymousClasses.getLast());
if (indexOfNodeToFind-- == 0) {
return Boolean.TRUE;
}
}
indexOfAnonymousClasses.addLast(0);
indexOfNamedAnonymousClasses.addLast(0);
try {
return super.visit(node, null);
} finally {
indexOfAnonymousClasses.removeLast();
indexOfNamedAnonymousClasses.removeLast();
}
}
@Override
public Boolean visit(TypeDeclarationStmt node, Void arg) {
int currentIndex = indexOfNamedAnonymousClasses.removeLast() + 1;
indexOfNamedAnonymousClasses.addLast(currentIndex);
if (anonymousClasses.get(indexOfNodeToFind) == node) {
buffy.append('$').append(indexOfNamedAnonymousClasses.getLast()).append(node.getTypeDeclaration().getName());
if (indexOfNodeToFind-- == 0) {
return Boolean.TRUE;
}
}
indexOfAnonymousClasses.addLast(0);
indexOfNamedAnonymousClasses.addLast(0);
try {
return super.visit(node, null);
} finally {
indexOfAnonymousClasses.removeLast();
indexOfNamedAnonymousClasses.removeLast();
}
}
@Override
public Boolean visit(ClassOrInterfaceDeclaration n, Void arg) {
indexOfAnonymousClasses.addLast(0);
indexOfNamedAnonymousClasses.addLast(0);
try {
return super.visit(n, null);
} finally {
indexOfAnonymousClasses.removeLast();
indexOfNamedAnonymousClasses.removeLast();
}
}
@Override
public Boolean visit(EnumDeclaration n, Void arg) {
indexOfAnonymousClasses.addLast(0);
indexOfNamedAnonymousClasses.addLast(0);
try {
return super.visit(n, null);
} finally {
indexOfAnonymousClasses.removeLast();
indexOfNamedAnonymousClasses.removeLast();
}
}
}, null);
assert typeResolved : "Failed to locate anonymous class definition!";
anonymousClasses.clear();
}
@Nonnull
public static StringBuilder prepend(@Nonnull NameExpr nameExpr, @Nonnull StringBuilder buffy) {
for (; ; ) {
prependSeparatorIfNecessary('.', buffy).insert(0, nameExpr.getName());
if (!QualifiedNameExpr.class.isInstance(nameExpr)) {
return buffy;
}
nameExpr = QualifiedNameExpr.class.cast(nameExpr).getQualifier();
}
}
@Nonnull
public static StringBuilder prependSeparatorIfNecessary(char character, @Nonnull StringBuilder buffy) {
if (buffy.length() > 0) {
buffy.insert(0, character);
}
return buffy;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy