Example usage for org.aspectj.apache.bcel Constants CONSTANT_Methodref

List of usage examples for org.aspectj.apache.bcel Constants CONSTANT_Methodref

Introduction

In this page you can find the example usage for org.aspectj.apache.bcel Constants CONSTANT_Methodref.

Prototype

byte CONSTANT_Methodref

To view the source code for org.aspectj.apache.bcel Constants CONSTANT_Methodref.

Click Source Link

Usage

From source file:org.caesarj.mixer.intern.ClassModifyingVisitor.java

License:Open Source License

/**
 * Checks method references to super-constructors and outerclass methods
 * and modifies them to refer to the correct new outer classes. 
 *//*w  w  w. j a v a 2 s .  c  om*/
protected void modifyMethodAndFieldRefs(JavaClass clazz) {

    ConstantPool cp = clazz.getConstantPool();
    for (int i = 1; i < cp.getLength(); i++) {
        Constant c = cp.getConstant(i);

        if (c == null)
            continue;

        if (c.getTag() == Constants.CONSTANT_Fieldref) {
            ConstantFieldref fieldRef = (ConstantFieldref) c;

            String targetClass = fieldRef.getClass(cp);
            if (Tools.sameClass(targetClass, oldOuterClassName)) {
                int classIndex = fieldRef.getClassIndex();
                ConstantClass cc = (ConstantClass) cp.getConstant(classIndex);
                int nameIndex = cc.getNameIndex();
                cp.setConstant(nameIndex, new ConstantUtf8(newOuterClassName));
            }

        } else if (c.getTag() == Constants.CONSTANT_Methodref) {
            ConstantMethodref mr = (ConstantMethodref) c;
            String targetClassName = mr.getClass(cp);

            int nameAndTypeIndex = mr.getNameAndTypeIndex();
            ConstantNameAndType nat = ((ConstantNameAndType) cp.getConstant(nameAndTypeIndex));
            String methodName = nat.getName(cp);

            // check for innerclass construction
            if (Tools.isPrefix(oldClassName, targetClassName)) {
                String innerIdent = targetClassName.substring(oldClassName.length() + 1);
                String newInnerName = newClassName + "$" + innerIdent;

                try {
                    Integer.parseInt(innerIdent);
                } catch (Exception e) {
                    // not an anonymous inner class
                    continue;
                }

                // Change target class to new inner class
                int targetClassIndex = mr.getClassIndex();
                int targetNameIndex = ((ConstantClass) cp.getConstant(targetClassIndex)).getNameIndex();
                cp.setConstant(targetNameIndex, new ConstantUtf8(newInnerName));

                // Change argument class to new class
                Type[] args = Type.getArgumentTypes(nat.getSignature(cp));
                for (int j = 0; j < args.length; j++) {
                    Type arg = args[j];
                    String signature = arg.getSignature();
                    String argumentType = arg.toString();
                    if (Tools.sameClass(argumentType, oldClassName)) {
                        args[j] = Type.getType("L" + newClassName + ";");
                    }
                }
                String signature = Type.getMethodSignature(Type.getReturnType(nat.getSignature(cp)), args);
                int signatureIndex = nat.getSignatureIndex();
                cp.setConstant(signatureIndex, new ConstantUtf8(signature));
            }

            // Check for superconstructor calls with otuer class parameter
            if (Tools.sameClass(targetClassName, newSuperclassName)) {
                if (methodName.equals("<init>")) {
                    Type[] args = Type.getArgumentTypes(nat.getSignature(cp));
                    if (args.length == 1) {
                        String argumentType = args[0].toString();
                        // if parameter is of old super-outer-class type, set new signature
                        if (Tools.sameClass(argumentType, outerOfOldSuper)) {
                            cp.setConstant(nat.getSignatureIndex(),
                                    new ConstantUtf8("(L" + outerOfNewSuper + ";)V"));
                        }
                    }
                }
            }

            // check whether its a call to our old outer class
            if (Tools.isPrefix(targetClassName, oldOuterClassName)) {
                //               String newTargetClass = Tools.getNewOuterName(
                //                                    oldClassName,
                //                                    targetClassName,
                //                                    outerClasses);
                int classIndex = mr.getClassIndex();
                ConstantClass cc = (ConstantClass) cp.getConstant(classIndex);
                int nameIndex = cc.getNameIndex();
                cp.setConstant(nameIndex, new ConstantUtf8(newOuterClassName));
            }
        }
    }
}