@Nullable
 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
     FunctionDescriptor substitutedDescriptor,
     @NotNull FunctionDescriptor functionDescriptor,
     @NotNull TypeSubstitutor substitutor) {
   List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
   List<ValueParameterDescriptor> unsubstitutedValueParameters =
       functionDescriptor.getValueParameters();
   for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size();
       i < unsubstitutedValueParametersSize;
       i++) {
     ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i);
     // TODO : Lazy?
     JetType substitutedType =
         substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
     JetType varargElementType = unsubstitutedValueParameter.getVarargElementType();
     JetType substituteVarargElementType =
         varargElementType == null
             ? null
             : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
     if (substitutedType == null) return null;
     result.add(
         new ValueParameterDescriptorImpl(
             substitutedDescriptor,
             unsubstitutedValueParameter,
             unsubstitutedValueParameter.getAnnotations(),
             unsubstitutedValueParameter.isVar(),
             substitutedType,
             substituteVarargElementType));
   }
   return result;
 }
Exemplo n.º 2
0
  @NotNull
  private VarargCheckResult checkVarargInSuperFunctions(
      @NotNull ValueParameterDescriptor originalParam) {
    boolean someSupersVararg = false;
    boolean someSupersNotVararg = false;
    for (FunctionDescriptor superFunction : superFunctions) {
      if (superFunction.getValueParameters().get(originalParam.getIndex()).getVarargElementType()
          != null) {
        someSupersVararg = true;
      } else {
        someSupersNotVararg = true;
      }
    }

    JetType originalVarargElementType = originalParam.getVarargElementType();
    JetType originalType = originalParam.getType();

    if (someSupersVararg && someSupersNotVararg) {
      reportError("Incompatible super methods: some have vararg parameter, some have not");
      return new VarargCheckResult(originalType, originalVarargElementType != null);
    }

    KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
    if (someSupersVararg && originalVarargElementType == null) {
      // convert to vararg

      assert isArrayType(originalType);

      if (builtIns.isPrimitiveArray(originalType)) {
        // replace IntArray? with IntArray
        return new VarargCheckResult(TypeUtils.makeNotNullable(originalType), true);
      }

      // replace Array<out Foo>? with Array<Foo>
      JetType varargElementType = builtIns.getArrayElementType(originalType);
      return new VarargCheckResult(builtIns.getArrayType(INVARIANT, varargElementType), true);
    } else if (someSupersNotVararg && originalVarargElementType != null) {
      // convert to non-vararg

      assert isArrayType(originalType);

      if (builtIns.isPrimitiveArray(originalType)) {
        // replace IntArray with IntArray?
        return new VarargCheckResult(TypeUtils.makeNullable(originalType), false);
      }

      // replace Array<Foo> with Array<out Foo>?
      return new VarargCheckResult(
          TypeUtils.makeNullable(
              builtIns.getArrayType(Variance.OUT_VARIANCE, originalVarargElementType)),
          false);
    }

    return new VarargCheckResult(originalType, originalVarargElementType != null);
  }
  private List<ValueParameterDescriptor> createValueParameterDescriptors(
      ExpressionTypingContext context,
      JetFunctionLiteral functionLiteral,
      FunctionDescriptorImpl functionDescriptor,
      boolean functionTypeExpected) {
    List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList();
    List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters();

    List<ValueParameterDescriptor> expectedValueParameters =
        (functionTypeExpected)
            ? JetStandardClasses.getValueParameters(functionDescriptor, context.expectedType)
            : null;

    boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null;
    if (functionTypeExpected
        && !hasDeclaredValueParameters
        && expectedValueParameters.size() == 1) {
      ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0);
      ValueParameterDescriptor it =
          new ValueParameterDescriptorImpl(
              functionDescriptor,
              0,
              Collections.<AnnotationDescriptor>emptyList(),
              "it",
              false,
              valueParameterDescriptor.getOutType(),
              valueParameterDescriptor.hasDefaultValue(),
              valueParameterDescriptor.getVarargElementType());
      valueParameterDescriptors.add(it);
      context.trace.record(AUTO_CREATED_IT, it);
    } else {
      for (int i = 0; i < declaredValueParameters.size(); i++) {
        JetParameter declaredParameter = declaredValueParameters.get(i);
        JetTypeReference typeReference = declaredParameter.getTypeReference();

        JetType type;
        if (typeReference != null) {
          type = context.getTypeResolver().resolveType(context.scope, typeReference);
        } else {
          if (expectedValueParameters != null && i < expectedValueParameters.size()) {
            type = expectedValueParameters.get(i).getOutType();
          } else {
            context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter));
            type = ErrorUtils.createErrorType("Cannot be inferred");
          }
        }
        ValueParameterDescriptor valueParameterDescriptor =
            context
                .getDescriptorResolver()
                .resolveValueParameterDescriptor(functionDescriptor, declaredParameter, i, type);
        valueParameterDescriptors.add(valueParameterDescriptor);
      }
    }
    return valueParameterDescriptors;
  }
  @NotNull
  private static List<ValueParameterDescriptor> createValueParameterDescriptors(
      @NotNull ExpressionTypingContext context,
      @NotNull JetFunctionLiteral functionLiteral,
      @NotNull FunctionDescriptorImpl functionDescriptor,
      boolean functionTypeExpected) {
    List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList();
    List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters();

    List<ValueParameterDescriptor> expectedValueParameters =
        (functionTypeExpected)
            ? KotlinBuiltIns.getInstance()
                .getValueParameters(functionDescriptor, context.expectedType)
            : null;

    JetParameterList valueParameterList = functionLiteral.getValueParameterList();
    boolean hasDeclaredValueParameters = valueParameterList != null;
    if (functionTypeExpected
        && !hasDeclaredValueParameters
        && expectedValueParameters.size() == 1) {
      ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0);
      ValueParameterDescriptor it =
          new ValueParameterDescriptorImpl(
              functionDescriptor,
              0,
              Collections.<AnnotationDescriptor>emptyList(),
              Name.identifier("it"),
              valueParameterDescriptor.getType(),
              valueParameterDescriptor.hasDefaultValue(),
              valueParameterDescriptor.getVarargElementType());
      valueParameterDescriptors.add(it);
      context.trace.record(AUTO_CREATED_IT, it);
    } else {
      if (expectedValueParameters != null
          && declaredValueParameters.size() != expectedValueParameters.size()) {
        List<JetType> expectedParameterTypes =
            DescriptorUtils.getValueParametersTypes(expectedValueParameters);
        context.trace.report(
            EXPECTED_PARAMETERS_NUMBER_MISMATCH.on(
                functionLiteral, expectedParameterTypes.size(), expectedParameterTypes));
      }
      for (int i = 0; i < declaredValueParameters.size(); i++) {
        ValueParameterDescriptor valueParameterDescriptor =
            createValueParameterDescriptor(
                context, functionDescriptor, declaredValueParameters, expectedValueParameters, i);
        valueParameterDescriptors.add(valueParameterDescriptor);
      }
    }
    return valueParameterDescriptors;
  }
