use of org.objectweb.asm.ClassVisitor in project android_frameworks_base by AOSPA.
the class AsmGenerator method transform.
/**
* Transforms a class.
* <p/>
* There are 3 kind of transformations:
*
* 1- For "mock" dependencies classes, we want to remove all code from methods and replace
* by a stub. Native methods must be implemented with this stub too. Abstract methods are
* left intact. Modified classes must be overridable (non-private, non-final).
* Native methods must be made non-final, non-private.
*
* 2- For "keep" classes, we want to rewrite all native methods as indicated above.
* If a class has native methods, it must also be made non-private, non-final.
*
* Note that unfortunately static methods cannot be changed to non-static (since static and
* non-static are invoked differently.)
*/
byte[] transform(ClassReader cr, boolean stubNativesOnly) {
boolean hasNativeMethods = hasNativeMethods(cr);
// Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
String className = cr.getClassName();
String newName = transformName(className);
// transformName returns its input argument if there's no need to rename the class
if (!newName.equals(className)) {
mRenameCount++;
// This class is being renamed, so remove it from the list of classes not renamed.
mClassesNotRenamed.remove(className);
}
mLog.debug("Transform %s%s%s%s", className, newName.equals(className) ? "" : " (renamed to " + newName + ")", hasNativeMethods ? " -- has natives" : "", stubNativesOnly ? " -- stub natives only" : "");
// Rewrite the new class from scratch, without reusing the constant pool from the
// original class reader.
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor cv = cw;
// FIXME Generify
if ("android/content/res/Resources".equals(className)) {
cv = new FieldInjectorAdapter(cv);
}
if (mReplaceMethodCallsClasses.contains(className)) {
cv = new ReplaceMethodCallsAdapter(cv, className);
}
cv = new RefactorClassAdapter(cv, mRefactorClasses);
if (!newName.equals(className)) {
cv = new RenameClassAdapter(cv, className, newName);
}
String binaryNewName = newName.replace('/', '.');
if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
}
cv = new TransformClassAdapter(mLog, mStubMethods, mDeleteReturns.get(className), newName, cv, stubNativesOnly);
Set<String> delegateMethods = mDelegateMethods.get(className);
if (delegateMethods != null && !delegateMethods.isEmpty()) {
// known to have no native methods, just skip this step.
if (hasNativeMethods || !(delegateMethods.size() == 1 && delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
}
}
Set<String> promoteFields = mPromotedFields.get(className);
if (promoteFields != null && !promoteFields.isEmpty()) {
cv = new PromoteFieldClassAdapter(cv, promoteFields);
}
cr.accept(cv, 0);
return cw.toByteArray();
}
use of org.objectweb.asm.ClassVisitor in project android_frameworks_base by ResurrectionRemix.
the class AsmGenerator method transform.
/**
* Transforms a class.
* <p/>
* There are 3 kind of transformations:
*
* 1- For "mock" dependencies classes, we want to remove all code from methods and replace
* by a stub. Native methods must be implemented with this stub too. Abstract methods are
* left intact. Modified classes must be overridable (non-private, non-final).
* Native methods must be made non-final, non-private.
*
* 2- For "keep" classes, we want to rewrite all native methods as indicated above.
* If a class has native methods, it must also be made non-private, non-final.
*
* Note that unfortunately static methods cannot be changed to non-static (since static and
* non-static are invoked differently.)
*/
byte[] transform(ClassReader cr, boolean stubNativesOnly) {
boolean hasNativeMethods = hasNativeMethods(cr);
// Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
String className = cr.getClassName();
String newName = transformName(className);
// transformName returns its input argument if there's no need to rename the class
if (!newName.equals(className)) {
mRenameCount++;
// This class is being renamed, so remove it from the list of classes not renamed.
mClassesNotRenamed.remove(className);
}
mLog.debug("Transform %s%s%s%s", className, newName.equals(className) ? "" : " (renamed to " + newName + ")", hasNativeMethods ? " -- has natives" : "", stubNativesOnly ? " -- stub natives only" : "");
// Rewrite the new class from scratch, without reusing the constant pool from the
// original class reader.
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor cv = cw;
// FIXME Generify
if ("android/content/res/Resources".equals(className)) {
cv = new FieldInjectorAdapter(cv);
}
if (mReplaceMethodCallsClasses.contains(className)) {
cv = new ReplaceMethodCallsAdapter(cv, className);
}
cv = new RefactorClassAdapter(cv, mRefactorClasses);
if (!newName.equals(className)) {
cv = new RenameClassAdapter(cv, className, newName);
}
String binaryNewName = newName.replace('/', '.');
if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
}
cv = new TransformClassAdapter(mLog, mStubMethods, mDeleteReturns.get(className), newName, cv, stubNativesOnly);
Set<String> delegateMethods = mDelegateMethods.get(className);
if (delegateMethods != null && !delegateMethods.isEmpty()) {
// known to have no native methods, just skip this step.
if (hasNativeMethods || !(delegateMethods.size() == 1 && delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
}
}
Set<String> promoteFields = mPromotedFields.get(className);
if (promoteFields != null && !promoteFields.isEmpty()) {
cv = new PromoteFieldClassAdapter(cv, promoteFields);
}
cr.accept(cv, 0);
return cw.toByteArray();
}
use of org.objectweb.asm.ClassVisitor in project CodeChickenLib by Chicken-Bones.
the class ASMHelper method dump.
public static void dump(Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals, boolean textify) {
try {
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (!file.exists())
file.createNewFile();
PrintWriter pout = new PrintWriter(file);
ClassVisitor cv = new TraceClassVisitor(null, textify ? new Textifier() : new ASMifier(), pout);
if (filterImportant)
cv = new ImportantInsnVisitor(cv);
if (sortLocals)
cv = new LocalVariablesSorterVisitor(cv);
acceptor.accept(cv);
pout.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of org.objectweb.asm.ClassVisitor in project aries by apache.
the class ProxySubclassGenerator method generateAndLoadSubclass.
private static Class<?> generateAndLoadSubclass(Class<?> aClass, ClassLoader loader) throws UnableToProxyException {
LOGGER.debug(Constants.LOG_ENTRY, "generateAndLoadSubclass", new Object[] { aClass, loader });
// set the newClassName
String newClassName = "$" + aClass.getSimpleName() + aClass.hashCode();
String packageName = aClass.getPackage().getName();
if (packageName.startsWith("java.") || packageName.startsWith("javax.")) {
packageName = "org.apache.aries.blueprint.proxy." + packageName;
}
String fullNewClassName = (packageName + "." + newClassName).replaceAll("\\.", "/");
LOGGER.debug("New class name: {}", newClassName);
LOGGER.debug("Full new class name: {}", fullNewClassName);
Class<?> clazz = null;
try {
ClassReader cReader = new ClassReader(loader.getResourceAsStream(aClass.getName().replaceAll("\\.", "/") + ".class"));
ClassWriter cWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor dynamicSubclassAdapter = new ProxySubclassAdapter(cWriter, fullNewClassName, loader);
byte[] byteClassData = processClass(cReader, cWriter, dynamicSubclassAdapter);
clazz = loadClassFromBytes(loader, getBinaryName(fullNewClassName), byteClassData, aClass.getName());
} catch (IOException ioe) {
LOGGER.debug(Constants.LOG_EXCEPTION, ioe);
throw new ProxyClassBytecodeGenerationException(aClass.getName(), ioe);
} catch (TypeNotPresentException tnpe) {
LOGGER.debug(Constants.LOG_EXCEPTION, tnpe);
throw new ProxyClassBytecodeGenerationException(tnpe.typeName(), tnpe.getCause());
}
LOGGER.debug(Constants.LOG_EXIT, "generateAndLoadSubclass", clazz);
return clazz;
}
use of org.objectweb.asm.ClassVisitor in project aries by apache.
the class Synthesizer method main.
/**
* This is the main method for running the Synthesizer
*
* @param args - String[] of file paths to class files
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//add the synthetic modifier for each of the supplied args
for (String arg : args) {
FileInputStream classInStream = null;
ClassWriter writer = null;
try {
//read in the class
classInStream = new FileInputStream(arg);
ClassReader reader = new ClassReader(classInStream);
//make a ClassWriter constructed with the reader for speed
//since we are mostly just copying
//we just need to override the visit method so we can add
//the synthetic modifier, otherwise we use the methods in
//a standard writer
writer = new ClassWriter(reader, 0);
ClassVisitor cv = new CustomClassVisitor((ClassVisitor) writer);
//call accept on the reader to start the visits
//using the writer we created as the visitor
reader.accept(cv, 0);
} finally {
if (classInStream != null)
classInStream.close();
}
FileOutputStream classOutStream = null;
try {
//write out the new bytes of the class file
classOutStream = new FileOutputStream(arg);
if (writer != null)
classOutStream.write(writer.toByteArray());
} finally {
//close the OutputStream if it is still around
if (classOutStream != null)
classOutStream.close();
}
}
}
Aggregations