Пример #1
0
  @Override
  public void genCallInner(
      @NotNull Callable callableMethod,
      @Nullable ResolvedCall<?> resolvedCall,
      boolean callDefault,
      @NotNull ExpressionCodegen codegen) {
    SMAPAndMethodNode nodeAndSmap = null;
    if (!state.getInlineCycleReporter().enterIntoInlining(resolvedCall)) {
      generateStub(resolvedCall, codegen);
      return;
    }

    try {
      nodeAndSmap = createMethodNode(callDefault);
      endCall(inlineCall(nodeAndSmap));
    } catch (CompilationException e) {
      throw e;
    } catch (Exception e) {
      boolean generateNodeText = !(e instanceof InlineException);
      PsiElement element =
          DescriptorToSourceUtils.descriptorToDeclaration(
              this.codegen.getContext().getContextDescriptor());
      throw new CompilationException(
          "Couldn't inline method call '"
              + functionDescriptor.getName()
              + "' into \n"
              + (element != null
                  ? element.getText()
                  : "null psi element " + this.codegen.getContext().getContextDescriptor())
              + (generateNodeText
                  ? ("\ncause: "
                      + InlineCodegenUtil.getNodeText(
                          nodeAndSmap != null ? nodeAndSmap.getNode() : null))
                  : ""),
          e,
          callElement);
    } finally {
      state.getInlineCycleReporter().exitFromInliningOf(resolvedCall);
    }
  }
Пример #2
0
 private SourceMapper createNestedSourceMapper(@NotNull SMAPAndMethodNode nodeAndSmap) {
   return new NestedSourceMapper(
       sourceMapper, nodeAndSmap.getRanges(), nodeAndSmap.getClassSMAP().getSourceInfo());
 }
Пример #3
0
  private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
    MethodNode node = nodeAndSmap.getNode();
    ReifiedTypeParametersUsages reificationResult =
        reifiedTypeInliner.reifyInstructions(node.instructions);
    generateClosuresBodies();

    // through generation captured parameters will be added to invocationParamBuilder
    putClosureParametersOnStack();

    addInlineMarker(codegen.v, true);

    Parameters parameters = invocationParamBuilder.buildParameters();

    InliningContext info =
        new RootInliningContext(
            expressionMap,
            state,
            codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
            codegen.getContext(),
            callElement,
            codegen.getParentCodegen().getClassName(),
            reifiedTypeInliner);

    MethodInliner inliner =
        new MethodInliner(
            node,
            parameters,
            info,
            new FieldRemapper(null, null, parameters),
            isSameModule,
            "Method inlining " + callElement.getText(),
            createNestedSourceMapper(nodeAndSmap)); // with captured

    LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);

    MethodNode adapter = InlineCodegenUtil.createEmptyMethodNode();
    // hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain
    adapter.visitInsn(Opcodes.NOP);

    InlineResult result = inliner.doInline(adapter, remapper, true, LabelOwner.SKIP_ALL);
    result.getReifiedTypeParametersUsages().mergeAll(reificationResult);

    CallableMemberDescriptor descriptor = codegen.getContext().getContextDescriptor();
    final Set<String> labels =
        getDeclarationLabels(
            DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor);
    LabelOwner labelOwner =
        new LabelOwner() {
          @Override
          public boolean isMyLabel(@NotNull String name) {
            return labels.contains(name);
          }
        };

    List<MethodInliner.PointForExternalFinallyBlocks> infos =
        MethodInliner.processReturns(adapter, labelOwner, true, null);
    generateAndInsertFinallyBlocks(
        adapter,
        infos,
        ((StackValue.Local) remapper.remap(parameters.totalSize() + 1).value).index);
    removeFinallyMarkers(adapter);

    adapter.accept(new InliningInstructionAdapter(codegen.v));

    addInlineMarker(codegen.v, false);

    return result;
  }