Esempio n. 1
0
  @NotNull
  protected ExpressionCodegen createOrGetClInitCodegen() {
    DeclarationDescriptor descriptor = context.getContextDescriptor();
    assert state.getClassBuilderMode() == ClassBuilderMode.FULL
        : "<clinit> should not be generated for light classes. Descriptor: " + descriptor;
    if (clInit == null) {
      MethodVisitor mv = v.newMethod(null, ACC_STATIC, "<clinit>", "()V", null, null);
      mv.visitCode();
      SimpleFunctionDescriptorImpl clInit =
          SimpleFunctionDescriptorImpl.create(
              descriptor, Annotations.EMPTY, Name.special("<clinit>"), SYNTHESIZED);
      clInit.initialize(
          null,
          null,
          Collections.<TypeParameterDescriptor>emptyList(),
          Collections.<ValueParameterDescriptor>emptyList(),
          null,
          null,
          Visibilities.PRIVATE);

      this.clInit =
          new ExpressionCodegen(
              mv, new FrameMap(), Type.VOID_TYPE, context.intoFunction(clInit), state, this);
    }
    return clInit;
  }
  @NotNull
  public static SimpleFunctionDescriptor createSamAdapterFunction(
      @NotNull SimpleFunctionDescriptor original) {
    SimpleFunctionDescriptorImpl result =
        new SimpleFunctionDescriptorImpl(
            original.getContainingDeclaration(),
            original.getAnnotations(),
            original.getName(),
            CallableMemberDescriptor.Kind.SYNTHESIZED);

    TypeParameters typeParameters =
        recreateAndInitializeTypeParameters(original.getTypeParameters(), result);

    JetType returnTypeUnsubstituted = original.getReturnType();
    assert returnTypeUnsubstituted != null : original;
    JetType returnType =
        typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE);
    assert returnType != null
        : "couldn't substitute type: "
            + returnType
            + ", substitutor = "
            + typeParameters.substitutor;

    List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
    for (ValueParameterDescriptor originalParam : original.getValueParameters()) {
      JetType originalType = originalParam.getType();
      JetType newTypeUnsubstituted =
          isSamType(originalType) ? getFunctionTypeForSamType(originalType) : originalType;
      JetType newType =
          typeParameters.substitutor.substitute(newTypeUnsubstituted, Variance.IN_VARIANCE);
      assert newType != null
          : "couldn't substitute type: "
              + newTypeUnsubstituted
              + ", substitutor = "
              + typeParameters.substitutor;

      ValueParameterDescriptor newParam =
          new ValueParameterDescriptorImpl(
              result,
              originalParam.getIndex(),
              originalParam.getAnnotations(),
              originalParam.getName(),
              newType,
              false,
              null);
      valueParameters.add(newParam);
    }

    result.initialize(
        null,
        original.getExpectedThisObject(),
        typeParameters.descriptors,
        valueParameters,
        returnType,
        original.getModality(),
        original.getVisibility(),
        false);

    return result;
  }
  @NotNull
  public static SimpleFunctionDescriptor createSamConstructorFunction(
      @NotNull ClassOrNamespaceDescriptor owner, @NotNull ClassDescriptor samInterface) {
    assert isSamInterface(samInterface) : samInterface;

    SimpleFunctionDescriptorImpl result =
        new SimpleFunctionDescriptorImpl(
            owner,
            samInterface.getAnnotations(),
            samInterface.getName(),
            CallableMemberDescriptor.Kind.SYNTHESIZED);

    TypeParameters typeParameters =
        recreateAndInitializeTypeParameters(
            samInterface.getTypeConstructor().getParameters(), result);

    JetType parameterTypeUnsubstituted = getFunctionTypeForSamType(samInterface.getDefaultType());
    JetType parameterType =
        typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE);
    assert parameterType != null
        : "couldn't substitute type: "
            + parameterType
            + ", substitutor = "
            + typeParameters.substitutor;
    ValueParameterDescriptor parameter =
        new ValueParameterDescriptorImpl(
            result,
            0,
            Collections.<AnnotationDescriptor>emptyList(),
            Name.identifier("function"),
            parameterType,
            false,
            null);

    JetType returnType =
        typeParameters.substitutor.substitute(samInterface.getDefaultType(), Variance.OUT_VARIANCE);
    assert returnType != null
        : "couldn't substitute type: "
            + returnType
            + ", substitutor = "
            + typeParameters.substitutor;

    result.initialize(
        null,
        null,
        typeParameters.descriptors,
        Arrays.asList(parameter),
        returnType,
        Modality.FINAL,
        samInterface.getVisibility(),
        false);

    return result;
  }
  @Nullable
  private static JetType computeUnsafeReturnType(
      @NotNull JetFunctionLiteralExpression expression,
      @NotNull ExpressionTypingContext context,
      @NotNull SimpleFunctionDescriptorImpl functionDescriptor,
      @Nullable JetType expectedReturnType) {
    JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
    JetBlockExpression bodyExpression = functionLiteral.getBodyExpression();
    assert bodyExpression != null;

    JetScope functionInnerScope =
        FunctionDescriptorUtil.getFunctionInnerScope(
            context.scope, functionDescriptor, context.trace);
    JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef();
    JetType declaredReturnType = null;
    if (returnTypeRef != null) {
      declaredReturnType =
          context
              .expressionTypingServices
              .getTypeResolver()
              .resolveType(context.scope, returnTypeRef, context.trace, true);
      // This is needed for ControlStructureTypingVisitor#visitReturnExpression() to properly
      // type-check returned expressions
      functionDescriptor.setReturnType(declaredReturnType);
      if (expectedReturnType != null) {
        if (!JetTypeChecker.INSTANCE.isSubtypeOf(declaredReturnType, expectedReturnType)) {
          context.trace.report(EXPECTED_RETURN_TYPE_MISMATCH.on(returnTypeRef, expectedReturnType));
        }
      }
    }

    // Type-check the body
    ExpressionTypingContext newContext =
        context
            .replaceScope(functionInnerScope)
            .replaceExpectedType(
                declaredReturnType != null
                    ? declaredReturnType
                    : (expectedReturnType != null ? expectedReturnType : NO_EXPECTED_TYPE));

    JetType typeOfBodyExpression =
        context
            .expressionTypingServices
            .getBlockReturnedType(bodyExpression, COERCION_TO_UNIT, newContext)
            .getType();

    List<JetType> returnedExpressionTypes =
        Lists.newArrayList(
            getTypesOfLocallyReturnedExpressions(
                functionLiteral, context.trace, collectReturns(bodyExpression)));
    ContainerUtil.addIfNotNull(returnedExpressionTypes, typeOfBodyExpression);

    if (declaredReturnType != null) return declaredReturnType;
    if (returnedExpressionTypes.isEmpty()) return null;
    return CommonSupertypes.commonSupertype(returnedExpressionTypes);
  }