Exemplo n.º 5
0
 private void checkDefaultParameterValues(
     List<JetParameter> valueParameters,
     List<ValueParameterDescriptor> valueParameterDescriptors,
     JetScope declaringScope) {
   for (int i = 0; i < valueParameters.size(); i++) {
     ValueParameterDescriptor valueParameterDescriptor = valueParameterDescriptors.get(i);
     if (valueParameterDescriptor.hasDefaultValue()) {
       JetParameter jetParameter = valueParameters.get(i);
       JetExpression defaultValue = jetParameter.getDefaultValue();
       if (defaultValue != null) {
         expressionTypingServices.getType(
             declaringScope, defaultValue, valueParameterDescriptor.getType(), trace);
       }
     }
   }
 }
Exemplo n.º 6
0
  /* VARIABLES */
  private void renderValueParameter(
      @NotNull ValueParameterDescriptor valueParameter,
      @NotNull StringBuilder builder,
      boolean topLevel) {
    if (topLevel) {
      builder.append(renderKeyword("value-parameter")).append(" ");
    }

    if (verbose) {
      builder.append("/*").append(valueParameter.getIndex()).append("*/ ");
    }

    renderAnnotations(valueParameter, builder);
    renderVariable(valueParameter, builder, topLevel);
    boolean withDefaultValue =
        debugMode ? valueParameter.declaresDefaultValue() : valueParameter.hasDefaultValue();
    if (withDefaultValue) {
      builder.append(" = ...");
    }
  }
