예제 #1
0
  public void insertInvokeSpecialForMockedSuperclass(MethodCallReplacementMethodAdapter mv) {
    int numArguments = Type.getArgumentTypes(replacementDesc).length;
    mv.push(numArguments);
    mv.newArray(Type.getType(Object.class));
    for (int i = 0; i < numArguments; i++) {
      // param, array
      mv.dupX1(); // array, param, array
      mv.swap(); // array, array, param
      mv.push(numArguments - i - 1); // array, array, param, index
      mv.swap(); // array, array, index, param
      mv.arrayStore(Type.getType(Object.class));
      // array
    }
    mv.push(methodName);
    mv.push(desc);
    Method invokeSpecialMethod = InvokeSpecialMock.class.getDeclaredMethods()[0];

    mv.visitMethodInsn(
        Opcodes.INVOKESTATIC,
        InvokeSpecialMock.class.getCanonicalName().replace('.', '/'),
        "invokeSpecial",
        Type.getMethodDescriptor(invokeSpecialMethod),
        false);

    if (Type.getReturnType(desc).equals(Type.VOID_TYPE)) {
      mv.pop();
    } else {
      mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getReturnType(desc).getInternalName());
    }
  }
예제 #2
0
 private void addMethodDesc(final String desc) {
   addType(Type.getReturnType(desc));
   Type[] types = Type.getArgumentTypes(desc);
   for (int i = 0; i < types.length; i++) {
     addType(types[i]);
   }
 }
      public void handleMethod(
          String className,
          String methodName,
          int access,
          String desc,
          String signature,
          String[] exceptions,
          String annotation,
          List<Value> values) {
        System.err.println(
            "Sample annotated method : classname="
                + className
                + " methodName="
                + methodName
                + " access="
                + access
                + " desc="
                + desc
                + " signature="
                + signature);

        org.objectweb.asm.Type retType = org.objectweb.asm.Type.getReturnType(desc);
        System.err.println("REturn type = " + retType);
        org.objectweb.asm.Type[] params = org.objectweb.asm.Type.getArgumentTypes(desc);
        if (params == null) System.err.println("No params");
        else System.err.println(params.length + " params");

        if (exceptions == null) System.err.println("No exceptions");
        else System.err.println(exceptions.length + " exceptions");

        assertEquals("org.eclipse.jetty.annotations.ClassA", className);
        assertTrue(methods.contains(methodName));
        assertEquals("org.eclipse.jetty.annotations.Sample", annotation);
      }
 public MethodVisitor visitMethod(
     int access, String name, String desc, String signature, String[] exceptions) {
   Type[] args = Type.getArgumentTypes(desc);
   Type returnType = Type.getReturnType(desc);
   int startParameter = getStartParameterIndex(name);
   MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions);
   return new MyMethodAdapter(this, v, args, returnType, access, startParameter, name);
 }
예제 #5
0
  protected void appendDescriptor(
      final StringBuffer buf1, final int type, final String desc, final boolean raw1) {
    if (desc == null) {
      // buf1.append("null");
      return;
    }
    if (raw1) {
      if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE || type == METHOD_SIGNATURE) {
        if (type != CLASS_SIGNATURE) {
          buf1.append(tab);
        }
        buf1.append("// signature ").append(desc).append('\n');
      } else {
        buf1.append(desc);
      }
    } else {
      switch (type) {
        case INTERNAL_NAME:
          buf1.append(eatPackageNames(desc, '/'));
          break;
        case FIELD_DESCRIPTOR:
          buf1.append(getSimpleName(Type.getType(desc)));
          break;
        case METHOD_DESCRIPTOR:
          Type[] args = Type.getArgumentTypes(desc);
          Type res = Type.getReturnType(desc);
          buf1.append('(');
          for (int i = 0; i < args.length; ++i) {
            if (i > 0) {
              buf1.append(',');
            }
            buf1.append(getSimpleName(args[i]));
          }
          buf1.append(") : ");
          buf1.append(getSimpleName(res));
          break;

        case METHOD_SIGNATURE:
        case FIELD_SIGNATURE:
        case CLASS_SIGNATURE:
          // ignore - show only in "raw" mode
          break;
        case TYPE_DECLARATION:
          buf1.append(eatPackageNames(desc, '.'));
          break;
        case CLASS_DECLARATION:
          buf1.append(eatPackageNames(desc, '.'));
          break;
        case PARAMETERS_DECLARATION:
          buf1.append(eatPackageNames(desc, '.'));
          break;
        default:
          buf1.append(desc);
      }
    }
  }
