List of usage examples for org.objectweb.asm ClassVisitor visitInnerClass
public void visitInnerClass(final String name, final String outerName, final String innerName, final int access)
From source file:com.facebook.buck.jvm.java.abi.InnerClassesTable.java
License:Apache License
public void reportInnerClassReferences(Element topElement, ClassVisitor visitor) { List<TypeElement> enclosingClasses = new ArrayList<>(); List<TypeElement> memberClasses = new ArrayList<>(); Set<TypeElement> referencesToInners = new HashSet<>(); ElementKind elementKind = topElement.getKind(); if (elementKind.isClass() || elementKind.isInterface()) { TypeElement walker = (TypeElement) topElement; while (walker.getNestingKind() == NestingKind.MEMBER) { enclosingClasses.add(walker); walker = (TypeElement) walker.getEnclosingElement(); }/*from w ww .j a va 2 s .c o m*/ } ElementScanner8<Void, Void> elementScanner = new ElementScanner8<Void, Void>() { @Override public Void visitPackage(PackageElement e, Void aVoid) { addTypeReferences(e.getAnnotationMirrors()); // If we're being asked to report inner class references of a package, it really means // we're being asked to report inner class references of package-info.java; i.e., just // the package annotations. We therefore return without chaining to super to avoid // recursing into enclosed elements. return null; } @Override public Void visitType(TypeElement e, Void aVoid) { if (e != topElement && !memberClasses.contains(e)) { memberClasses.add(e); return null; } addTypeReferences(e.getAnnotationMirrors()); e.getTypeParameters().forEach(typeParam -> scan(typeParam, aVoid)); addTypeReferences(e.getSuperclass()); e.getInterfaces().forEach(this::addTypeReferences); // Members will be visited in the call to super, below return super.visitType(e, aVoid); } @Override public Void visitExecutable(ExecutableElement e, Void aVoid) { addTypeReferences(e.getAnnotationMirrors()); e.getTypeParameters().forEach(typeParam -> scan(typeParam, aVoid)); addTypeReferences(e.getReturnType()); addTypeReferences(e.getDefaultValue()); // Parameters will be visited in the call to super, below e.getThrownTypes().forEach(this::addTypeReferences); return super.visitExecutable(e, aVoid); } @Override public Void visitVariable(VariableElement e, Void aVoid) { addTypeReferences(e.getAnnotationMirrors()); addTypeReferences(e.asType()); return super.visitVariable(e, aVoid); } @Override public Void visitTypeParameter(TypeParameterElement e, Void aVoid) { addTypeReferences(e.getAnnotationMirrors()); addTypeReferences(e.asType()); return super.visitTypeParameter(e, aVoid); } private void addTypeReferences(TypeMirror type) { new TypeScanner8<Void, Void>() { @Override public Void scan(@Nullable TypeMirror t, Void aVoid) { if (t == null) { return null; } return super.scan(t, aVoid); } @Override public Void visitDeclared(DeclaredType t, Void aVoid) { TypeElement element = (TypeElement) t.asElement(); if (element.getNestingKind() == NestingKind.MEMBER) { referencesToInners.add(element); element.getEnclosingElement().asType().accept(this, null); } return super.visitDeclared(t, aVoid); } }.scan(type); } private void addTypeReferences(List<? extends AnnotationMirror> annotationMirrors) { annotationMirrors.forEach(this::addTypeReferences); } private void addTypeReferences(AnnotationMirror annotationMirror) { addTypeReferences(annotationMirror.getAnnotationType()); annotationMirror.getElementValues().values().forEach(this::addTypeReferences); } private void addTypeReferences(@Nullable AnnotationValue annotationValue) { if (annotationValue == null) { return; } new AnnotationValueScanner8<Void, Void>() { @Override public Void visitType(TypeMirror t, Void aVoid) { addTypeReferences(t); return super.visitType(t, aVoid); } @Override public Void visitEnumConstant(VariableElement c, Void aVoid) { addTypeReferences(c.asType()); return super.visitEnumConstant(c, aVoid); } @Override public Void visitAnnotation(AnnotationMirror a, Void aVoid) { addTypeReferences(a.getAnnotationType()); return super.visitAnnotation(a, aVoid); } }.scan(annotationValue); } }; elementScanner.scan(topElement); Set<TypeElement> reported = new HashSet<>(); for (TypeElement element : Lists.reverse(enclosingClasses)) { if (reported.add(element)) { visitor.visitInnerClass(descriptorFactory.getInternalName(element), descriptorFactory.getInternalName((TypeElement) element.getEnclosingElement()), element.getSimpleName().toString(), accessFlagsUtils.getAccessFlags(element) & ~Opcodes.ACC_SUPER); } } for (TypeElement element : Lists.reverse(memberClasses)) { if (reported.add(element)) { visitor.visitInnerClass(descriptorFactory.getInternalName(element), descriptorFactory.getInternalName((TypeElement) element.getEnclosingElement()), element.getSimpleName().toString(), accessFlagsUtils.getAccessFlags(element) & ~Opcodes.ACC_SUPER); } } referencesToInners.stream().filter(reported::add) .sorted(Comparator.comparing(e -> e.getQualifiedName().toString())).forEach(element -> { visitor.visitInnerClass(descriptorFactory.getInternalName(element), descriptorFactory.getInternalName((TypeElement) element.getEnclosingElement()), element.getSimpleName().toString(), accessFlagsUtils.getAccessFlags(element) & ~Opcodes.ACC_SUPER); }); }
From source file:com.google.code.jconts.instrument.gen.ComputationClassGenerator.java
License:Apache License
public void accept(TransformationContext context) { ClassVisitor cv = context.writer(); // extends Object implements Computation<ValueType> SignatureWriter sign = new SignatureWriter(); SignatureVisitor supsign = sign.visitSuperclass(); supsign.visitClassType(OBJECT_NAME); supsign.visitEnd();//from www . j av a2 s. c om SignatureVisitor iface = sign.visitInterface(); iface.visitClassType(COMPUTATION_NAME); SignatureVisitor argsign = iface.visitTypeArgument('='); new SignatureReader(info.valueSignature).acceptType(argsign); argsign.visitEnd(); cv.visit(Opcodes.V1_6, Opcodes.ACC_FINAL, info.computationClassName, sign.toString(), OBJECT_NAME, new String[] { COMPUTATION_NAME }); cv.visitSource(info.ownerSource, null); cv.visitInnerClass(info.stateClassName, info.owner, info.stateSimpleName, 0); cv.visitInnerClass(info.computationClassName, info.owner, info.computationSimpleName, 0); cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "state", stateDesc, null, null); generateConstructor(cv); generateExecute(cv); cv.visitEnd(); }
From source file:com.google.code.jconts.instrument.gen.ContinuationClassGenerator.java
License:Apache License
public void accept(TransformationContext context) { ClassVisitor cv = context.writer(); cv.visit(Opcodes.V1_6, Opcodes.ACC_FINAL, info.continuationClassName, signature, OBJECT_NAME, new String[] { CONTINUATION_NAME }); cv.visitSource(info.ownerSource, null); cv.visitInnerClass(info.stateClassName, info.owner, info.stateSimpleName, 0); cv.visitInnerClass(info.continuationClassName, info.owner, info.continuationSimpleName, 0); cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "state", stateDesc, null, null); cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "index", "I", null, null); generateConstructor(cv);/*from www . j av a2 s . c o m*/ generateExecute(cv, true); generateExecute(cv, false); cv.visitEnd(); }
From source file:com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.java
License:Apache License
public byte[] writeJsoIntf(final String className, byte classBytes[]) { String desc = toDescriptor(className); assert (jsoIntfDescs.contains(desc)); assert (jsoSuperDescs.containsKey(desc)); List<String> superDescs = jsoSuperDescs.get(desc); assert (superDescs != null); assert (superDescs.size() > 0); // The ASM model is to chain a bunch of visitors together. ClassWriter writer = new ClassWriter(0); final ClassVisitor v = writer; // v = new CheckClassAdapter(v); // v = new TraceClassVisitor(v, new PrintWriter(System.out)); String[] interfaces;/* ww w .j ava2s . c o m*/ // TODO(bov): something better than linear? if (superDescs.contains("java/lang/Object")) { interfaces = null; } else { interfaces = superDescs.toArray(new String[superDescs.size()]); } v.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC | Opcodes.ACC_INTERFACE, desc, null, "java/lang/Object", interfaces); if (classBytes != null) { // Java7 enforces innerclass/outerclass consistency. In order to fix this, copy from original ClassVisitor cv = new EmptyVisitor() { @Override public void visitInnerClass(String name, String outerName, String innerName, int access) { // copy inner class table from original JSO to synthetic interface v.visitInnerClass(name, outerName, innerName, access); } @Override public void visitOuterClass(String owner, String name, String desc) { // copy outer class table from original JSO to synthetic interface v.visitOuterClass(owner, name, desc); } }; new ClassReader(classBytes).accept(cv, 0); } v.visitEnd(); return writer.toByteArray(); }
From source file:com.google.template.soy.jbcsrc.InnerClasses.java
License:Apache License
private void doRegister(ClassVisitor visitor, TypeInfo innerClass) { visitor.visitInnerClass(innerClass.internalName(), outer.internalName(), innerClass.simpleName(), innerClassesAccessModifiers.get(innerClass)); }
From source file:com.googlecode.ddom.weaver.asm.ClassVisitorTee.java
License:Apache License
public void visitInnerClass(String name, String outerName, String innerName, int access) { for (ClassVisitor visitor : visitors) { visitor.visitInnerClass(name, outerName, innerName, access); }/* w ww.j a v a 2s .co m*/ }
From source file:org.adjective.stout.writer.ByteCodeWriter.java
License:Apache License
public byte[] write(ClassDescriptor cls) { begin(cls);/*from ww w . jav a 2s . c o m*/ ClassWriter writer = createClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor cv = writer; if (_trace) { cv = new TraceClassVisitor(cv, new PrintWriter(System.err)); } if (_check) { cv = new CheckClassAdapter(cv); } String signature = null; // @TODO cv.visit(Opcodes.V1_5, getModifierCode(cls.getModifiers(), cls.getSort()), cls.getInternalName(), signature, getInternalName(cls.getSuperClass()), getInterfaceNames(cls)); if (cls.getSourceFile() != null) { cv.visitSource(cls.getSourceFile(), ""); } UnresolvedType outer = cls.getOuterClass(); if (outer != null) { cv.visitOuterClass(outer.getInternalName(), null, null); } for (AnnotationDescriptor annotation : cls.getAnnotations()) { writeAnnotation(cv, annotation); } for (ClassDescriptor inner : cls.getInnerClasses()) { String name = inner.getInternalName(); String simpleName = name.substring(name.lastIndexOf('/') + 1); cv.visitInnerClass(name, cls.getInternalName(), simpleName, getModifierCode(inner.getModifiers(), inner.getSort())); } for (FieldDescriptor field : cls.getFields()) { writeField(cv, field); } for (MethodDescriptor method : cls.getMethods()) { writeMethod(cv, cls, method); } cv.visitEnd(); end(cls); return writer.toByteArray(); }
From source file:org.jephyr.common.agent.DelegationClassAdapter.java
License:Open Source License
@Override public void visitInnerClass(String name, String outerName, String innerName, int access) { ClassVisitor cv1 = delegate(); if (cv1 != null) { cv1.visitInnerClass(name, outerName, innerName, access); }//w ww . j a va 2 s. c o m }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Accepts a visitor and fills it with information for a given class. * @param classRep the representation for the top-level class. * @param cv the class visitor to accept. * @throws JavaGenerationException/* w ww . j av a 2 s . c o m*/ */ private static void encodeClassAcceptingVisitor(JavaClassRep classRep, ClassVisitor cv) throws JavaGenerationException { // Get the fully-qualified internal class and superclass names. final JavaTypeName classRepTypeName = classRep.getClassName(); final String className = classRepTypeName.getJVMInternalName(); final String superclassName = classRep.getSuperclassName().getJVMInternalName(); // Determine if the class or any inner class contains assert statements. int assertPresence = classRep.getAssertionContainment(); if ((assertPresence & JavaClassRep.ASSERTS_UNKNOWN) > 0) { assertPresence = AsmJavaBytecodeGenerator.containsAsserts(classRep); } // Create the interfaces[] array. final int nInterfaces = classRep.getNInterfaces(); final String[] interfaces = new String[nInterfaces]; for (int i = 0; i < nInterfaces; i++) { interfaces[i] = classRep.getInterface(i).getJVMInternalName(); } //ACC_SUPER flag should always be set for the flags defining a class file. //(see the Java language specification under ACC_SUPER in the index. The flag is not set only //by older Java compilers and exists for backwards compatibility reasons). int classModifiers = classRep.getModifiers() | Opcodes.ACC_SUPER; //static inner classes are marked with the static modifier, but this is not a valid access flag for a class. classModifiers &= ~Modifier.STATIC; // We aren't generating or using generics, so the signature can be null String classSignature = null; cv.visit(Opcodes.V1_5, classModifiers, className, classSignature, superclassName, interfaces); //sourcefileName = null, since this class was not compiled from a Java source file. //However, if we are debugging byte codes, use a "fake" source file name as if this class were generated from a Java source file. //This eliminates a trivial difference between the byte code generated by ASM and that of javac and makes inspecting the //differences in a differencing tool easier. String sourceFileName = null; // if (AsmJavaBytecodeGenerator.DEBUG_GENERATED_BYTECODE) { String unqualifiedName = classRepTypeName.getUnqualifiedJavaSourceName(); int dotPosition = unqualifiedName.indexOf('.'); if (dotPosition != -1) { //get the top level class name. unqualifiedName = unqualifiedName.substring(0, dotPosition); } sourceFileName = unqualifiedName + ".java"; // } cv.visitSource(sourceFileName, null); //add the fields for (int i = 0, nFields = classRep.getNFieldDeclarations(); i < nFields; ++i) { JavaFieldDeclaration fieldDeclaration = classRep.getFieldDeclaration(i); //todoBI it may be more efficient to handle initializers for static-fields here in the cases where it is possible //(int, long, float, double, String). cv.visitField(fieldDeclaration.getModifiers(), fieldDeclaration.getFieldName(), fieldDeclaration.getFieldType().getJVMDescriptor(), null, null); } /* * When dealing with assert statements there is possibly an additional field that needs to be * added. * If a class contains an assert statement a static final synthetic boolean field called '$assertionsDisabled' is * added. This field is initialized in the class static initializer and is used to determine whether to * check or skip assertions. */ if (assertPresence != JavaClassRep.ASSERTS_NONE) { if ((assertPresence & JavaClassRep.ASSERTS_IN_CLASS) > 0) { // We need to add a static final synthetic boolean field to indicate the enabled/disabled state of assertions. cv.visitField(Opcodes.ACC_FINAL + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, "$assertionsDisabled", "Z", null, null); } } //add the constructors final int nConstructors = classRep.getNConstructors(); if (nConstructors == 0) { //if empty, add the default constructor. JavaConstructor defaultConstructor = new JavaConstructor(Modifier.PUBLIC, ((JavaTypeName.Reference.Object) classRepTypeName).getBaseName()); defaultConstructor.addStatement(new JavaStatement.ReturnStatement()); encodeConstructor(classRep, defaultConstructor, cv); } else { for (int i = 0; i < nConstructors; ++i) { encodeConstructor(classRep, classRep.getConstructor(i), cv); } } //add the methods for (int i = 0, nMethods = classRep.getNMethods(); i < nMethods; ++i) { encodeMethod(classRep, classRep.getMethod(i), cv); } //add the initializers for the static fields encodeClassInitializer(classRep, cv, (assertPresence & JavaClassRep.ASSERTS_IN_CLASS) > 0); //add the inner classes (these are basically just references to the inner classes) //if classRep itself is an inner class, call visitInnerClass on itself. This is what the eclipse java compiler does. //javac annotates for every inner class reference occurring within the class file e.g. a field declared of inner class type, //an instance of expression of inner class type, a throws declaration on a method where an inner class is thrown. if (classRepTypeName.isInnerClass()) { JavaTypeName.Reference.Object classTypeName = (JavaTypeName.Reference.Object) classRepTypeName; String internalImportName = classTypeName.getImportName().replace('.', '/'); cv.visitInnerClass(classTypeName.getJVMInternalName(), internalImportName, classTypeName.getBaseName(), classRep.getModifiers()); } /* * Previously we would call visitInnerClass for any inner classes associated with this class. However, * we are no longer doing this. * Bytecode is generated in different scenarios (i.e. static generation, dynamic generation, etc). In some * scenarios inner classes are generated separately from the containing class. In order to keep the generated * bytecode consistent between the dynamic and static scenarios wer are not adding the attributes for contained * inner classes to the bytecode. * for (int i = 0, nInnerClasses = classRep.getNInnerClasses(); i < nInnerClasses; ++i) { JavaClassRep innerClass = classRep.getInnerClass(i); JavaTypeName.Reference.Object innerClassTypeName = (JavaTypeName.Reference.Object)innerClass.getClassName(); cw.visitInnerClass(innerClassTypeName.getJVMInternalName(), className, innerClassTypeName.getBaseName(), innerClass.getModifiers()); } */ cv.visitEnd(); }
From source file:org.springframework.migrationanalyzer.contributions.bytecode.DelegatingClassVisitor.java
License:Apache License
@Override public void visitInnerClass(String name, String outerName, String innerName, int access) { for (ClassVisitor delegate : this.delegates) { delegate.visitInnerClass(name, outerName, innerName, access); }// w w w.jav a2 s .c om }