Example usage for org.objectweb.asm ClassVisitor visitInnerClass

List of usage examples for org.objectweb.asm ClassVisitor visitInnerClass

Introduction

In this page you can find the example usage for org.objectweb.asm ClassVisitor visitInnerClass.

Prototype

public void visitInnerClass(final String name, final String outerName, final String innerName,
        final int access) 

Source Link

Document

Visits information about an inner class.

Usage

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
}