Java Code Examples for proguard.classfile.ClassConstants#INTERNAL_ACC_ABSTRACT

The following examples show how to use proguard.classfile.ClassConstants#INTERNAL_ACC_ABSTRACT . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ConcreteClassDownTraveler.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
public void visitProgramClass(ProgramClass programClass)
{
    // Is this an abstract class or an interface?
    if ((programClass.getAccessFlags() &
         (ClassConstants.INTERNAL_ACC_INTERFACE |
          ClassConstants.INTERNAL_ACC_ABSTRACT)) != 0)
    {
        // Travel down the hierarchy.
        Clazz[] subClasses = programClass.subClasses;
        if (subClasses != null)
        {
            for (int index = 0; index < subClasses.length; index++)
            {
                subClasses[index].accept(this);
            }
        }
    }
    else
    {
        // Visit the class. Don't descend any further.
        programClass.accept(classVisitor);
    }
}
 
Example 2
Source File: ConcreteClassDownTraveler.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
public void visitLibraryClass(LibraryClass libraryClass)
{
    // Is this an abstract class or interface?
    if ((libraryClass.getAccessFlags() &
         (ClassConstants.INTERNAL_ACC_INTERFACE |
          ClassConstants.INTERNAL_ACC_ABSTRACT)) != 0)
    {
        // Travel down the hierarchy.
        Clazz[] subClasses = libraryClass.subClasses;
        if (subClasses != null)
        {
            for (int index = 0; index < subClasses.length; index++)
            {
                subClasses[index].accept(this);
            }
        }
    }
    else
    {
        // Visit the class. Don't descend any further.
        libraryClass.accept(classVisitor);
    }
}
 
Example 3
Source File: ClassFinalizer.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
public void visitProgramClass(ProgramClass programClass)
{
    // If the class is not final/interface/abstract,
    // and it is not being kept,
    // and it doesn't have any subclasses,
    // then make it final.
    if ((programClass.u2accessFlags & (ClassConstants.INTERNAL_ACC_FINAL     |
                                       ClassConstants.INTERNAL_ACC_INTERFACE |
                                       ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
        !KeepMarker.isKept(programClass)                                           &&
        programClass.subClasses == null)
    {
        programClass.u2accessFlags |= ClassConstants.INTERNAL_ACC_FINAL;

        // Visit the class, if required.
        if (extraClassVisitor != null)
        {
            extraClassVisitor.visitProgramClass(programClass);
        }
    }
}
 
Example 4
Source File: MethodFinalizer.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
    String name = programMethod.getName(programClass);

    // If the method is not already private/static/final/abstract,
    // and it is not a constructor,
    // and its class is final,
    //     or it is not being kept and it is not overridden,
    // then make it final.
    if ((programMethod.u2accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE |
                                        ClassConstants.INTERNAL_ACC_STATIC  |
                                        ClassConstants.INTERNAL_ACC_FINAL   |
                                        ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
        !name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)                      &&
        ((programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0 ||
         (!KeepMarker.isKept(programMethod) &&
          (programClass.subClasses == null ||
           !memberFinder.isOverriden(programClass, programMethod)))))
    {
        programMethod.u2accessFlags |= ClassConstants.INTERNAL_ACC_FINAL;

        // Visit the method, if required.
        if (extraMemberVisitor != null)
        {
            extraMemberVisitor.visitProgramMethod(programClass, programMethod);
        }
    }
}
 
Example 5
Source File: ClassMerger.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Returns whether the given class would introduce any abstract methods
 * in the target class.
 */
private boolean introducesUnwantedAbstractMethods(Clazz        clazz,
                                                  ProgramClass targetClass)
{
    // It's ok if the target class is already abstract and it has at most
    // the class as a subclass.
    if ((targetClass.getAccessFlags() &
         (ClassConstants.INTERNAL_ACC_ABSTRACT |
          ClassConstants.INTERNAL_ACC_INTERFACE)) != 0 &&
        (targetClass.subClasses == null ||
         isOnlySubClass(clazz, targetClass)))
    {
        return false;
    }

    MemberCounter counter   = new MemberCounter();
    Set           targetSet = new HashSet();

    // Collect all abstract methods, and similar abstract methods in the
    // class hierarchy of the target class.
    clazz.methodsAccept(new MemberAccessFilter(ClassConstants.INTERNAL_ACC_ABSTRACT, 0,
                        new MultiMemberVisitor(new MemberVisitor[]
                        {
                            counter,
                            new SimilarMemberVisitor(targetClass, true, true, true, false,
                                                     new MemberAccessFilter(ClassConstants.INTERNAL_ACC_ABSTRACT, 0,
                                                     new MemberCollector(targetSet)))
                        })));

    return targetSet.size() < counter.getCount();
}
 
Example 6
Source File: ClassUtil.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
/**
 * Converts internal class access flags into an external access description.
 * @param accessFlags the class access flags.
 * @param prefix      a prefix that is added to each access modifier.
 * @return the external class access description,
 *         e.g. "<code>public final </code>".
 */
public static String externalClassAccessFlags(int accessFlags, String prefix)
{
    if (accessFlags == 0)
    {
        return EMPTY_STRING;
    }

    StringBuffer string = new StringBuffer(50);

    if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0)
    {
        // Only in InnerClasses attributes.
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0)
    {
        // Only in InnerClasses attributes.
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
    {
        // Only in InnerClasses attributes.
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STATIC).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_ANNOTATTION) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ANNOTATION);
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_INTERFACE) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_INTERFACE).append(' ');
    }
    else if ((accessFlags & ClassConstants.INTERNAL_ACC_ENUM) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ENUM).append(' ');
    }
    else if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(' ');
    }
    else if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
    }

    return string.toString();
}
 
Example 7
Source File: ClassUtil.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
/**
 * Converts internal method access flags into an external access description.
 * @param accessFlags the method access flags.
 * @param prefix      a prefix that is added to each access modifier.
 * @return the external method access description,
 *                    e.g. "public synchronized ".
 */
public static String externalMethodAccessFlags(int accessFlags, String prefix)
{
    if (accessFlags == 0)
    {
        return EMPTY_STRING;
    }

    StringBuffer string = new StringBuffer(50);

    if ((accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STATIC).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNCHRONIZED) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_BRIDGE) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_BRIDGE).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_VARARGS) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_VARARGS).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_NATIVE) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_NATIVE).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_STRICT) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STRICT).append(' ');
    }
    if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
    {
        string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
    }

    return string.toString();
}
 
Example 8
Source File: MemberAdder.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
    String name        = programMethod.getName(programClass);
    String descriptor  = programMethod.getDescriptor(programClass);
    int    accessFlags = programMethod.getAccessFlags();

    // Does the target class already have such a method?
    ProgramMethod targetMethod = (ProgramMethod)targetClass.findMethod(name, descriptor);
    if (targetMethod != null)
    {
        // is this source method abstract?
        if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
        {
            // Keep the target method.
            if (DEBUG)
            {
                System.out.println("MemberAdder: skipping abstract method ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]");
            }

            // Don't add a new method.
            return;
        }

        // Is the target method abstract?
        int targetAccessFlags = targetMethod.getAccessFlags();
        if ((targetAccessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
        {
            // Keep the abstract method, but update its contents, in order
            // to keep any references to it valid.
            if (DEBUG)
            {
                System.out.println("MemberAdder: updating method ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]");
            }

            // Replace the access flags.
            targetMethod.u2accessFlags =
                accessFlags & ~ClassConstants.INTERNAL_ACC_FINAL;

            // Add and replace the attributes.
            programMethod.attributesAccept(programClass,
                                           new AttributeAdder(targetClass,
                                                              targetMethod,
                                                              true));

            // Don't add a new method.
            return;
        }

        if (DEBUG)
        {
            System.out.println("MemberAdder: renaming method ["+targetClass.getName()+"."+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]");
        }

        // Rename the private (non-abstract) or static method.
        targetMethod.u2nameIndex =
            constantPoolEditor.addUtf8Constant(newUniqueMemberName(name, descriptor));
    }

    if (DEBUG)
    {
        System.out.println("MemberAdder: copying method ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] into ["+targetClass.getName()+"]");
    }

    // Create a copy of the method.
    ProgramMethod newProgramMethod =
        new ProgramMethod(accessFlags & ~ClassConstants.INTERNAL_ACC_FINAL,
                          constantAdder.addConstant(programClass, programMethod.u2nameIndex),
                          constantAdder.addConstant(programClass, programMethod.u2descriptorIndex),
                          0,
                          programMethod.u2attributesCount > 0 ?
                              new Attribute[programMethod.u2attributesCount] :
                              EMPTY_ATTRIBUTES,
                          programMethod.referencedClasses != null ?
                              (Clazz[])programMethod.referencedClasses.clone() :
                              null);

    // Link to its visitor info.
    newProgramMethod.setVisitorInfo(programMethod);

    // Copy its attributes.
    programMethod.attributesAccept(programClass,
                                   new AttributeAdder(targetClass,
                                                      newProgramMethod,
                                                      false));

    // Add the completed method.
    classEditor.addMethod(newProgramMethod);
}
 
Example 9
Source File: ParameterUsageMarker.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
    int parameterSize =
        ClassUtil.internalMethodParameterSize(programMethod.getDescriptor(programClass),
                                              programMethod.getAccessFlags());

    if (parameterSize > 0)
    {
        int accessFlags = programMethod.getAccessFlags();

        // Must we mark the 'this' parameter?
        if (markThisParameter &&
            (accessFlags & ClassConstants.INTERNAL_ACC_STATIC) == 0)
        {
            // Mark the 'this' parameter.
            markParameterUsed(programMethod, 0);
        }

        // Must we mark all other parameters?
        if (markAllParameters)
        {
            // Mark all parameters, without the 'this' parameter.
            markUsedParameters(programMethod,
                               (accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0 ?
                                   -1L : -2L);
        }

        // Is it a native method?
        if ((accessFlags & ClassConstants.INTERNAL_ACC_NATIVE) != 0)
        {
            // Mark all parameters.
            markUsedParameters(programMethod, -1L);
        }

        // Is it an abstract method?
        else if ((accessFlags & ClassConstants.INTERNAL_ACC_ABSTRACT) != 0)
        {
            // Mark the 'this' parameter.
            markParameterUsed(programMethod, 0);
        }

        // Is it a non-native, concrete method?
        else
        {
            // Is the method not static, but synchronized, or can it have
            // other implementations, or is it a class instance initializer?
            if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) == 0 &&
                ((accessFlags & ClassConstants.INTERNAL_ACC_SYNCHRONIZED) != 0 ||
                 programClass.mayHaveImplementations(programMethod)            ||
                 programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)))
            {
                // Mark the 'this' parameter.
                markParameterUsed(programMethod, 0);
            }

            // Mark the parameters that are used by the code.
            programMethod.attributesAccept(programClass, this);
        }

        if (DEBUG)
        {
            System.out.print("ParameterUsageMarker: ["+programClass.getName() +"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"]: ");
            for (int index = 0; index < parameterSize; index++)
            {
                System.out.print(isParameterUsed(programMethod, index) ? '+' : '-');
            }
            System.out.println();
        }

    }

    // Set the parameter size.
    setParameterSize(programMethod, parameterSize);
}
 
