proguard.classfile.util.renderer.ClassViewModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of proguard-core Show documentation
Show all versions of proguard-core Show documentation
ProGuardCORE is a free library to read, analyze, modify, and write Java class files.
package proguard.classfile.util.renderer;
import java.util.ArrayList;
import java.util.List;
import proguard.classfile.AccessConstants;
import proguard.classfile.Clazz;
import proguard.classfile.Field;
import proguard.classfile.LibraryClass;
import proguard.classfile.LibraryField;
import proguard.classfile.LibraryMethod;
import proguard.classfile.Method;
import proguard.classfile.ProgramClass;
import proguard.classfile.ProgramField;
import proguard.classfile.ProgramMethod;
import proguard.classfile.constant.Constant;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.ClassUtil;
import proguard.classfile.visitor.ClassVisitor;
import proguard.classfile.visitor.MemberVisitor;
import proguard.util.ProcessingFlags;
/**
* This utility class renders {@link Clazz} objects into a more human-readable format. It can be
* used as a Java type renderer in Intellij-based IDE to support debugging.
*
* @author Kymeng Tang
*/
public class ClassViewModel extends ProcessableViewModel {
private Clazz model;
private ClassViewModel parent;
private ClassViewModel[] interfaces;
private ConstantViewModel[] constantPool;
private FieldViewModel[] fields;
private MethodViewModel[] methods;
/**
* Renders {@link Clazz} object into an abstract representation that hides the low-level Jvm class
* data structure. The processing flags rendering are limited to those declared in {@link
* ProcessingFlags}.
*
* @param clazz The {@link Clazz} object to be rendered.
* @return A high-level representation of {@link Clazz} (i.e., {@link ClassViewModel} object).
*/
public static ClassViewModel render(Clazz clazz) {
ClassViewModel viewModel = new ClassViewModel(clazz);
viewModel.parent = renderSuperClass(clazz);
viewModel.interfaces = renderInterfaces(clazz);
viewModel.constantPool = renderConstantPool(clazz);
viewModel.fields = renderFields(clazz);
viewModel.methods = renderMethods(clazz);
viewModel.processingFlags = renderProcessingFlags(clazz.getProcessingFlags());
viewModel.processingInfo = clazz.getProcessingInfo();
return viewModel;
}
/**
* Renders {@link Clazz} object into an abstract representation that hides the low-level Jvm class
* data structure; additional processing flags declared in a subclass of {@link ProcessingFlags}
* will also be rendered.
*
* @param clazz The {@link Clazz} object to be rendered.
* @param processingFlagsHolder A subclass of {@link ProcessingFlags} that holds additional
* processing flags.
* @return A high-level representation of {@link Clazz} (i.e., {@link ClassViewModel} object).
*/
public static ClassViewModel render(
Clazz clazz, Class processingFlagsHolder) {
addExtraProcessingFlags(processingFlagsHolder);
return render(clazz);
}
/**
* Private constructor for the {@link ClassViewModel}. The rendering of the {@link Clazz} object
* should be done with ClassViewModel.render(clazz:Clazz) or ClassViewModel.render(clazz:Clazz,
* processingFlagsHolder:Class).
*
* @param clazz {@link Class} object to be rendered.
*/
private ClassViewModel(Clazz clazz) {
this.model = clazz;
}
/**
* A utility method that renders a {@link Clazz} object into a string containing class name, type,
* accessibility. (e.g., "public static class Foo").
*
* @param model {@link Clazz} object to be rendered.
* @return A string previewing the class signature.
*/
public static String renderPreview(Clazz model) {
return ClassUtil.externalClassAccessFlags(model.getAccessFlags())
+ ((model.getAccessFlags() & AccessConstants.INTERFACE) == 0 ? "class " : "")
+ model.getName();
}
/**
* A utility method for recursively rendering {@link Clazz} objects in the hierarchy.
*
* @param model A {@link Clazz} object whose parent needs to be rendered.
* @return A high-level representation of the parent {@link Clazz}.
*/
public static ClassViewModel renderSuperClass(Clazz model) {
return model.getSuperClass() != null ? new ClassViewModel(model.getSuperClass()) : null;
}
/**
* A utility method for recursively rendering interfaces of an implementing {@link Clazz}.
*
* @param model A {@link Clazz} object whose interfaces need to be rendered.
* @return An array of high-level representation of the implemented interfaces.
*/
public static ClassViewModel[] renderInterfaces(Clazz model) {
List interfaces = new ArrayList<>();
model.hierarchyAccept(
false,
false,
true,
false,
new ClassVisitor() {
public void visitAnyClass(Clazz clazz) {
interfaces.add(new ClassViewModel(clazz));
}
});
return interfaces.toArray(new ClassViewModel[interfaces.size()]);
}
/**
* A utility method for rendering each constant pool entry into a higher-level representation. see
* {@link ConstantViewModel}.
*
* @param model A {@link Clazz} object whose constant pool needs to be rendered.
* @return An array of high-level representation of the constant pool entries.
*/
public static ConstantViewModel[] renderConstantPool(Clazz model) {
List constantList = new ArrayList<>();
constantList.add(null);
model.constantPoolEntriesAccept(
new ConstantVisitor() {
public void visitAnyConstant(Clazz clazz, Constant constant) {
constantList.add(new ConstantViewModel(clazz, constant));
}
});
return constantList.toArray(new ConstantViewModel[constantList.size()]);
}
/**
* A utility method for rendering each {@link Field} into a higher-level representation. see
* {@link FieldViewModel}.
*
* @param model A {@link Clazz} object whose fields need to be rendered.
* @return An array of high-level representation of the class' fields.
*/
public static FieldViewModel[] renderFields(Clazz model) {
List fields = new ArrayList<>();
model.fieldsAccept(
new MemberVisitor() {
private void visitAnyField(Clazz clazz, Field field) {
fields.add(FieldViewModel.render(clazz, field));
}
public void visitProgramField(ProgramClass programClass, ProgramField programField) {
visitAnyField(programClass, programField);
}
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) {
visitAnyField(libraryClass, libraryField);
}
});
return fields.toArray(new FieldViewModel[fields.size()]);
}
/**
* A utility method for rendering each {@link Method} into a higher-level representation. see
* {@link MethodViewModel}.
*
* @param model A {@link Clazz} object whose methods need to be rendered.
* @return An array of high-level representation of the class' methods.
*/
public static MethodViewModel[] renderMethods(Clazz model) {
List methods = new ArrayList<>();
model.methodsAccept(
new MemberVisitor() {
private void visitAnyMethod(Clazz clazz, Method method) {
MethodViewModel methodViewModel = MethodViewModel.render(clazz, method);
methods.add(methodViewModel);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) {
this.visitAnyMethod(programClass, programMethod);
}
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) {
this.visitAnyMethod(libraryClass, libraryMethod);
}
});
return methods.toArray(new MethodViewModel[methods.size()]);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy