示例#1
0
  public void visitLibraryClass(LibraryClass libraryClass) {
    if (shouldBeMarkedAsUsed(libraryClass)) {
      markAsUsed(libraryClass);

      // We're not going to analyze all library code. We're assuming that
      // if this class is being used, all of its methods will be used as
      // well. We'll mark them as such (here and in all subclasses).

      // Mark the superclass.
      Clazz superClass = libraryClass.superClass;
      if (superClass != null) {
        superClass.accept(this);
      }

      // Mark the interfaces.
      Clazz[] interfaceClasses = libraryClass.interfaceClasses;
      if (interfaceClasses != null) {
        for (int index = 0; index < interfaceClasses.length; index++) {
          if (interfaceClasses[index] != null) {
            interfaceClasses[index].accept(this);
          }
        }
      }

      // Mark all methods.
      libraryClass.methodsAccept(this);
    }
  }
示例#2
0
  public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) {
    // At this point, we only mark outer classes of this class.
    // Inner class can be marked later, by InnerUsageMarker.
    if (innerClassesInfo.u2innerClassIndex != 0
        && clazz.getName().equals(clazz.getClassName(innerClassesInfo.u2innerClassIndex))) {
      markAsUsed(innerClassesInfo);

      innerClassesInfo.innerClassConstantAccept(clazz, this);
      innerClassesInfo.outerClassConstantAccept(clazz, this);
      innerClassesInfo.innerNameConstantAccept(clazz, this);
    }
  }
示例#3
0
  /**
   * Marks the hierarchy of implementing or overriding methods corresponding to the given method, if
   * any.
   */
  protected void markMethodHierarchy(Clazz clazz, Method method) {
    int accessFlags = method.getAccessFlags();
    if ((accessFlags & (ClassConstants.ACC_PRIVATE | ClassConstants.ACC_STATIC)) == 0
        && !ClassUtil.isInitializer(method.getName(clazz))) {
      // We can skip private and static methods in the hierarchy, and
      // also abstract methods, unless they might widen a current
      // non-public access.
      int requiredUnsetAccessFlags =
          ClassConstants.ACC_PRIVATE
              | ClassConstants.ACC_STATIC
              | ((accessFlags & ClassConstants.ACC_PUBLIC) == 0 ? 0 : ClassConstants.ACC_ABSTRACT);

      clazz.accept(
          new ConcreteClassDownTraveler(
              new ClassHierarchyTraveler(
                  true,
                  true,
                  false,
                  true,
                  new NamedMethodVisitor(
                      method.getName(clazz),
                      method.getDescriptor(clazz),
                      new MemberAccessFilter(0, requiredUnsetAccessFlags, this)))));
    }
  }
示例#4
0
  /**
   * Marks the hierarchy of implementing or overriding methods corresponding to the given method, if
   * any.
   */
  protected void markMethodHierarchy(Clazz clazz, Method method) {
    int accessFlags = method.getAccessFlags();
    if ((accessFlags & (ClassConstants.ACC_PRIVATE | ClassConstants.ACC_STATIC)) == 0
        && !ClassUtil.isInitializer(method.getName(clazz))) {
      // We can skip private and static methods in the hierarchy, and
      // also abstract methods, unless they might widen a current
      // non-public access.
      int requiredUnsetAccessFlags =
          ClassConstants.ACC_PRIVATE
              | ClassConstants.ACC_STATIC
              | ((accessFlags & ClassConstants.ACC_PUBLIC) == 0 ? 0 : ClassConstants.ACC_ABSTRACT);

      // Mark default implementations in interfaces down the hierarchy.
      // TODO: This may be premature if there aren't any concrete implementing classes.
      clazz.accept(
          new ClassAccessFilter(
              ClassConstants.ACC_ABSTRACT,
              0,
              new ClassHierarchyTraveler(
                  false,
                  false,
                  false,
                  true,
                  new ProgramClassFilter(
                      new ClassAccessFilter(
                          ClassConstants.ACC_ABSTRACT,
                          0,
                          new NamedMethodVisitor(
                              method.getName(clazz),
                              method.getDescriptor(clazz),
                              new MemberAccessFilter(
                                  0, requiredUnsetAccessFlags, defaultMethodUsageMarker)))))));

      // Mark other implementations.
      clazz.accept(
          new ConcreteClassDownTraveler(
              new ClassHierarchyTraveler(
                  true,
                  true,
                  false,
                  true,
                  new NamedMethodVisitor(
                      method.getName(clazz),
                      method.getDescriptor(clazz),
                      new MemberAccessFilter(0, requiredUnsetAccessFlags, this)))));
    }
  }
示例#5
0
  public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) {
    if (shouldBeMarkedAsUsed(invokeDynamicConstant)) {
      markAsUsed(invokeDynamicConstant);

      markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);

      // Mark the bootstrap methods attribute.
      clazz.attributesAccept(
          new MyBootStrapMethodUsageMarker(invokeDynamicConstant.u2bootstrapMethodAttributeIndex));
    }
  }
示例#6
0
  public void visitConstantInstruction(
      Clazz clazz,
      Method method,
      CodeAttribute codeAttribute,
      int offset,
      ConstantInstruction constantInstruction) {
    markConstant(clazz, constantInstruction.constantIndex);

    // Also mark the parameterless constructor of the class, in case the
    // string constant or class constant is being used in a Class.forName
    // or a .class construct.
    clazz.constantPoolEntryAccept(
        constantInstruction.constantIndex, parameterlessConstructorMarker);
  }
示例#7
0
 /**
  * Marks the given constant pool entry of the given class. This includes visiting any referenced
  * objects.
  */
 private void markConstant(Clazz clazz, int index) {
   clazz.constantPoolEntryAccept(index, this);
 }