예제 #6
0
  /**
   * Translates a descriptor, specifically. Only translates names in the descriptor, if they are
   * represented by class mirrors.
   */
  protected String translateMethodDescriptor(final String descriptor) {
    Type[] argTypes = Type.getArgumentTypes(descriptor);

    for (int i = 0; i < argTypes.length; ++i) {
      argTypes[i] = getMirrorType(argTypes[i]);
    }

    final Type returnType = getMirrorType(Type.getReturnType(descriptor));

    return Type.getMethodDescriptor(returnType, argTypes);
  }
예제 #7
0
  private void contributeToString(
      String internalName, Property<Class<?>, Method> property, MethodVisitor toStringMv) {
    if (property.isLeastSpecificType()) {
      Type returnType = Type.getReturnType(property.getAccessor());

      toStringMv.visitVarInsn(ALOAD, 0);

      toStringMv.visitVarInsn(ALOAD, 1);
      toStringMv.visitLdcInsn(property.getName());
      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/Object;)Ljava/lang/StringBuilder;",
          false);

      toStringMv.visitLdcInsn("=");
      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/Object;)Ljava/lang/StringBuilder;",
          false);

      toStringMv.visitVarInsn(ALOAD, 0);
      toStringMv.visitMethodInsn(
          INVOKESPECIAL,
          internalName,
          property.getAccessor().getName(),
          Type.getMethodDescriptor(property.getAccessor()),
          false);

      String desc =
          property.getType().isPrimitive()
              ? Type.getDescriptor(property.getType())
              : "Ljava/lang/Object;";

      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(" + desc + ")Ljava/lang/StringBuilder;",
          false);

      toStringMv.visitLdcInsn(", ");
      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/Object;)Ljava/lang/StringBuilder;",
          false);
    }
  }
 private String getExecutorDescriptor(MethodMember methodMember) {
   Type[] params = Type.getArgumentTypes(methodMember.getDescriptor());
   Type[] newParametersArray = params;
   if (!methodMember.isStatic()) {
     newParametersArray = new Type[params.length + 1];
     System.arraycopy(params, 0, newParametersArray, 1, params.length);
     newParametersArray[0] = Type.getType(reloadableType.getClazz());
   }
   String executorDescriptor =
       Type.getMethodDescriptor(
           Type.getReturnType(methodMember.getDescriptor()), newParametersArray);
   return executorDescriptor;
 }
예제 #9
0
  public static MethodDescriptor fromAsmMethodDescriptor(String desc) {

    MethodDescriptor md = new MethodDescriptor();

    org.objectweb.asm.Type[] asmTypes = org.objectweb.asm.Type.getArgumentTypes(desc);

    for (org.objectweb.asm.Type asmType : asmTypes) {
      md.fParameters.add(DescriptorPart.fromAsmType(asmType));
    }

    md.fReturnType = DescriptorPart.fromAsmType(org.objectweb.asm.Type.getReturnType(desc));

    return md;
  }
예제 #10
0
 private void unwrapResult(final MethodVisitor mv, final String desc) {
   Type returnType = Type.getReturnType(desc);
   if (returnType == Type.VOID_TYPE) {
     mv.visitInsn(POP);
     mv.visitInsn(RETURN);
   } else {
     if (isPrimitive(returnType)) {
       BytecodeHelper.unbox(mv, ClassHelper.make(returnType.getClassName()));
     } else {
       mv.visitTypeInsn(CHECKCAST, returnType.getInternalName());
     }
     mv.visitInsn(getReturnInsn(returnType));
   }
 }
