private void addUserDefinedMethods(TopLevelClass exampleClass, Interface mapperClass, IntrospectedTable introspectedTable, MyBatisClasses cls) {
        for (Method action : mapperClass.getMethods()) {
            if (!userDefinedMethods.matcher(action.getName()).matches()) continue;
            StringBuilder args = new StringBuilder();
            List<Parameter> params = new ArrayList<Parameter>();
            boolean example = false;
            if (action.getParameters() != null)
                for (Parameter param : action.getParameters()) {
                    String name;
                    if (Objects.equals(param.getType(), exampleClass.getType())) {
                        example = true;
                        name = "this";
                    } else {
                        name = param.getName();
                        params.add(new Parameter(param.getType(), name));
                    }
                    if (args.length() > 0)
                        args.append(", ");
                    args.append(name);
                }
            if (!example) {
                //System.err.println("Invalid user-defined mapper method: "+action.getName());
                continue;
            }

            exampleClass.addMethod(method(
                PUBLIC, INT, action.getName(), _(sqlSession, "sql"), params.toArray(new Parameter[params.size()]), __(
                    "return sql.getMapper(" + cls.names.mapper + ".class)."+action.getName()+"("+args+");"
            )));
            exampleClass.addMethod(method(
                PUBLIC, INT, action.getName(), _(cls.types.mapper, "mapper"), params.toArray(new Parameter[params.size()]), __(
                    "return mapper."+action.getName()+"("+args+");"
            )));
        }
    }
Beispiel #2
0
  /**
   * Marks the hierarchy of implementing or overriding methods corresponding to the given method, if
   * any.
   */
  protected void markMethodHierarchy(Clazz clazz, Method method) {
    int accessFlags = method.getAccessFlags();
    if ((accessFlags & (ClassConstants.ACC_PRIVATE | ClassConstants.ACC_STATIC)) == 0
        && !ClassUtil.isInitializer(method.getName(clazz))) {
      // We can skip private and static methods in the hierarchy, and
      // also abstract methods, unless they might widen a current
      // non-public access.
      int requiredUnsetAccessFlags =
          ClassConstants.ACC_PRIVATE
              | ClassConstants.ACC_STATIC
              | ((accessFlags & ClassConstants.ACC_PUBLIC) == 0 ? 0 : ClassConstants.ACC_ABSTRACT);

      clazz.accept(
          new ConcreteClassDownTraveler(
              new ClassHierarchyTraveler(
                  true,
                  true,
                  false,
                  true,
                  new NamedMethodVisitor(
                      method.getName(clazz),
                      method.getDescriptor(clazz),
                      new MemberAccessFilter(0, requiredUnsetAccessFlags, this)))));
    }
  }
Beispiel #3
0
  public static Map<String, Object> getAnnotationValues(Annotation annotation) {
    ClassType type = TypeOracle.Instance.getClassType(annotation.annotationType());
    if (type == null) reflectionRequired(annotation.annotationType().getName(), "");

    Map<String, Object> result = new HashMap<String, Object>();

    Method[] methods = type.getMethods();
    for (Method method : methods) {
      result.put(method.getName(), getAnnotationValueByName(annotation, method.getName()));
    }

    return result;
  }
