package de.is24.deadcode4j.analyzer; import de.is24.deadcode4j.AnalysisContext; import javassist.CtClass; import javassist.Modifier; import javassist.bytecode.AccessFlag; import javassist.bytecode.MethodInfo; import javax.annotation.Nonnull; import static com.google.common.collect.Iterables.filter; /** * Analyzes class files: marks a class as being in use if it defines a main method. * * @since 2.0.0 */ public class MainClassAnalyzer extends ByteCodeAnalyzer { private static boolean isPublicStatic(MethodInfo methodInfo) { int modifier = AccessFlag.toModifier(methodInfo.getAccessFlags()); return Modifier.isPublic(modifier) && Modifier.isStatic(modifier); } private static boolean matchesSignature(MethodInfo methodInfo) { return "([Ljava/lang/String;)V".equals(methodInfo.getDescriptor()); } @Override protected void analyzeClass(@Nonnull AnalysisContext analysisContext, @Nonnull CtClass clazz) { String clazzName = clazz.getName(); analysisContext.addAnalyzedClass(clazzName); for (MethodInfo methodInfo : filter(clazz.getClassFile2().getMethods(), MethodInfo.class)) { if (methodInfo.isMethod() && isPublicStatic(methodInfo) && "main".equals(methodInfo.getName()) && matchesSignature(methodInfo)) { analysisContext.addDependencies("_Main-Class_", clazz.getName()); } } } }