@Override
  protected void onApply(CtBehavior behavior, Bytecode bytecode) throws BadBytecode {

    bytecode = BytecodeTools.prepareMethodForBytecode(behavior, bytecode);

    // loop through the opcodes and change any GT/GE opcodes to ICMPGT/ICMPGE
    CodeIterator iterator = behavior.getMethodInfo().getCodeAttribute().iterator();
    while (iterator.hasNext()) {
      int index = iterator.next();
      int opcode = iterator.byteAt(index);
      switch (opcode) {
        case Opcode.IFGT:

          // overwrite the opcode
          iterator.writeByte(Opcode.IF_ICMPGT, index);

          // insert the method call
          iterator.insertAt(index, bytecode.get());
          behavior.getMethodInfo().getCodeAttribute().computeMaxStack();

          break;

        case Opcode.IFGE:

          // overwrite the opcode
          iterator.writeByte(Opcode.IF_ICMPGE, index);

          // insert the method call
          iterator.insertAt(index, bytecode.get());
          behavior.getMethodInfo().getCodeAttribute().computeMaxStack();

          break;
      }
    }
  }
Example #2
0
  /**
   * Return javaassist source snippet which lists all the parameters and their values. If available
   * the source names are extracted from the debug information and used, otherwise just a number is
   * shown.
   *
   * @param method
   * @return
   * @throws NotFoundException
   */
  public static String getSignature(CtBehavior method) throws NotFoundException {

    CtClass[] parameterTypes = method.getParameterTypes();

    CodeAttribute codeAttribute = method.getMethodInfo().getCodeAttribute();

    LocalVariableAttribute locals = null;

    if (codeAttribute != null) {
      AttributeInfo attribute;
      attribute = codeAttribute.getAttribute("LocalVariableTable");
      locals = (LocalVariableAttribute) attribute;
    }

    String methodName = method.getName();

    StringBuilder sb = new StringBuilder(methodName).append("(\" ");
    for (int i = 0; i < parameterTypes.length; i++) {
      if (i > 0) {
        // add a comma and a space between printed values
        sb.append(" + \", \" ");
      }

      CtClass parameterType = parameterTypes[i];
      boolean isArray = parameterType.isArray();
      CtClass arrayType = parameterType.getComponentType();
      if (isArray) {
        while (arrayType.isArray()) {
          arrayType = arrayType.getComponentType();
        }
      }

      sb.append(" + \"");
      try {
        sb.append(parameterNameFor(method, locals, i));
      } catch (Exception e) {
        sb.append(i + 1);
      }
      sb.append("\" + \"=");

      if (parameterType.isPrimitive()) {
        // let the compiler handle primitive -> string
        sb.append("\"+ $").append(i + 1);
      } else {
        String s = "org.slf4j.instrumentation.ToStringHelper.render";
        sb.append("\"+ ").append(s).append("($").append(i + 1).append(')');
      }
    }
    sb.append("+\")");

    String signature = sb.toString();
    return signature;
  }