Beispiel #4
0
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    //        DEBUG =
    //            clazz.getName().equals("abc/Def") &&
    //            method.getName(clazz).equals("abc");

    // The minimum variable size is determined by the arguments.
    codeAttribute.u2maxLocals =
        ClassUtil.internalMethodParameterSize(method.getDescriptor(clazz), method.getAccessFlags());

    if (DEBUG) {
      System.out.println(
          "VariableSizeUpdater: "
              + clazz.getName()
              + "."
              + method.getName(clazz)
              + method.getDescriptor(clazz));
      System.out.println("  Max locals: " + codeAttribute.u2maxLocals + " <- parameters");
    }

    // Go over all instructions.
    codeAttribute.instructionsAccept(clazz, method, this);

    // Remove the unused variables of the attributes.
    codeAttribute.attributesAccept(clazz, method, variableCleaner);
  }
  public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    if (DEBUG) {
      System.out.println(
          "StackSizeComputer: "
              + clazz.getName()
              + "."
              + method.getName(clazz)
              + method.getDescriptor(clazz));
    }

    // Try to reuse the previous array.
    int codeLength = codeAttribute.u4codeLength;
    if (evaluated.length < codeLength) {
      evaluated = new boolean[codeLength];
      stackSizes = new int[codeLength];
    } else {
      Arrays.fill(evaluated, 0, codeLength, false);
    }

    // The initial stack is always empty.
    stackSize = 0;
    maxStackSize = 0;

    // Evaluate the instruction block starting at the entry point of the method.
    evaluateInstructionBlock(clazz, method, codeAttribute, 0);

    // Evaluate the exception handlers.
    codeAttribute.exceptionsAccept(clazz, method, this);
  }
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    //        DEBUG =
    //            clazz.getName().equals("abc/Def") &&
    //            method.getName(clazz).equals("abc");

    // TODO: Remove this when the code has stabilized.
    // Catch any unexpected exceptions from the actual visiting method.
    try {
      // Process the code.
      visitCodeAttribute0(clazz, method, codeAttribute);
    } catch (RuntimeException ex) {
      System.err.println("Unexpected error while computing stack sizes:");
      System.err.println("  Class       = [" + clazz.getName() + "]");
      System.err.println(
          "  Method      = [" + method.getName(clazz) + method.getDescriptor(clazz) + "]");
      System.err.println(
          "  Exception   = [" + ex.getClass().getName() + "] (" + ex.getMessage() + ")");

      if (DEBUG) {
        method.accept(clazz, new ClassPrinter());
      }

      throw ex;
    }
  }
    private void addCriteriaMethods(TopLevelClass topLevelClass, int newMethodsStart) {
        if (!generateCriteriaMethods) return;
        InnerClass criteria = null;
        for (InnerClass c : topLevelClass.getInnerClasses()) {
            if (c.getType().getShortName().equals("Criteria")) criteria = c;
        }
        if (criteria == null) return;
        boolean owner = false;
        for (Field f : criteria.getFields()) if (ExampleMethodsChainPlugin.OWNER.equals(f.getName())) owner = true;
        if (!owner) return;

        for (ListIterator<Method> methods = topLevelClass.getMethods().listIterator(newMethodsStart); methods.hasNext(); ) {
            Method base = methods.next();
            if (base.getVisibility() != PUBLIC || base.isStatic() || base.isConstructor()) continue;
            Method m = method(PUBLIC, base.getReturnType(), base.getName());
            StringBuilder sb = new StringBuilder();
            sb.append("return ").append(ExampleMethodsChainPlugin.OWNER).append(".").append(base.getName()).append("(");
            for (ListIterator<Parameter> params = base.getParameters().listIterator(); params.hasNext(); ) {
                if (params.hasPrevious()) sb.append(", ");
                Parameter p = params.next();
                m.addParameter(new Parameter(p.getType(), p.getName()));
                sb.append(p.getName());
            }
            sb.append(");");
            m.addBodyLine(sb.toString());
            criteria.addMethod(m);
        }
    }
