示例#1
0
 /**
  * Makes the given class visitor visit this class.
  *
  * @param cv a class visitor.
  */
 public void accept(final ClassVisitor cv) {
   // visits header
   String[] interfaces = new String[this.interfaces.size()];
   this.interfaces.toArray(interfaces);
   cv.visit(version, access, name, signature, superName, interfaces);
   // visits source
   if (sourceFile != null || sourceDebug != null) {
     cv.visitSource(sourceFile, sourceDebug);
   }
   // visits outer class
   if (outerClass != null) {
     cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
   }
   // visits attributes
   int i, n;
   n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
   for (i = 0; i < n; ++i) {
     AnnotationNode an = visibleAnnotations.get(i);
     an.accept(cv.visitAnnotation(an.desc, true));
   }
   n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
   for (i = 0; i < n; ++i) {
     AnnotationNode an = invisibleAnnotations.get(i);
     an.accept(cv.visitAnnotation(an.desc, false));
   }
   n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
   for (i = 0; i < n; ++i) {
     TypeAnnotationNode an = visibleTypeAnnotations.get(i);
     an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, true));
   }
   n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations.size();
   for (i = 0; i < n; ++i) {
     TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
     an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, false));
   }
   n = attrs == null ? 0 : attrs.size();
   for (i = 0; i < n; ++i) {
     cv.visitAttribute(attrs.get(i));
   }
   // visits inner classes
   for (i = 0; i < innerClasses.size(); ++i) {
     innerClasses.get(i).accept(cv);
   }
   // visits fields
   for (i = 0; i < fields.size(); ++i) {
     fields.get(i).accept(cv);
   }
   // visits methods
   for (i = 0; i < methods.size(); ++i) {
     methods.get(i).accept(cv);
   }
   // visits end
   cv.visitEnd();
 }
 /**
  * Handle a bizarre special case. Nested classes (static classes declared inside another class)
  * that are protected have their access bit set to public in their class files to deal with some
  * odd reflection situation. Our SVUID computation must do as the JVM does and ignore access bits
  * in the class file in favor of the access bits InnerClass attribute.
  */
 @Override
 public void visitInnerClass(
     final String aname, final String outerName, final String innerName, final int attr_access) {
   if ((name != null) && name.equals(aname)) {
     this.access = attr_access;
   }
   super.visitInnerClass(aname, outerName, innerName, attr_access);
 }
  /*
   * Add the SVUID if class doesn't have one
   */
  @Override
  public void visitEnd() {
    // compute SVUID and add it to the class
    if (computeSVUID && !hasSVUID) {
      try {
        addSVUID(computeSVUID());
      } catch (Throwable e) {
        throw new RuntimeException("Error while computing SVUID for " + name, e);
      }
    }

    super.visitEnd();
  }
  /*
   * Visit class header and get class name, access , and interfaces
   * information (step 1,2, and 3) for SVUID computation.
   */
  @Override
  public void visit(
      final int version,
      final int access,
      final String name,
      final String signature,
      final String superName,
      final String[] interfaces) {
    computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;

    if (computeSVUID) {
      this.name = name;
      this.access = access;
      this.interfaces = new String[interfaces.length];
      System.arraycopy(interfaces, 0, this.interfaces, 0, interfaces.length);
    }

    super.visit(version, access, name, signature, superName, interfaces);
  }