예제 #11
0
 private InsnList generateInvokeDynamicVirtualInterfaceSpecial(
     String name, String owner, String desc, String bootstrapMethod) {
   InsnList insnList = new InsnList();
   Handle methodHandle =
       new Handle(Opcodes.H_INVOKESTATIC, BOOTSTRAP_CLASS, bootstrapMethod, BOOTSTRAP_SIGNATURE);
   List<Type> argsList =
       new ArrayList<Type>(Arrays.asList(new Type[] {Type.getObjectType(owner)}));
   argsList.addAll(Arrays.asList(Type.getArgumentTypes(desc)));
   String descReceiver =
       Type.getMethodDescriptor(
           Type.getReturnType(desc), argsList.toArray(new Type[argsList.size()]));
   insnList.add(new InvokeDynamicInsnNode(owner + "." + name, descReceiver, methodHandle, ""));
   return insnList;
 }
 /** Creates the 'invoke' method. */
 protected void createInvokeMethod() {
   String invokeDesc = buildInvokeMethodSignature();
   MethodVisitor cv =
       m_cw.visitMethod(
           ACC_PUBLIC + ACC_FINAL + ACC_STATIC,
           INVOKE_METHOD_NAME,
           invokeDesc,
           null,
           new String[] {THROWABLE_CLASS_NAME});
   AsmHelper.loadArgumentTypes(cv, Type.getArgumentTypes(invokeDesc), true);
   cv.visitMethodInsn(
       INVOKESTATIC, m_redefinedModel.getJoinPointClassName(), INVOKE_METHOD_NAME, invokeDesc);
   AsmHelper.addReturnStatement(cv, Type.getReturnType(invokeDesc));
   cv.visitMaxs(0, 0);
 }
예제 #13
0
    private String getMethodDescriptor(String methodDescriptor) {
      Type[] argumentTypes = Type.getArgumentTypes(methodDescriptor);
      Type returnType = Type.getReturnType(methodDescriptor);

      StringBuilder sb = new StringBuilder();
      sb.append('(');
      for (int i = 0; i < argumentTypes.length; i++) {
        sb.append(getDescriptor(argumentTypes[i]));
        if (i + 1 < argumentTypes.length) {
          sb.append(", ");
        }
      }
      sb.append(')');
      sb.append(getDescriptor(returnType));

      return sb.toString();
    }
예제 #14
0
      /** @see org.objectweb.asm.MethodVisitor#visitMethodInsn(int, String, String, String) */
      public void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
        if (owner.charAt(0) == '[') {
          Type type = Type.getType(owner);
          inspectType(type);
        } else {
          String typeName = refactor(owner.replace('/', '.'));
          checkReference(typeName);
        }

        inspectType(Type.getReturnType(descriptor));

        Type[] types = Type.getArgumentTypes(descriptor);

        for (int i = 0; i < types.length; i++) {
          inspectType(types[i]);
        }
      }
예제 #15
0
 protected static Set<String> makeMethodSet(ClassNode node) {
   Set<String> sigs = Sets.newHashSet();
   @SuppressWarnings("unchecked")
   List<MethodNode> meths = node.methods;
   for (MethodNode meth : meths) {
     StringBuilder builder = new StringBuilder(Type.getReturnType(meth.desc).getClassName());
     builder.append(' ').append(meth.name).append('(');
     Type[] args = Type.getArgumentTypes(meth.desc);
     for (int ii = 0; ii < args.length; ii++) {
       builder.append(args[ii].getClassName());
       if (ii < args.length - 1) {
         builder.append(", ");
       }
     }
     builder.append(')');
     sigs.add(builder.toString());
   }
   return sigs;
 }