Beispiel #8
0
  /**
   * Marks the hierarchy of implementing or overriding methods corresponding to the given method, if
   * any.
   */
  protected void markMethodHierarchy(Clazz clazz, Method method) {
    int accessFlags = method.getAccessFlags();
    if ((accessFlags & (ClassConstants.ACC_PRIVATE | ClassConstants.ACC_STATIC)) == 0
        && !ClassUtil.isInitializer(method.getName(clazz))) {
      // We can skip private and static methods in the hierarchy, and
      // also abstract methods, unless they might widen a current
      // non-public access.
      int requiredUnsetAccessFlags =
          ClassConstants.ACC_PRIVATE
              | ClassConstants.ACC_STATIC
              | ((accessFlags & ClassConstants.ACC_PUBLIC) == 0 ? 0 : ClassConstants.ACC_ABSTRACT);

      // Mark default implementations in interfaces down the hierarchy.
      // TODO: This may be premature if there aren't any concrete implementing classes.
      clazz.accept(
          new ClassAccessFilter(
              ClassConstants.ACC_ABSTRACT,
              0,
              new ClassHierarchyTraveler(
                  false,
                  false,
                  false,
                  true,
                  new ProgramClassFilter(
                      new ClassAccessFilter(
                          ClassConstants.ACC_ABSTRACT,
                          0,
                          new NamedMethodVisitor(
                              method.getName(clazz),
                              method.getDescriptor(clazz),
                              new MemberAccessFilter(
                                  0, requiredUnsetAccessFlags, defaultMethodUsageMarker)))))));

      // Mark other implementations.
      clazz.accept(
          new ConcreteClassDownTraveler(
              new ClassHierarchyTraveler(
                  true,
                  true,
                  false,
                  true,
                  new NamedMethodVisitor(
                      method.getName(clazz),
                      method.getDescriptor(clazz),
                      new MemberAccessFilter(0, requiredUnsetAccessFlags, this)))));
    }
  }
Beispiel #9
0
  /** @return method object with given name and signature, or null */
  public Method containsMethod(String name, String signature) {
    for (Iterator e = method_vec.iterator(); e.hasNext(); ) {
      Method m = (Method) e.next();
      if (m.getName().equals(name) && m.getSignature().equals(signature)) return m;
    }

    return null;
  }
 @Nullable
 public static Method getClassMethod(PhpClass phpClass, String methodName) {
   for (Method method : phpClass.getMethods()) {
     if (method.getName().equals(methodName)) {
       return method;
     }
   }
   return null;
 }
 /** @see AbstractReferenceCheck */
 public boolean ignore(String aClassName, Method aMethod) {
   final String methodName = aMethod.getName();
   return (
   /*super.ignore(aClassName, aMethod)
   || */ methodName.equals("<init>")
       || methodName.equals("<clinit>")
       || methodName.equals("class$")
       || aMethod.toString().indexOf("[Synthetic]") > -1);
 }
Beispiel #12
0
  /**
   * Return method with given name
   *
   * @param name
   * @return
   */
  public Method getMethod(String name) {

    for (Method m : methods) {
      if (m.getName().equals(name)) {
        return m;
      }
    }

    return null;
  }
 public boolean mayHaveImplementations(Method method) {
   return (u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0
       && (method == null
           || ((method.getAccessFlags()
                       & (ClassConstants.INTERNAL_ACC_PRIVATE
                           | ClassConstants.INTERNAL_ACC_STATIC
                           | ClassConstants.INTERNAL_ACC_FINAL))
                   == 0
               && !method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)));
 }
  public static ArrayList<Method> getClassPublicMethod(PhpClass phpClass) {
    ArrayList<Method> methods = new ArrayList<Method>();

    for (Method method : phpClass.getMethods()) {
      if (method.getAccess().isPublic() && !method.getName().startsWith("__")) {
        methods.add(method);
      }
    }

    return methods;
  }
Beispiel #15
0
  public static String annotationToString(Annotation anno) {
    StringBuilder sb = new StringBuilder();

    sb.append(anno.annotationType().getName()).append("(");
    ClassType type = TypeOracle.Instance.getClassType(anno.annotationType());
    for (Method method : type.getMethods()) {
      sb.append(method.getName()).append("=").append(method.invoke(anno)).append(";");
    }
    sb.append(")");

    return sb.toString();
  }
Beispiel #16
0
  public static Method findMethodByName(ClassType classType, String methodName) {
    ClassType parent = classType;
    while (parent != null) {
      for (Method method : parent.getMethods()) {
        if (method.getName().equals(methodName)) return method;
      }

      parent = parent.getSuperclass();
    }

    return null;
  }
  private static ArrayList<Method> getImplementedMethods(
      @Nullable PhpClass phpClass, @NotNull Method method, ArrayList<Method> implementedMethods) {
    if (phpClass == null) {
      return implementedMethods;
    }

    Method[] methods = phpClass.getOwnMethods();
    for (Method ownMethod : methods) {
      if (PhpLangUtil.equalsMethodNames(ownMethod.getName(), method.getName())) {
        implementedMethods.add(ownMethod);
      }
    }

    for (PhpClass interfaceClass : phpClass.getImplementedInterfaces()) {
      getImplementedMethods(interfaceClass, method, implementedMethods);
    }

    getImplementedMethods(phpClass.getSuperClass(), method, implementedMethods);

    return implementedMethods;
  }