Example 10
Source File: TailRecursionSimplifier.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
    {
        int accessFlags = method.getAccessFlags();

        if (// Only check the method if it is private, static, or final.
            (accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE |
                            ClassConstants.INTERNAL_ACC_STATIC  |
                            ClassConstants.INTERNAL_ACC_FINAL)) != 0 &&

            // Only check the method if it is not synchronized, etc.
            (accessFlags & (ClassConstants.INTERNAL_ACC_SYNCHRONIZED |
                            ClassConstants.INTERNAL_ACC_NATIVE       |
                            ClassConstants.INTERNAL_ACC_INTERFACE    |
                            ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0)
        {
//            codeAttributeComposer.DEBUG = DEBUG =
//                clazz.getName().equals("abc/Def") &&
//                method.getName(clazz).equals("abc");

            targetMethod = method;
            inlinedAny   = false;
            codeAttributeComposer.reset();

            // The code may expand, due to expanding constant and variable
            // instructions.
            codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);

            // Copy the instructions.
            codeAttribute.instructionsAccept(clazz, method, this);

            // Update the code attribute if any code has been inlined.
            if (inlinedAny)
            {
                // Copy the exceptions.
                codeAttribute.exceptionsAccept(clazz, method, this);

                // Append a label just after the code.
                codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);

                codeAttributeComposer.endCodeFragment();

                codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute);
            }
        }
    }
 