예제 #16
0
 @Override
 public MethodVisitor visitMethod(
     int flags,
     String name,
     String desc,
     @Nullable String signature,
     @Nullable String[] exceptions) {
   Preconditions.checkNotNull(name);
   Preconditions.checkNotNull(desc);
   if (!BytecodeCompleter.isSynthetic(flags)) {
     Preconditions.checkState(
         (flags & Opcodes.ACC_BRIDGE) == 0,
         "bridge method not marked as synthetic in class " + className);
     // TODO(Godin): according to JVMS 4.7.24 - parameter can be marked as synthetic
     MethodJavaType type =
         new MethodJavaType(
             convertAsmTypes(org.objectweb.asm.Type.getArgumentTypes(desc)),
             convertAsmType(org.objectweb.asm.Type.getReturnType(desc)),
             getCompletedClassSymbolsType(exceptions),
             classSymbol);
     final JavaSymbol.MethodJavaSymbol methodSymbol =
         new JavaSymbol.MethodJavaSymbol(
             bytecodeCompleter.filterBytecodeFlags(flags), name, type, classSymbol);
     classSymbol.members.enter(methodSymbol);
     if (signature != null) {
       SignatureReader signatureReader = new SignatureReader(signature);
       signatureReader.accept(new TypeParameterDeclaration(methodSymbol));
       signatureReader.accept(new ReadMethodSignature(methodSymbol));
     }
     methodSymbol.parameters = new Scope(methodSymbol);
     for (int i = 0; i < type.argTypes.size(); i += 1) {
       methodSymbol.parameters.enter(
           new JavaSymbol.VariableJavaSymbol(0, "arg" + i, methodSymbol));
     }
     // checks for annotations on the method and its parameters
     return new BytecodeMethodVisitor(methodSymbol, this);
   }
   return null;
 }
  /**
   * Adds the mixin methods to the target class.
   *
   * @param fieldInfo
   * @param mixinDef
   */
  private void addMixinMethods(final MixinFieldInfo fieldInfo, final MixinDefinition mixinDef) {
    for (Iterator it3 = mixinDef.getMethodsToIntroduce().iterator(); it3.hasNext(); ) {
      MethodInfo methodInfo = (MethodInfo) it3.next();
      final String methodName = methodInfo.getName();
      final String methodSignature = methodInfo.getSignature();

      if (m_addedMethods.contains(
          AlreadyAddedMethodVisitor.getMethodKey(methodName, methodSignature))) {
        continue;
      }

      MethodVisitor mv =
          cv.visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, methodName, methodSignature, null, null);
      if (fieldInfo.isStatic) {
        mv.visitFieldInsn(
            GETSTATIC,
            m_declaringTypeName,
            fieldInfo.fieldName,
            fieldInfo.mixinClassInfo.getSignature());
      } else {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD,
            m_declaringTypeName,
            fieldInfo.fieldName,
            fieldInfo.mixinClassInfo.getSignature());
      }
      AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(methodSignature), false);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          fieldInfo.mixinClassInfo.getName().replace('.', '/'),
          methodName,
          methodSignature);
      AsmHelper.addReturnStatement(mv, Type.getReturnType(methodSignature));
      mv.visitMaxs(0, 0);
    }
  }
예제 #18
0
    /** @see org.objectweb.asm.ClassVisitor#visitMethod(int, String, String, String, String[]) */
    public MethodVisitor visitMethod(
        int access, String name, String descriptor, String signature, String[] exceptions) {

      inspectType(Type.getReturnType(descriptor));

      Type[] types = Type.getArgumentTypes(descriptor);

      for (int i = 0; i < types.length; i++) {
        inspectType(types[i]);
      }

      if (signature != null) {
        new SignatureReader(signature).accept(new SignatureInspector());
      }

      if (exceptions != null) {
        for (int i = 0; i < exceptions.length; i++) {
          String typeName = refactor(exceptions[i].replace('/', '.'));
          checkReference(typeName);
        }
      }

      return new MethodInspector();
    }