Beispiel #18
0
    public void visitMethod(Method method) {

      super.visitMethod(method);
      // now get the MethodInfo back from the ClassInfo for
      // additional work.
      String methodId = method.getName() + method.getSignature();
      OldMethodInfo mi = getITMethodInfo(methodId);
      if (JOPizer.dumpMgci) {
        // GCRT
        new GCRTMethodInfo(mi, method);
      }
    }
  public Method findMethod(String name, String descriptor) {
    for (int index = 0; index < methods.length; index++) {
      Method method = methods[index];
      if (method != null
          && (name == null || method.getName(this).equals(name))
          && (descriptor == null || method.getDescriptor(this).equals(descriptor))) {
        return method;
      }
    }

    return null;
  }
  public static void main(String[] args) {
    Class student = Student.class;
    Method[] methods = student.getDeclaredMethods();

    ArrayList<String> methodList = new ArrayList<>();
    for (Method method : methods) {
      methodList.add(method.getName());
    }
    Collections.sort(methodList);
    for (String name : methodList) {
      System.out.println(name);
    }
  }
 /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */
 public void visitObject(Object aJavaClass) {
   final JavaClass javaClass = (JavaClass) aJavaClass;
   final String className = javaClass.getClassName();
   final JavaClass[] superClasses = javaClass.getSuperClasses();
   final Method[] methods = javaClass.getMethods();
   // Check all methods
   for (int i = 0; i < methods.length; i++) {
     final Method method = methods[i];
     // Check that the method is a possible match
     if (!method.isPrivate() && method.isStatic()) {
       // Go through all their superclasses
       for (int j = 0; j < superClasses.length; j++) {
         final JavaClass superClass = superClasses[j];
         final String superClassName = superClass.getClassName();
         final Method[] superClassMethods = superClass.getMethods();
         // Go through the methods of the superclasses
         for (int k = 0; k < superClassMethods.length; k++) {
           final Method superClassMethod = superClassMethods[k];
           if (superClassMethod.getName().equals(method.getName()) && !ignore(className, method)) {
             Type[] methodTypes = method.getArgumentTypes();
             Type[] superTypes = superClassMethod.getArgumentTypes();
             if (methodTypes.length == superTypes.length) {
               boolean match = true;
               for (int arg = 0; arg < methodTypes.length; arg++) {
                 if (!methodTypes[arg].equals(superTypes[arg])) {
                   match = false;
                 }
               }
               // Same method parameters
               if (match) {
                 log(javaClass, 0, "hidden.static.method", new Object[] {method, superClassName});
               }
             }
           }
         }
       }
     }
   }
 }
  private void importMethod(DbJVClass dbClaz, Method method) throws DbException {
    if (dbClaz == null) {
      return;
    }

    String methodName = method.getName();
    boolean isConstructor = "<init>".equals(methodName);
    boolean isInitBlock = "<clinit>".equals(methodName);
    DbOOAbstractMethod oper = null;

    if (isInitBlock) {
      new DbJVInitBlock(dbClaz);
    } else if (isConstructor) {
      DbJVConstructor constr = new DbJVConstructor(dbClaz);
      importExceptions(constr, method);
      oper = constr;
    } else {
      // create method and return type
      DbJVMethod meth = new DbJVMethod(dbClaz);
      Type type = method.getReturnType();
      meth.setReturnType(toAdt(type));
      meth.setTypeUse(toTypeUse(type));

      // set method modifiers
      meth.setAbstract(method.isAbstract());
      meth.setFinal(method.isFinal());
      meth.setNative(method.isNative());
      meth.setStatic(method.isStatic());
      meth.setStrictfp(method.isStrictfp());
      meth.setSynchronized(method.isSynchronized());
      // method.isTransient()
      // method.isVolatile()
      importExceptions(meth, method);

      oper = meth;
    }

    // set name and visibility
    if (oper != null) {
      oper.setName(methodName);
      oper.setVisibility(toVisibility(method));

      // create parameters
      Type[] args = method.getArgumentTypes();
      for (Type arg : args) {
        DbJVParameter param = new DbJVParameter(oper);
        param.setType(toAdt(arg));
        param.setTypeUse(toTypeUse(arg));
      } // end for
    } // end if
  } // end importMethod()
