use of org.objectweb.asm.AnnotationVisitor in project groovy-core by groovy.
the class AsmClassGenerator method visitAnnotationDefault.
private void visitAnnotationDefault(MethodNode node, MethodVisitor mv) {
if (!node.hasAnnotationDefault())
return;
Expression exp = ((ReturnStatement) node.getCode()).getExpression();
AnnotationVisitor av = mv.visitAnnotationDefault();
visitAnnotationDefaultExpression(av, node.getReturnType(), exp);
}
use of org.objectweb.asm.AnnotationVisitor in project gradle by gradle.
the class ApiMemberSelector method visitAnnotationMembers.
private void visitAnnotationMembers(FieldVisitor fv, Set<AnnotationMember> annotationMembers) {
for (AnnotationMember annotation : annotationMembers) {
AnnotationVisitor annotationVisitor = fv.visitAnnotation(annotation.getName(), annotation.isVisible());
visitAnnotationValues(annotation, annotationVisitor);
}
}
use of org.objectweb.asm.AnnotationVisitor in project groovy-core by groovy.
the class AsmClassGenerator method visitAnnotationAttributes.
/**
* Generate the annotation attributes.
* @param an the node with an annotation
* @param av the visitor to use
*/
private void visitAnnotationAttributes(AnnotationNode an, AnnotationVisitor av) {
Map<String, Object> constantAttrs = new HashMap<String, Object>();
Map<String, PropertyExpression> enumAttrs = new HashMap<String, PropertyExpression>();
Map<String, Object> atAttrs = new HashMap<String, Object>();
Map<String, ListExpression> arrayAttrs = new HashMap<String, ListExpression>();
for (String name : an.getMembers().keySet()) {
Expression expr = an.getMember(name);
if (expr instanceof AnnotationConstantExpression) {
atAttrs.put(name, ((AnnotationConstantExpression) expr).getValue());
} else if (expr instanceof ConstantExpression) {
constantAttrs.put(name, ((ConstantExpression) expr).getValue());
} else if (expr instanceof ClassExpression) {
constantAttrs.put(name, Type.getType(BytecodeHelper.getTypeDescription((expr.getType()))));
} else if (expr instanceof PropertyExpression) {
enumAttrs.put(name, (PropertyExpression) expr);
} else if (expr instanceof ListExpression) {
arrayAttrs.put(name, (ListExpression) expr);
} else if (expr instanceof ClosureExpression) {
ClassNode closureClass = controller.getClosureWriter().getOrAddClosureClass((ClosureExpression) expr, ACC_PUBLIC);
constantAttrs.put(name, Type.getType(BytecodeHelper.getTypeDescription(closureClass)));
}
}
for (Map.Entry entry : constantAttrs.entrySet()) {
av.visit((String) entry.getKey(), entry.getValue());
}
for (Map.Entry entry : enumAttrs.entrySet()) {
PropertyExpression propExp = (PropertyExpression) entry.getValue();
av.visitEnum((String) entry.getKey(), BytecodeHelper.getTypeDescription(propExp.getObjectExpression().getType()), String.valueOf(((ConstantExpression) propExp.getProperty()).getValue()));
}
for (Map.Entry entry : atAttrs.entrySet()) {
AnnotationNode atNode = (AnnotationNode) entry.getValue();
AnnotationVisitor av2 = av.visitAnnotation((String) entry.getKey(), BytecodeHelper.getTypeDescription(atNode.getClassNode()));
visitAnnotationAttributes(atNode, av2);
av2.visitEnd();
}
visitArrayAttributes(an, arrayAttrs, av);
}
use of org.objectweb.asm.AnnotationVisitor in project groovy-core by groovy.
the class AsmClassGenerator method visitClass.
// GroovyClassVisitor interface
//-------------------------------------------------------------------------
public void visitClass(ClassNode classNode) {
referencedClasses.clear();
WriterControllerFactory factory = (WriterControllerFactory) classNode.getNodeMetaData(WriterControllerFactory.class);
WriterController normalController = new WriterController();
if (factory != null) {
this.controller = factory.makeController(normalController);
} else {
this.controller = normalController;
}
this.controller.init(this, context, cv, classNode);
if (controller.shouldOptimizeForInt() || factory != null) {
OptimizingStatementWriter.setNodeMeta(controller.getTypeChooser(), classNode);
}
try {
cv.visit(controller.getBytecodeVersion(), adjustedClassModifiersForClassWriting(classNode), controller.getInternalClassName(), BytecodeHelper.getGenericsSignature(classNode), controller.getInternalBaseClassName(), BytecodeHelper.getClassInternalNames(classNode.getInterfaces()));
cv.visitSource(sourceFile, null);
if (classNode instanceof InnerClassNode) {
InnerClassNode innerClass = (InnerClassNode) classNode;
MethodNode enclosingMethod = innerClass.getEnclosingMethod();
if (enclosingMethod != null) {
String outerClassName = BytecodeHelper.getClassInternalName(innerClass.getOuterClass().getName());
cv.visitOuterClass(outerClassName, enclosingMethod.getName(), BytecodeHelper.getMethodDescriptor(enclosingMethod));
}
}
if (classNode.getName().endsWith("package-info")) {
PackageNode packageNode = classNode.getPackage();
if (packageNode != null) {
// pull them out of package node but treat them like they were on class node
for (AnnotationNode an : packageNode.getAnnotations()) {
// skip built-in properties
if (an.isBuiltIn())
continue;
if (an.hasSourceRetention())
continue;
AnnotationVisitor av = getAnnotationVisitor(classNode, an, cv);
visitAnnotationAttributes(an, av);
av.visitEnd();
}
}
cv.visitEnd();
return;
} else {
visitAnnotations(classNode, cv);
}
if (classNode.isInterface()) {
ClassNode owner = classNode;
if (owner instanceof InnerClassNode) {
owner = owner.getOuterClass();
}
String outerClassName = classNode.getName();
String name = outerClassName + "$" + context.getNextInnerClassIdx();
controller.setInterfaceClassLoadingClass(new InterfaceHelperClassNode(owner, name, 4128, ClassHelper.OBJECT_TYPE, controller.getCallSiteWriter().getCallSites()));
super.visitClass(classNode);
createInterfaceSyntheticStaticFields();
} else {
super.visitClass(classNode);
MopWriter.Factory mopWriterFactory = classNode.getNodeMetaData(MopWriter.Factory.class);
if (mopWriterFactory == null) {
mopWriterFactory = MopWriter.FACTORY;
}
MopWriter mopWriter = mopWriterFactory.create(controller);
mopWriter.createMopMethods();
controller.getCallSiteWriter().generateCallSiteArray();
createSyntheticStaticFields();
}
// GROOVY-6750 and GROOVY-6808
for (Iterator<InnerClassNode> iter = classNode.getInnerClasses(); iter.hasNext(); ) {
InnerClassNode innerClass = iter.next();
makeInnerClassEntry(innerClass);
}
makeInnerClassEntry(classNode);
cv.visitEnd();
} catch (GroovyRuntimeException e) {
e.setModule(classNode.getModule());
throw e;
} catch (NegativeArraySizeException nase) {
throw new GroovyRuntimeException("NegativeArraySizeException while processing " + sourceFile, nase);
} catch (NullPointerException npe) {
throw new GroovyRuntimeException("NPE while processing " + sourceFile, npe);
}
}
use of org.objectweb.asm.AnnotationVisitor in project android_frameworks_base by ResurrectionRemix.
the class DelegateMethodAdapter method generateDelegateCode.
/**
* Generates the new code for the method.
* <p/>
* For native methods, this must be invoked directly by {@link DelegateClassAdapter}
* (since they have no code to visit).
* <p/>
* Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
* return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
* invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
* this method will be invoked from {@link MethodVisitor#visitEnd()}.
*/
public void generateDelegateCode() {
/*
* The goal is to generate a call to a static delegate method.
* If this method is non-static, the first parameter will be 'this'.
* All the parameters must be passed and then the eventual return type returned.
*
* Example, let's say we have a method such as
* public void myMethod(int a, Object b, ArrayList<String> c) { ... }
*
* We'll want to create a body that calls a delegate method like this:
* TheClass_Delegate.myMethod(this, a, b, c);
*
* If the method is non-static and the class name is an inner class (e.g. has $ in its
* last segment), we want to push the 'this' of the outer class first:
* OuterClass_InnerClass_Delegate.myMethod(
* OuterClass.this,
* OuterClass$InnerClass.this,
* a, b, c);
*
* Only one level of inner class is supported right now, for simplicity and because
* we don't need more.
*
* The generated class name is the current class name with "_Delegate" appended to it.
* One thing to realize is that we don't care about generics -- since generic types
* are erased at build time, they have no influence on the method name being called.
*/
// Add our annotation
AnnotationVisitor aw = mDelWriter.visitAnnotation(Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), // visible at runtime
true);
if (aw != null) {
aw.visitEnd();
}
mDelWriter.visitCode();
if (mDelegateLineNumber != null) {
Object[] p = mDelegateLineNumber;
mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
}
ArrayList<Type> paramTypes = new ArrayList<>();
String delegateClassName = mClassName + DELEGATE_SUFFIX;
boolean pushedArg0 = false;
int maxStack = 0;
// Check if the last segment of the class name has inner an class.
// Right now we only support one level of inner classes.
Type outerType = null;
int slash = mClassName.lastIndexOf('/');
int dol = mClassName.lastIndexOf('$');
if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
String outerClass = mClassName.substring(0, dol);
outerType = Type.getObjectType(outerClass);
// Change a delegate class name to "com/foo/Outer_Inner_Delegate"
delegateClassName = delegateClassName.replace('$', '_');
}
// by the 'this' of any outer class, if any.
if (!mIsStatic) {
if (outerType != null && !mIsStaticInnerClass) {
// The first-level inner class has a package-protected member called 'this$0'
// that points to the outer class.
// Push this.getField("this$0") on the call stack.
// var 0 = this
mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
mDelWriter.visitFieldInsn(Opcodes.GETFIELD, // class where the field is defined
mClassName, // field name
"this$0", // type of the field
outerType.getDescriptor());
maxStack++;
paramTypes.add(outerType);
}
// Push "this" for the instance method, which is always ALOAD 0
mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
maxStack++;
pushedArg0 = true;
paramTypes.add(Type.getObjectType(mClassName));
}
// Push all other arguments. Start at arg 1 if we already pushed 'this' above.
Type[] argTypes = Type.getArgumentTypes(mDesc);
int maxLocals = pushedArg0 ? 1 : 0;
for (Type t : argTypes) {
int size = t.getSize();
mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
maxLocals += size;
maxStack += size;
paramTypes.add(t);
}
// Construct the descriptor of the delegate based on the parameters
// we pushed on the call stack. The return type remains unchanged.
String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc), paramTypes.toArray(new Type[paramTypes.size()]));
// Invoke the static delegate
mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc, false);
Type returnType = Type.getReturnType(mDesc);
mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
mDelWriter.visitMaxs(maxStack, maxLocals);
mDelWriter.visitEnd();
// For debugging now. Maybe we should collect these and store them in
// a text file for helping create the delegates. We could also compare
// the text file to a golden and break the build on unsupported changes
// or regressions. Even better we could fancy-print something that looks
// like the expected Java method declaration.
mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}
Aggregations