예제 #19
0
 @Override
 public MethodVisitor visitMethod(
     final int access,
     final String name,
     final String desc,
     final String signature,
     final String[] exceptions) {
   Object key = Arrays.asList(name, desc);
   if (visitedMethods.contains(key)) return EMPTY_VISITOR;
   if (Modifier.isPrivate(access)
       || Modifier.isNative(access)
       || ((access & ACC_SYNTHETIC) != 0)) {
     // do not generate bytecode for private methods
     return EMPTY_VISITOR;
   }
   int accessFlags = access;
   visitedMethods.add(key);
   if ((objectDelegateMethods.contains(name)
           || delegatedClosures.containsKey(name)
           || (!"<init>".equals(name) && hasWildcard))
       && !Modifier.isStatic(access)
       && !Modifier.isFinal(access)) {
     if (!GROOVYOBJECT_METHOD_NAMESS.contains(name)) {
       if (Modifier.isAbstract(access)) {
         // prevents the proxy from being abstract
         accessFlags -= ACC_ABSTRACT;
       }
       if (delegatedClosures.containsKey(name) || (!"<init>".equals(name) && hasWildcard)) {
         delegatedClosures.put(name, Boolean.TRUE);
         return makeDelegateToClosureCall(name, desc, signature, exceptions, accessFlags);
       }
       if (generateDelegateField && objectDelegateMethods.contains(name)) {
         return makeDelegateCall(name, desc, signature, exceptions, accessFlags);
       }
       delegatedClosures.put(name, Boolean.TRUE);
       return makeDelegateToClosureCall(name, desc, signature, exceptions, accessFlags);
     }
   } else if ("<init>".equals(name)
       && (Modifier.isPublic(access) || Modifier.isProtected(access))) {
     return createConstructor(access, name, desc, signature, exceptions);
   } else if (Modifier.isAbstract(access) && !GROOVYOBJECT_METHOD_NAMESS.contains(name)) {
     accessFlags -= ACC_ABSTRACT;
     MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
     mv.visitCode();
     Type[] args = Type.getArgumentTypes(desc);
     if (emptyBody) {
       Type returnType = Type.getReturnType(desc);
       if (returnType == Type.VOID_TYPE) {
         mv.visitInsn(RETURN);
       } else {
         int loadIns = getLoadInsn(returnType);
         switch (loadIns) {
           case ILOAD:
             mv.visitInsn(ICONST_0);
             break;
           case LLOAD:
             mv.visitInsn(LCONST_0);
             break;
           case FLOAD:
             mv.visitInsn(FCONST_0);
             break;
           case DLOAD:
             mv.visitInsn(DCONST_0);
             break;
           default:
             mv.visitInsn(ACONST_NULL);
         }
         mv.visitInsn(getReturnInsn(returnType));
         mv.visitMaxs(2, registerLen(args) + 1);
       }
     } else {
       // for compatibility with the legacy proxy generator, we should throw an
       // UnsupportedOperationException
       // instead of an AbtractMethodException
       mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
       mv.visitInsn(DUP);
       mv.visitMethodInsn(
           INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "()V");
       mv.visitInsn(ATHROW);
       mv.visitMaxs(2, registerLen(args) + 1);
     }
     mv.visitEnd();
   }
   return EMPTY_VISITOR;
 }
