Пример #1
0
  private SMAP generateMethodBody(
      @NotNull MethodVisitor adapter,
      @NotNull FunctionDescriptor descriptor,
      @NotNull MethodContext context,
      @NotNull JetExpression expression,
      @NotNull JvmMethodSignature jvmMethodSignature,
      boolean isLambda) {
    FakeMemberCodegen parentCodegen =
        new FakeMemberCodegen(
            codegen.getParentCodegen(),
            expression,
            (FieldOwnerContext) context.getParentContext(),
            isLambda
                ? codegen.getParentCodegen().getClassName()
                : typeMapper.mapOwner(descriptor).getInternalName());

    FunctionGenerationStrategy strategy =
        expression instanceof JetCallableReferenceExpression
            ? new FunctionReferenceGenerationStrategy(
                state,
                descriptor,
                CallUtilKt.getResolvedCallWithAssert(
                    ((JetCallableReferenceExpression) expression).getCallableReference(),
                    codegen.getBindingContext()))
            : new FunctionGenerationStrategy.FunctionDefault(
                state, descriptor, (JetDeclarationWithBody) expression);

    FunctionCodegen.generateMethodBody(
        adapter,
        descriptor,
        context,
        jvmMethodSignature,
        strategy,
        // Wrapping for preventing marking actual parent codegen as containing reifier markers
        parentCodegen);

    return createSMAPWithDefaultMapping(
        expression, parentCodegen.getOrCreateSourceMapper().getResultMappings());
  }
Пример #2
0
  @NotNull
  private SMAPAndMethodNode createMethodNode(boolean callDefault)
      throws ClassNotFoundException, IOException {
    JvmMethodSignature jvmSignature =
        typeMapper.mapSignature(functionDescriptor, context.getContextKind());

    Method asmMethod;
    if (callDefault) {
      asmMethod = typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind());
    } else {
      asmMethod = jvmSignature.getAsmMethod();
    }

    SMAPAndMethodNode nodeAndSMAP;
    if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
      JetTypeMapper.ContainingClassesInfo containingClasses =
          typeMapper.getContainingClassesForDeserializedCallable(
              (DeserializedSimpleFunctionDescriptor) functionDescriptor);

      VirtualFile file =
          InlineCodegenUtil.getVirtualFileForCallable(containingClasses.getImplClassId(), state);
      nodeAndSMAP =
          InlineCodegenUtil.getMethodNode(
              file.contentsToByteArray(),
              asmMethod.getName(),
              asmMethod.getDescriptor(),
              containingClasses.getFacadeClassId());

      if (nodeAndSMAP == null) {
        throw new RuntimeException(
            "Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
      }
    } else {
      PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);

      if (element == null || !(element instanceof JetNamedFunction)) {
        throw new RuntimeException(
            "Couldn't find declaration for function " + descriptorName(functionDescriptor));
      }
      JetNamedFunction inliningFunction = (JetNamedFunction) element;

      MethodNode node =
          new MethodNode(
              InlineCodegenUtil.API,
              getMethodAsmFlags(functionDescriptor, context.getContextKind())
                  | (callDefault ? Opcodes.ACC_STATIC : 0),
              asmMethod.getName(),
              asmMethod.getDescriptor(),
              jvmSignature.getGenericsSignature(),
              null);

      // for maxLocals calculation
      MethodVisitor maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node);
      MethodContext methodContext = context.getParentContext().intoFunction(functionDescriptor);

      SMAP smap;
      if (callDefault) {
        Type implementationOwner = typeMapper.mapOwner(functionDescriptor);
        FakeMemberCodegen parentCodegen =
            new FakeMemberCodegen(
                codegen.getParentCodegen(),
                inliningFunction,
                (FieldOwnerContext) methodContext.getParentContext(),
                implementationOwner.getInternalName());
        FunctionCodegen.generateDefaultImplBody(
            methodContext,
            functionDescriptor,
            maxCalcAdapter,
            DefaultParameterValueLoader.DEFAULT,
            inliningFunction,
            parentCodegen);
        smap =
            createSMAPWithDefaultMapping(
                inliningFunction, parentCodegen.getOrCreateSourceMapper().getResultMappings());
      } else {
        smap =
            generateMethodBody(
                maxCalcAdapter,
                functionDescriptor,
                methodContext,
                inliningFunction,
                jvmSignature,
                false);
      }

      nodeAndSMAP = new SMAPAndMethodNode(node, smap);
      maxCalcAdapter.visitMaxs(-1, -1);
      maxCalcAdapter.visitEnd();
    }
    return nodeAndSMAP;
  }