示例#1
0
  public void visitProgramClass(ProgramClass programClass) {
    int[] interfaces = programClass.u2interfaces;
    int interfacesCount = programClass.u2interfacesCount;

    if (interfacesCount > 1) {
      // Sort the interfaces.
      Arrays.sort(interfaces, 0, interfacesCount);

      // Remove any duplicate entries.
      int newInterfacesCount = 0;
      int previousInterfaceIndex = 0;
      for (int index = 0; index < interfacesCount; index++) {
        int interfaceIndex = interfaces[index];

        // Isn't this a duplicate of the previous interface?
        if (interfaceIndex != previousInterfaceIndex) {
          interfaces[newInterfacesCount++] = interfaceIndex;

          // Remember the interface.
          previousInterfaceIndex = interfaceIndex;
        }
      }

      programClass.u2interfacesCount = newInterfacesCount;

      // Update the signature, if any
      programClass.attributesAccept(this);
    }
  }
示例#2
0
  protected void markProgramClassBody(ProgramClass programClass) {
    // Mark this class's name.
    markConstant(programClass, programClass.u2thisClass);

    // Mark the superclass.
    if (programClass.u2superClass != 0) {
      markConstant(programClass, programClass.u2superClass);
    }

    // Give the interfaces preliminary marks.
    programClass.hierarchyAccept(false, false, true, false, interfaceUsageMarker);

    // Explicitly mark the <clinit> method, if it's not empty.
    programClass.methodAccept(
        ClassConstants.METHOD_NAME_CLINIT,
        ClassConstants.METHOD_TYPE_CLINIT,
        nonEmptyMethodUsageMarker);

    // Process all class members that have already been marked as possibly used.
    programClass.fieldsAccept(possiblyUsedMemberUsageMarker);
    programClass.methodsAccept(possiblyUsedMemberUsageMarker);

    // Mark the attributes.
    programClass.attributesAccept(this);
  }
  public void visitProgramClass(ProgramClass programClass) {
    // Visit the constant pool entries.
    programClass.constantPoolEntriesAccept(this);

    // Visit the fields and methods.
    programClass.fieldsAccept(this);
    programClass.methodsAccept(this);

    // Visit the attributes.
    programClass.attributesAccept(this);
  }
示例#4
0
  public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) {
    // Process the generic definitions, superclass, and implemented
    // interfaces.
    String signature = clazz.getString(signatureAttribute.u2signatureIndex);

    // Count the signature types.
    InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(signature);

    int count = 0;
    int interfacesCount = -1;
    while (internalTypeEnumeration.hasMoreTypes()) {
      String internalType = internalTypeEnumeration.nextType();

      count++;

      if (ClassUtil.isInternalClassType(internalType)) {
        interfacesCount++;
      }
    }

    // Put the signature types in an array.
    internalTypeEnumeration = new InternalTypeEnumeration(signature);

    String[] internalTypes = new String[count];

    for (int index = 0; index < count; index++) {
      String internalType = internalTypeEnumeration.nextType();

      internalTypes[index] = internalType;
    }

    // Sort the interface types in the array.
    Arrays.sort(internalTypes, count - interfacesCount, count);

    // Recompose the signature types in a string.
    StringBuffer newSignatureBuffer = new StringBuffer();

    for (int index = 0; index < count; index++) {
      // Is this not an interface type, or an interface type that isn't
      // a duplicate of the previous interface type?
      if (index < count - interfacesCount
          || !internalTypes[index].equals(internalTypes[index - 1])) {
        newSignatureBuffer.append(internalTypes[index]);
      }
    }

    String newSignature = newSignatureBuffer.toString();

    // Did the signature change?
    if (!newSignature.equals(signature)) {
      // Update the signature.
      ((Utf8Constant) ((ProgramClass) clazz).constantPool[signatureAttribute.u2signatureIndex])
          .setString(newSignatureBuffer.toString());

      // Clear the referenced classes.
      // TODO: Properly update the referenced classes.
      signatureAttribute.referencedClasses = null;
    }
  }
  public void visitProgramClass(ProgramClass programClass) {
    if (DEBUG) {
      System.out.println("SimpleEnumClassSimplifier: [" + programClass.getName() + "]");
    }

    // Unmark the class as an enum.
    programClass.u2accessFlags &= ~ClassConstants.ACC_ENUM;

    // Remove the valueOf method, if present.
    Method valueOfMethod = programClass.findMethod(ClassConstants.METHOD_NAME_VALUEOF, null);
    if (valueOfMethod != null) {
      new ClassEditor(programClass).removeMethod(valueOfMethod);
    }

    // Simplify the static initializer.
    programClass.methodAccept(
        ClassConstants.METHOD_NAME_CLINIT,
        ClassConstants.METHOD_TYPE_CLINIT,
        initializerSimplifier);
  }