예제 #20
0
 public Type getReturnType() {
     return Type.getReturnType(desc);
 }
 private void addMethodTypes(final String desc) {
   addType(Type.getReturnType(desc));
   for (Type each : Type.getArgumentTypes(desc)) {
     addType(each);
   }
 }
  private ClassObject parseBytecode(File file) {
    final ClassObject co = new ClassObject();
    try {
      FileInputStream fin = new FileInputStream(file);
      ClassReader cr = new ClassReader(new DataInputStream(fin));
      ClassNode cn = new ClassNode();
      cr.accept(cn, ClassReader.SKIP_DEBUG);

      String name = cn.name;
      co.setName(name.replaceAll("/", "."));

      if ((cn.access & Opcodes.ACC_INTERFACE) != 0) co.setInterface(true);
      else if ((cn.access & Opcodes.ACC_ABSTRACT) != 0) co.setAbstract(true);

      if ((cn.access & Opcodes.ACC_PUBLIC) != 0) co.setAccess(Access.PUBLIC);
      else if ((cn.access & Opcodes.ACC_PROTECTED) != 0) co.setAccess(Access.PROTECTED);
      else if ((cn.access & Opcodes.ACC_PRIVATE) != 0) co.setAccess(Access.PRIVATE);
      if ((cn.access & Opcodes.ACC_STATIC) != 0) co.setStatic(true);

      String superClass = cn.superName;
      co.setSuperclass(superClass.replaceAll("/", "."));

      List interfaces = cn.interfaces;
      for (Object anInterface : interfaces) {
        String interfaceString = (String) anInterface;
        co.addInterface(interfaceString.replaceAll("/", "."));
      }

      List fields = cn.fields;
      for (Object field : fields) {
        FieldNode fieldNode = (FieldNode) field;
        Type fieldType = Type.getType(fieldNode.desc);
        TypeObject typeObject = new TypeObject(fieldType.getClassName());
        if (fieldNode.signature != null) {
          TraceSignatureVisitor v = new TraceSignatureVisitor(ClassReader.SKIP_DEBUG);
          SignatureReader r = new SignatureReader(fieldNode.signature);
          r.accept(v);
          String declaration = v.getDeclaration();
          if (declaration.contains("<") && declaration.contains(">"))
            typeObject.setGeneric(
                declaration.substring(declaration.indexOf("<") + 1, declaration.lastIndexOf(">")));
        }
        FieldObject fo = new FieldObject(typeObject, fieldNode.name);

        if ((fieldNode.access & Opcodes.ACC_PUBLIC) != 0) fo.setAccess(Access.PUBLIC);
        else if ((fieldNode.access & Opcodes.ACC_PROTECTED) != 0) fo.setAccess(Access.PROTECTED);
        else if ((fieldNode.access & Opcodes.ACC_PRIVATE) != 0) fo.setAccess(Access.PRIVATE);
        if ((fieldNode.access & Opcodes.ACC_STATIC) != 0) fo.setStatic(true);
        co.addField(fo);
      }

      List methods = cn.methods;
      for (Object method : methods) {
        MethodNode methodNode = (MethodNode) method;

        final ConstructorObject constructorObject = new ConstructorObject();

        if ((methodNode.access & Opcodes.ACC_PUBLIC) != 0)
          constructorObject.setAccess(Access.PUBLIC);
        else if ((methodNode.access & Opcodes.ACC_PROTECTED) != 0)
          constructorObject.setAccess(Access.PROTECTED);
        else if ((methodNode.access & Opcodes.ACC_PRIVATE) != 0)
          constructorObject.setAccess(Access.PRIVATE);

        if (methodNode.signature != null) {
          TraceSignatureVisitor v = new TraceSignatureVisitor(ClassReader.SKIP_DEBUG);
          SignatureReader r = new SignatureReader(methodNode.signature);
          r.accept(v);
          String declaration = v.getDeclaration();
          String temp = declaration;
          if (temp.startsWith("(")) temp = temp.substring(1, temp.length());
          if (temp.endsWith("")) temp = temp.substring(0, temp.length() - 1);
          if (!temp.equals("")) {
            ParameterAnalyzer analyzer = new ParameterAnalyzer(temp);
            for (String token : analyzer.getParameters()) {
              if (token.contains("<") && token.contains(">")) {
                TypeObject typeObject = new TypeObject(token.substring(0, token.indexOf("<")));
                typeObject.setGeneric(
                    token.substring(token.indexOf("<") + 1, token.lastIndexOf(">")));
                constructorObject.addParameter(typeObject);
              } else {
                constructorObject.addParameter(new TypeObject(token));
              }
            }
          }
        } else {
          Type[] argumentTypes = Type.getArgumentTypes(methodNode.desc);
          for (Type argumentType : argumentTypes)
            constructorObject.addParameter(new TypeObject(argumentType.getClassName()));
        }
        if (methodNode.instructions.size() > 0) {
          Map<String, Integer> labelIndexMap = new HashMap<String, Integer>();
          List<LoopObject> activeLoops = new ArrayList<LoopObject>();

          Iterator insnIt = methodNode.instructions.iterator();
          int index = 0;
          while (insnIt.hasNext()) {
            AbstractInsnNode ainsn = (AbstractInsnNode) insnIt.next();

            if (ainsn instanceof LabelNode) {
              LabelNode labelNode = (LabelNode) ainsn;
              Label label = labelNode.getLabel();
              LoopObject loop = new LoopObject(label.toString());
              activeLoops.add(loop);
              labelIndexMap.put(label.toString(), index);
            }

            if (ainsn instanceof JumpInsnNode) {
              JumpInsnNode jumpNode = (JumpInsnNode) ainsn;
              Label label = jumpNode.label.getLabel();
              if (labelIndexMap.containsKey(label.toString())) {
                LoopObject matchingLoop = null;
                for (LoopObject loop : activeLoops) {
                  if (loop.getLabel().equals(label.toString())) {
                    matchingLoop = loop;
                    break;
                  }
                }
                if (matchingLoop != null) {
                  constructorObject.addLoop(matchingLoop);
                  activeLoops.remove(matchingLoop);
                }
              }
            }

            if (ainsn instanceof FieldInsnNode) {
              FieldInsnNode fieldInsnNode = (FieldInsnNode) ainsn;
              Type fieldType = Type.getType(fieldInsnNode.desc);
              FieldInstructionObject fieldObject =
                  new FieldInstructionObject(
                      fieldInsnNode.owner.replaceAll("/", "."),
                      fieldType.getClassName(),
                      fieldInsnNode.name);
              constructorObject.addFieldInstruction(fieldObject);
              for (LoopObject loop : activeLoops) {
                loop.addFieldInstruction(fieldObject);
              }
            }

            if ((ainsn.getOpcode() == Opcodes.INVOKEVIRTUAL)
                || (ainsn.getOpcode() == Opcodes.INVOKESTATIC)
                || (ainsn.getOpcode() == Opcodes.INVOKESPECIAL)
                || (ainsn.getOpcode() == Opcodes.INVOKEINTERFACE)) {

              MethodInsnNode minsn = (MethodInsnNode) ainsn;
              MethodInvocationObject mio =
                  new MethodInvocationObject(
                      minsn.owner.replaceAll("/", "."),
                      minsn.name,
                      Type.getReturnType(minsn.desc).getClassName());
              Type[] argTypes = Type.getArgumentTypes(minsn.desc);
              for (Type argType : argTypes) mio.addParameter(argType.getClassName());

              constructorObject.addMethodInvocation(mio);
              for (LoopObject loop : activeLoops) {
                loop.addMethodInvocation(mio);
              }
            }

            if ((ainsn.getOpcode() == Opcodes.NEW) || (ainsn.getOpcode() == Opcodes.ANEWARRAY)) {

              TypeInsnNode tinsn = (TypeInsnNode) ainsn;
              constructorObject.addObjectInstantiation(tinsn.desc.replaceAll("/", "."));
            }
            index++;
          }
        }

        if (methodNode.name.equals("<init>")) {
          constructorObject.setName(co.getName());
          co.addConstructor(constructorObject);
        } else {
          Type returnType = Type.getReturnType(methodNode.desc);
          constructorObject.setName(methodNode.name);
          MethodObject methodObject = new MethodObject(constructorObject);
          TypeObject typeObject = new TypeObject(returnType.getClassName());
          if (methodNode.signature != null) {
            TraceSignatureVisitor v = new TraceSignatureVisitor(ClassReader.SKIP_DEBUG);
            SignatureReader r = new SignatureReader(methodNode.signature);
            r.accept(v);
            String genericReturnType = v.getReturnType();
            if (genericReturnType.contains("<") && genericReturnType.contains(">"))
              typeObject.setGeneric(
                  genericReturnType.substring(
                      genericReturnType.indexOf("<") + 1, genericReturnType.lastIndexOf(">")));
          }

          methodObject.setReturnType(typeObject);
          methodObject.setClassName(co.getName());
          if ((methodNode.access & Opcodes.ACC_ABSTRACT) != 0) methodObject.setAbstract(true);
          if ((methodNode.access & Opcodes.ACC_STATIC) != 0) methodObject.setStatic(true);
          co.addMethod(methodObject);
        }
      }
      fin.close();
    } catch (FileNotFoundException fnfe) {
      fnfe.printStackTrace();
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }

    return co;
  }
예제 #23
0
 /** {@inheritDoc} */
 public ClassMetadata getMethodReturnType(ClassMetadataResolver resolver, String desc) {
   return getClassMetadata(resolver, Type.getReturnType(desc), false);
 }