Beispiel #23
0
 /**
  * Creates a new {@link GeneratorAdapter}.
  *
  * @param access access flags of the adapted method.
  * @param method the adapted method.
  * @param signature the signature of the adapted method (may be <tt>null</tt>).
  * @param exceptions the exceptions thrown by the adapted method (may be <tt>null</tt>).
  * @param cv the class visitor to which this adapter delegates calls.
  */
 public GeneratorAdapter(
     final int access,
     final Method method,
     final String signature,
     final Type[] exceptions,
     final ClassVisitor cv) {
   this(
       access,
       method,
       cv.visitMethod(
           access,
           method.getName(),
           method.getDescriptor(),
           signature,
           getInternalNames(exceptions)));
 }
Beispiel #24
0
  /**
   * Guess setter method of a field name if get more then 1 method, this function will raise an
   * error if you have the value to set into a field, please using getSetter(ClassType, fieldName,
   * ObjectVlaue)
   *
   * @param classType
   * @param fieldName
   * @return
   */
  public static Method getSetter(ClassType classType, String fieldName) {
    for (String methodName : getSetterNames(fieldName)) {
      List<Method> methods = new ArrayList<Method>();
      for (Method method : classType.getMethods()) {
        if ((method.getName().equals(methodName)) && (method.getParameters().length == 1)) {
          methods.add(method);
        }
      }

      if (methods.size() == 1) return methods.get(0);
      else {
        if (methods.size() > 1)
          throw new RuntimeException(
              "Found more then one setter of " + fieldName + " in class " + classType.getName());
      }
    }

    if (classType.getSuperclass() != null) return getSetter(classType.getSuperclass(), fieldName);

    return null;
  }
Beispiel #25
0
  @Test
  public void basicTest() {
    startTest("Basic Test");
    attr = Method.Create("- _name():String");

    assertNotNull(attr);

    assertTrue(attr.getName().equals("_name"));
    assertTrue(attr.getType().equals("String"));
    assertTrue(attr.getAccess() == Access.PRIVATE);

    assertFalse(attr.isStatic());
    assertFalse(attr.isAbstract());

    assertTrue(Method.Create("_name : String") == null);
    assertTrue(Method.Create("_name String") == null);

    // decided not to test
    // Method meth = Method.Create ( "_name( ) String " );

    passed();
  }
Beispiel #26
0
 /**
  * Marks the hierarchy of implementing or overriding methods corresponding to the given method, if
  * any.
  */
 protected void markMethodHierarchy(Clazz clazz, Method method) {
   if ((method.getAccessFlags()
           & (ClassConstants.INTERNAL_ACC_PRIVATE | ClassConstants.INTERNAL_ACC_STATIC))
       == 0) {
     clazz.accept(
         new ConcreteClassDownTraveler(
             new ClassHierarchyTraveler(
                 true,
                 true,
                 false,
                 true,
                 new NamedMethodVisitor(
                     method.getName(clazz),
                     method.getDescriptor(clazz),
                     new MemberAccessFilter(
                         0,
                         ClassConstants.INTERNAL_ACC_PRIVATE
                             | ClassConstants.INTERNAL_ACC_STATIC
                             | ClassConstants.INTERNAL_ACC_ABSTRACT,
                         this)))));
   }
 }