示例#6
0
 /** Deletes the specified attribute from the target. */
 public void deleteAttribute(String attributeName) {
   // What's the target?
   if (targetAttribute != null) {
     targetAttribute.u2attributesCount =
         deleteAttribute(
             targetAttribute.u2attributesCount, targetAttribute.attributes, attributeName);
   } else if (targetMember != null) {
     targetMember.u2attributesCount =
         deleteAttribute(targetMember.u2attributesCount, targetMember.attributes, attributeName);
   } else {
     targetClass.u2attributesCount =
         deleteAttribute(targetClass.u2attributesCount, targetClass.attributes, attributeName);
   }
 }
  public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) {
    // Update the descriptor if it has any unused parameters.
    String descriptor = programMethod.getDescriptor(programClass);
    String newDescriptor = shrinkDescriptor(programMethod, descriptor);

    if (!descriptor.equals(newDescriptor)) {
      // Shrink the signature and parameter annotations.
      programMethod.attributesAccept(programClass, this);

      String name = programMethod.getName(programClass);
      String newName = name;

      // Append a code, if the method isn't a class instance initializer.
      if (!name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)) {
        newName +=
            ClassConstants.SPECIAL_MEMBER_SEPARATOR
                + Long.toHexString(Math.abs((descriptor).hashCode()));
      }

      if (DEBUG) {
        System.out.println("MethodDescriptorShrinker:");
        System.out.println("  Class file        = " + programClass.getName());
        System.out.println("  Method name       = " + name);
        System.out.println("                   -> " + newName);
        System.out.println("  Method descriptor = " + descriptor);
        System.out.println("                   -> " + newDescriptor);
      }

      ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(programClass);

      // Update the name, if necessary.
      if (!newName.equals(name)) {
        programMethod.u2nameIndex = constantPoolEditor.addUtf8Constant(newName);
      }

      // Update the referenced classes.
      programMethod.referencedClasses =
          shrinkReferencedClasses(programMethod, descriptor, programMethod.referencedClasses);

      // Finally, update the descriptor itself.
      programMethod.u2descriptorIndex = constantPoolEditor.addUtf8Constant(newDescriptor);

      // Visit the method, if required.
      if (extraMemberVisitor != null) {
        extraMemberVisitor.visitProgramMethod(programClass, programMethod);
      }
    }
  }
示例#8
0
  /** Adds the given attribute to the target. */
  public void addAttribute(Attribute attribute) {
    // What's the target?
    if (targetAttribute != null) {
      // Try to replace an existing attribute.
      if (!replaceAttributes
          || !replaceAttribute(
              targetAttribute.u2attributesCount, targetAttribute.attributes, attribute)) {
        // Otherwise append the attribute.
        targetAttribute.attributes =
            addAttribute(targetAttribute.u2attributesCount, targetAttribute.attributes, attribute);

        targetAttribute.u2attributesCount++;
      }
    } else if (targetMember != null) {
      // Try to replace an existing attribute.
      if (!replaceAttributes
          || !replaceAttribute(
              targetMember.u2attributesCount, targetMember.attributes, attribute)) {
        // Otherwise append the attribute.
        targetMember.attributes =
            addAttribute(targetMember.u2attributesCount, targetMember.attributes, attribute);

        targetMember.u2attributesCount++;
      }
    } else {
      // Try to replace an existing attribute.
      if (!replaceAttributes
          || !replaceAttribute(targetClass.u2attributesCount, targetClass.attributes, attribute)) {
        // Otherwise append the attribute.
        targetClass.attributes =
            addAttribute(targetClass.u2attributesCount, targetClass.attributes, attribute);

        targetClass.u2attributesCount++;
      }
    }
  }