@NotNull
  private ClassBuilder createClassBuilder() {
    ClassBuilder classBuilder =
        state
            .getFactory()
            .newVisitor(
                NO_ORIGIN,
                newLambdaType,
                inliningContext.getRoot().callElement.getContainingFile());

    return new RemappingClassBuilder(
        classBuilder,
        new AsmTypeRemapper(
            inliningContext.typeRemapper,
            inliningContext.getRoot().typeParameterMappings == null,
            transformationResult));
  }
  @NotNull
  private InlineResult inlineMethod(
      @NotNull AnonymousObjectGeneration anonymousObjectGen,
      @NotNull FieldRemapper parentRemapper,
      @NotNull MethodVisitor deferringVisitor,
      @NotNull MethodNode sourceNode,
      @NotNull ParametersBuilder capturedBuilder,
      boolean isConstructor) {
    ReifiedTypeParametersUsages typeParametersToReify =
        inliningContext.reifedTypeInliner.reifyInstructions(sourceNode);
    Parameters parameters =
        isConstructor
            ? capturedBuilder.buildParameters()
            : getMethodParametersWithCaptured(capturedBuilder, sourceNode);

    RegeneratedLambdaFieldRemapper remapper =
        new RegeneratedLambdaFieldRemapper(
            oldObjectType.getInternalName(),
            newLambdaType.getInternalName(),
            parameters,
            anonymousObjectGen.getCapturedLambdasToInline(),
            parentRemapper,
            isConstructor);

    MethodInliner inliner =
        new MethodInliner(
            sourceNode,
            parameters,
            inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
            remapper,
            isSameModule,
            "Transformer for " + anonymousObjectGen.getOwnerInternalName(),
            sourceMapper,
            new InlineCallSiteInfo(
                anonymousObjectGen.getOwnerInternalName(),
                sourceNode.name,
                isConstructor
                    ? anonymousObjectGen.getNewConstructorDescriptor()
                    : sourceNode.desc));

    InlineResult result =
        inliner.doInline(
            deferringVisitor,
            new LocalVarRemapper(parameters, 0),
            false,
            LabelOwner.NOT_APPLICABLE);
    result.getReifiedTypeParametersUsages().mergeAll(typeParametersToReify);
    deferringVisitor.visitMaxs(-1, -1);
    return result;
  }
Пример #3
0
  public InlineResult doInline(
      @NotNull MethodVisitor adapter,
      @NotNull LocalVarRemapper remapper,
      boolean remapReturn,
      @NotNull LabelOwner labelOwner) {
    // analyze body
    MethodNode transformedNode = markPlacesForInlineAndRemoveInlinable(node);

    // substitute returns with "goto end" instruction to keep non local returns in lambdas
    Label end = new Label();
    transformedNode = doInline(transformedNode);
    removeClosureAssertions(transformedNode);
    InsnList instructions = transformedNode.instructions;
    instructions.resetLabels();

    MethodNode resultNode =
        new MethodNode(
            InlineCodegenUtil.API,
            transformedNode.access,
            transformedNode.name,
            transformedNode.desc,
            transformedNode.signature,
            ArrayUtil.toStringArray(transformedNode.exceptions));
    RemapVisitor visitor = new RemapVisitor(resultNode, remapper, nodeRemapper);
    try {
      transformedNode.accept(visitor);
    } catch (Exception e) {
      throw wrapException(e, transformedNode, "couldn't inline method call");
    }

    resultNode.visitLabel(end);

    if (inliningContext.isRoot()) {
      InternalFinallyBlockInliner.processInlineFunFinallyBlocks(resultNode, lambdasFinallyBlocks);
    }

    processReturns(resultNode, labelOwner, remapReturn, end);
    // flush transformed node to output
    resultNode.accept(new InliningInstructionAdapter(adapter));

    return result;
  }
 private void writeOuterInfo(@NotNull ClassVisitor visitor) {
   InlineCallSiteInfo info = inliningContext.getCallSiteInfo();
   visitor.visitOuterClass(
       info.getOwnerClassName(), info.getFunctionName(), info.getFunctionDesc());
 }