Пример #1
0
  @NotNull
  public MethodNode prepareNode(@NotNull MethodNode node) {
    final int capturedParamsSize = parameters.getCaptured().size();
    final int realParametersSize = parameters.getReal().size();
    Type[] types = Type.getArgumentTypes(node.desc);
    Type returnType = Type.getReturnType(node.desc);

    ArrayList<Type> capturedTypes = parameters.getCapturedTypes();
    Type[] allTypes =
        ArrayUtil.mergeArrays(types, capturedTypes.toArray(new Type[capturedTypes.size()]));

    node.instructions.resetLabels();
    MethodNode transformedNode =
        new MethodNode(
            InlineCodegenUtil.API,
            node.access,
            node.name,
            Type.getMethodDescriptor(returnType, allTypes),
            node.signature,
            null) {

          private final boolean isInliningLambda = nodeRemapper.isInsideInliningLambda();

          private int getNewIndex(int var) {
            return var + (var < realParametersSize ? 0 : capturedParamsSize);
          }

          @Override
          public void visitVarInsn(int opcode, int var) {
            super.visitVarInsn(opcode, getNewIndex(var));
          }

          @Override
          public void visitIincInsn(int var, int increment) {
            super.visitIincInsn(getNewIndex(var), increment);
          }

          @Override
          public void visitMaxs(int maxStack, int maxLocals) {
            super.visitMaxs(maxStack, maxLocals + capturedParamsSize);
          }

          @Override
          public void visitLineNumber(int line, @NotNull Label start) {
            if (isInliningLambda) {
              super.visitLineNumber(line, start);
            }
          }

          @Override
          public void visitLocalVariable(
              @NotNull String name,
              @NotNull String desc,
              String signature,
              @NotNull Label start,
              @NotNull Label end,
              int index) {
            if (isInliningLambda) {
              super.visitLocalVariable(name, desc, signature, start, end, getNewIndex(index));
            }
          }
        };

    node.accept(transformedNode);

    transformCaptured(transformedNode);

    return transformedNode;
  }