Example 11
Source File: VariableShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
    if ((method.getAccessFlags() & ClassConstants.INTERNAL_ACC_ABSTRACT) == 0)
    {
        // Compute the parameter size.
        int parameterSize =
            ClassUtil.internalMethodParameterSize(method.getDescriptor(clazz),
                                                  method.getAccessFlags());

        // Get the total size of the local variable frame.
        int maxLocals = codeAttribute.u2maxLocals;

        if (DEBUG)
        {
            System.out.println("VariableShrinker: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
            System.out.println("  Parameter size = " + parameterSize);
            System.out.println("  Max locals     = " + maxLocals);
        }

        // Figure out the local variables that are used by the code.
        variableUsageMarker.visitCodeAttribute(clazz, method, codeAttribute);

        // Delete unused local variables from the local variable frame.
        variableEditor.reset(maxLocals);

        for (int variableIndex = parameterSize; variableIndex < maxLocals; variableIndex++)
        {
            // Is the variable not required?
            if (!variableUsageMarker.isVariableUsed(variableIndex))
            {
                if (DEBUG)
                {
                    System.out.println("  Deleting local variable #"+variableIndex);
                }

                // Delete the unused variable.
                variableEditor.deleteVariable(variableIndex);

                // Visit the method, if required.
                if (extraVariableMemberVisitor != null)
                {
                    method.accept(clazz, extraVariableMemberVisitor);
                }
            }
        }

        // Shift all remaining parameters and variables in the byte code.
        variableEditor.visitCodeAttribute(clazz, method, codeAttribute);
    }
}
 
Example 12
Source File: MethodInliner.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
    {
        int accessFlags = programMethod.getAccessFlags();

        if (// Only inline the method if it is private, static, or final.
            (accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE |
                            ClassConstants.INTERNAL_ACC_STATIC  |
                            ClassConstants.INTERNAL_ACC_FINAL)) != 0                              &&

            // Only inline the method if it is not synchronized, etc.
            (accessFlags & (ClassConstants.INTERNAL_ACC_SYNCHRONIZED |
                            ClassConstants.INTERNAL_ACC_NATIVE       |
                            ClassConstants.INTERNAL_ACC_INTERFACE    |
                            ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0                           &&

            // Don't inline an <init> method, except in an <init> method in the
            // same class.
//            (!programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ||
//             (programClass.equals(targetClass) &&
//              targetMethod.getName(targetClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))) &&
            !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&

            // Don't inline a method into itself.
            (!programMethod.equals(targetMethod) ||
             !programClass.equals(targetClass))                                                   &&

            // Only inline the method if it isn't recursing.
            !inliningMethods.contains(programMethod)                                              &&

            // Only inline the method if its target class has at least the
            // same version number as the source class, in order to avoid
            // introducing incompatible constructs.
            targetClass.u4version >= programClass.u4version                                       &&

            // Only inline the method if it doesn't invoke a super method, or if
            // it is in the same class.
            (!SuperInvocationMarker.invokesSuperMethods(programMethod) ||
             programClass.equals(targetClass))                                                    &&

            // Only inline the method if it doesn't branch backward while there
            // are uninitialized objects.
            (!BackwardBranchMarker.branchesBackward(programMethod) ||
             uninitializedObjectCount == 0)                                                       &&

            // Only inline if the code access of the inlined method allows it.
            (allowAccessModification ||
             ((!AccessMethodMarker.accessesPrivateCode(programMethod) ||
               programClass.equals(targetClass)) &&

              (!AccessMethodMarker.accessesPackageCode(programMethod) ||
               ClassUtil.internalPackageName(programClass.getName()).equals(
               ClassUtil.internalPackageName(targetClass.getName())))))                           &&

//               (!AccessMethodMarker.accessesProtectedCode(programMethod) ||
//                targetClass.extends_(programClass) ||
//                targetClass.implements_(programClass)) ||
            (!AccessMethodMarker.accessesProtectedCode(programMethod) ||
             programClass.equals(targetClass))                                                    &&

            // Only inline the method if it doesn't catch exceptions, or if it
            // is invoked with an empty stack.
            (!CatchExceptionMarker.catchesExceptions(programMethod) ||
             emptyInvokingStack)                                                                  &&

            // Only inline the method if it comes from the a class with at most
            // a subset of the initialized superclasses.
            (programClass.equals(targetClass) ||
             initializedSuperClasses(targetClass).containsAll(initializedSuperClasses(programClass))))
        {                                                                                                   boolean oldInlining = inlining;
            inlining = true;
            inliningMethods.push(programMethod);

            // Inline the method body.
            programMethod.attributesAccept(programClass, this);

            // Update the optimization information of the target method.
            MethodOptimizationInfo info =
                MethodOptimizationInfo.getMethodOptimizationInfo(targetMethod);
            if (info != null)
            {
                info.merge(MethodOptimizationInfo.getMethodOptimizationInfo(programMethod));
            }

            inlining = oldInlining;
            inliningMethods.pop();
        }
        else if (programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))
        {
            uninitializedObjectCount--;
        }
    }