Exemplo n.º 7
0
  private JavaDescriptorResolver.ValueParameterDescriptors
      modifyValueParametersAccordingToSuperMethods(
          @NotNull
              JavaDescriptorResolver.ValueParameterDescriptors
                  parameters // descriptors built by parameters resolver
          ) {
    // we are not processing receiver type specifically:
    // if this function comes from Kotlin, then we don't need to do it, if it doesn't, then it can't
    // have receiver

    List<ValueParameterDescriptor> resultParameters = Lists.newArrayList();

    for (ValueParameterDescriptor originalParam : parameters.getDescriptors()) {
      final int index = originalParam.getIndex();
      List<TypeAndVariance> typesFromSuperMethods =
          ContainerUtil.map(
              superFunctions,
              new Function<FunctionDescriptor, TypeAndVariance>() {
                @Override
                public TypeAndVariance fun(FunctionDescriptor superFunction) {
                  return new TypeAndVariance(
                      superFunction.getValueParameters().get(index).getType(), INVARIANT);
                }
              });

      VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam);

      JetType altType =
          modifyTypeAccordingToSuperMethods(
              varargCheckResult.parameterType,
              typesFromSuperMethods,
              MEMBER_SIGNATURE_CONTRAVARIANT);

      resultParameters.add(
          new ValueParameterDescriptorImpl(
              originalParam.getContainingDeclaration(),
              index,
              originalParam.getAnnotations(),
              originalParam.getName(),
              altType,
              originalParam.declaresDefaultValue(),
              varargCheckResult.isVararg
                  ? KotlinBuiltIns.getInstance().getArrayElementType(altType)
                  : null));
    }

    JetType originalReceiverType = parameters.getReceiverType();
    if (originalReceiverType != null) {
      JetType substituted =
          SignaturesUtil.createSubstitutorForFunctionTypeParameters(autoTypeParameterToModified)
              .substitute(originalReceiverType, INVARIANT);
      assert substituted != null;
      return new JavaDescriptorResolver.ValueParameterDescriptors(substituted, resultParameters);
    } else {
      return new JavaDescriptorResolver.ValueParameterDescriptors(null, resultParameters);
    }
  }
  @Override
  public JetType visitFunctionLiteralExpression(
      JetFunctionLiteralExpression expression, ExpressionTypingContext context) {
    JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
    JetBlockExpression bodyExpression = functionLiteral.getBodyExpression();
    if (bodyExpression == null) return null;

    JetType expectedType = context.expectedType;
    boolean functionTypeExpected =
        expectedType != TypeUtils.NO_EXPECTED_TYPE
            && JetStandardClasses.isFunctionType(expectedType);

    NamedFunctionDescriptorImpl functionDescriptor =
        createFunctionDescriptor(expression, context, functionTypeExpected);

    List<JetType> parameterTypes = Lists.newArrayList();
    List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
    for (ValueParameterDescriptor valueParameter : valueParameters) {
      parameterTypes.add(valueParameter.getOutType());
    }
    ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
    JetType receiver = receiverParameter != NO_RECEIVER ? receiverParameter.getType() : null;

    JetType returnType = TypeUtils.NO_EXPECTED_TYPE;
    JetScope functionInnerScope =
        FunctionDescriptorUtil.getFunctionInnerScope(
            context.scope, functionDescriptor, context.trace);
    JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef();
    if (returnTypeRef != null) {
      returnType = context.getTypeResolver().resolveType(context.scope, returnTypeRef);
      context
          .getServices()
          .checkFunctionReturnType(
              expression,
              context
                  .replaceScope(functionInnerScope)
                  .replaceExpectedType(returnType)
                  .replaceExpectedReturnType(returnType)
                  .replaceDataFlowInfo(context.dataFlowInfo));
    } else {
      if (functionTypeExpected) {
        returnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType);
      }
      returnType =
          context
              .getServices()
              .getBlockReturnedType(
                  functionInnerScope,
                  bodyExpression,
                  CoercionStrategy.COERCION_TO_UNIT,
                  context.replaceExpectedType(returnType).replaceExpectedReturnType(returnType));
    }
    JetType safeReturnType =
        returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType;
    functionDescriptor.setReturnType(safeReturnType);

    boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null;
    if (!hasDeclaredValueParameters && functionTypeExpected) {
      JetType expectedReturnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType);
      if (JetStandardClasses.isUnit(expectedReturnType)) {
        functionDescriptor.setReturnType(JetStandardClasses.getUnitType());
        return DataFlowUtils.checkType(
            JetStandardClasses.getFunctionType(
                Collections.<AnnotationDescriptor>emptyList(),
                receiver,
                parameterTypes,
                JetStandardClasses.getUnitType()),
            expression,
            context);
      }
    }
    return DataFlowUtils.checkType(
        JetStandardClasses.getFunctionType(
            Collections.<AnnotationDescriptor>emptyList(),
            receiver,
            parameterTypes,
            safeReturnType),
        expression,
        context);
  }