Beispiel #27
0
  /* Print the current type graph to the dotfile */
  public void printDot(String title, Call call) {
    boolean printUnifications = false;
    PrintStream ps = PointsToAnalysis.v().file;
    if (ps == null) return;

    ps.println("\ndigraph F {");
    ps.println("   size = \"7,7\"; rankdir = LR;");
    ps.println("   orientation = landscape;");

    ps.println("   subgraph cluster1 {");
    ps.println("   \"Method: " + method.getName() + "\" [color=white];");

    if (nodes.isEmpty()) {
      ps.println("   \"empty graph\" [color = white];");
      ps.println("   }");
      ps.println("}");
      return;
    }

    for (Node node : nodes) {
      if (!printUnifications && !node.isRep()) continue;
      String color = "style=filled,fillcolor=";
      if (node.isheap && node.hasallocs) color += "red,";
      else if (node.isheap) color += "orange,";
      else if (node.hasallocs) color += "grey,";
      else color += "white,";
      // if (node.istouched) color = "khaki";
      // if (node.hassync) color = "khaki";
      String shape = "shape=";
      if (node.istouched) shape += "box";
      else shape += "ellipse";

      ps.println("   o" + node.id + "[label = \"" + node.getName() + "\"," + color + shape + "];");
    }
    ps.println("   }");

    Map<Integer, Map<Integer, String>> labels = new HashMap<Integer, Map<Integer, String>>();
    for (Field f : fedges.keySet())
      for (FieldEdge e : fedges.get(f)) {
        if (labels.containsKey(e.src.id)) {
          if (labels.get(e.src.id).containsKey(e.dst.id)) {
            labels.get(e.src.id).put(e.dst.id, "*");
            //                            labels.get(e.src.id).get(e.dst.id) + ", " +
            //                            e.field.getName());
          } else labels.get(e.src.id).put(e.dst.id, e.field.getName());

        } else {
          Map<Integer, String> is = new HashMap<Integer, String>();
          is.put(e.dst.id, e.field.getName());
          labels.put(e.src.id, is);
        }
      }
    for (Integer i : labels.keySet())
      for (Integer j : labels.get(i).keySet())
        ps.print(
            "   o"
                + i
                + " -> o"
                + j
                + "[label=\""
                + labels.get(i).get(j)
                + "\",style=solid,color=black];");

    for (Call ce : cedges.keySet())
      for (CallEdge e : cedges.get(ce)) {
        if (!(e.call instanceof VirtualCallExpr)) continue;
        // if (!e.call.equals(call)) continue;
        ps.print(
            "   o"
                + e.src.id
                + " -> o"
                + e.dst.id
                + "[label=\""
                + e.call
                + "\",style=solid,color=red];");
      }

    if (printUnifications)
      for (Node node : nodes)
        if (node.parent != null)
          ps.println("   o" + node.id + " -> o" + node.parent.id + " [color = blue];");

    ps.println("}");
  }
  /**
   * Evaluates a block of instructions that hasn't been handled before, starting at the given offset
   * and ending at a branch instruction, a return instruction, or a throw instruction. Branch
   * instructions are handled recursively.
   */
  private void evaluateInstructionBlock(
      Clazz clazz, Method method, CodeAttribute codeAttribute, int instructionOffset) {
    if (DEBUG) {
      if (evaluated[instructionOffset]) {
        System.out.println("-- (instruction block at " + instructionOffset + " already evaluated)");
      } else {
        System.out.println("-- instruction block:");
      }
    }

    // Remember the initial stack size.
    int initialStackSize = stackSize;

    // Remember the maximum stack size.
    if (maxStackSize < stackSize) {
      maxStackSize = stackSize;
    }

    // Evaluate any instructions that haven't been evaluated before.
    while (!evaluated[instructionOffset]) {
      // Mark the instruction as evaluated.
      evaluated[instructionOffset] = true;

      Instruction instruction = InstructionFactory.create(codeAttribute.code, instructionOffset);

      if (DEBUG) {
        int stackPushCount = instruction.stackPushCount(clazz);
        int stackPopCount = instruction.stackPopCount(clazz);
        System.out.println(
            "["
                + instructionOffset
                + "]: "
                + stackSize
                + " - "
                + stackPopCount
                + " + "
                + stackPushCount
                + " = "
                + (stackSize + stackPushCount - stackPopCount)
                + ": "
                + instruction.toString(instructionOffset));
      }

      // Compute the instruction's effect on the stack size.
      stackSize -= instruction.stackPopCount(clazz);

      if (stackSize < 0) {
        throw new IllegalArgumentException(
            "Stack size becomes negative after instruction "
                + instruction.toString(instructionOffset)
                + " in ["
                + clazz.getName()
                + "."
                + method.getName(clazz)
                + method.getDescriptor(clazz)
                + "]");
      }

      stackSizes[instructionOffset] = stackSize += instruction.stackPushCount(clazz);

      // Remember the maximum stack size.
      if (maxStackSize < stackSize) {
        maxStackSize = stackSize;
      }

      // Remember the next instruction offset.
      int nextInstructionOffset = instructionOffset + instruction.length(instructionOffset);

      // Visit the instruction, in order to handle branches.
      instruction.accept(clazz, method, codeAttribute, instructionOffset, this);

      // Stop evaluating after a branch.
      if (exitInstructionBlock) {
        break;
      }

      // Continue with the next instruction.
      instructionOffset = nextInstructionOffset;

      if (DEBUG) {
        if (evaluated[instructionOffset]) {
          System.out.println("-- (instruction at " + instructionOffset + " already evaluated)");
        }
      }
    }

    // Restore the stack size for possible subsequent instruction blocks.
    this.stackSize = initialStackSize;
  }
  public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) {
    //        DEBUG =
    //            clazz.getName().equals("abc/Def") &&
    //            method.getName(clazz).equals("abc");

    if (DEBUG) {
      method.accept(clazz, new ClassPrinter());
    }

    branchTargetFinder.visitCodeAttribute(clazz, method, codeAttribute);

    // Don't bother if there aren't any subroutines anyway.
    if (!containsSubroutines(codeAttribute)) {
      return;
    }

    if (DEBUG) {
      System.out.println(
          "SubroutineInliner: processing ["
              + clazz.getName()
              + "."
              + method.getName(clazz)
              + method.getDescriptor(clazz)
              + "]");
    }

    // Append the body of the code.
    codeAttributeComposer.reset();
    codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);

    // Copy the non-subroutine instructions.
    int offset = 0;
    while (offset < codeAttribute.u4codeLength) {
      Instruction instruction = InstructionFactory.create(codeAttribute.code, offset);
      int instructionLength = instruction.length(offset);

      // Is this returning subroutine?
      if (branchTargetFinder.isSubroutine(offset)
          && branchTargetFinder.isSubroutineReturning(offset)) {
        // Skip the subroutine.
        if (DEBUG) {
          System.out.println(
              "  Skipping original subroutine instruction " + instruction.toString(offset));
        }

        // Append a label at this offset instead.
        codeAttributeComposer.appendLabel(offset);
      } else {
        // Copy the instruction, inlining any subroutine call recursively.
        instruction.accept(clazz, method, codeAttribute, offset, this);
      }

      offset += instructionLength;
    }

    // Copy the exceptions. Note that exceptions with empty try blocks
    // are automatically removed.
    codeAttribute.exceptionsAccept(clazz, method, subroutineExceptionInliner);

    if (DEBUG) {
      System.out.println("  Appending label after code at [" + offset + "]");
    }

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

    // End and update the code attribute.
    codeAttributeComposer.endCodeFragment();
    codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute);

    if (DEBUG) {
      method.accept(clazz, new ClassPrinter());
    }
  }
Beispiel #30
0
 /**
  * Generates an invoke method instruction.
  *
  * @param opcode the instruction's opcode.
  * @param type the class in which the method is defined.
  * @param method the method to be invoked.
  */
 private void invokeInsn(final int opcode, final Type type, final Method method) {
   String owner = type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName();
   mv.visitMethodInsn(opcode, owner, method.getName(), method.getDescriptor());
 }