@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;
 }
 private static String renderParameter(
     ValueParameterDescriptor descriptor, boolean named, BindingContext bindingContext) {
   StringBuilder builder = new StringBuilder();
   if (named) builder.append("[");
   if (descriptor.getVarargElementType() != null) {
     builder.append("vararg ");
   }
   builder
       .append(descriptor.getName())
       .append(": ")
       .append(DescriptorRenderer.TEXT.renderType(getActualParameterType(descriptor)));
   if (descriptor.hasDefaultValue()) {
     PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
     String defaultExpression = "?";
     if (element instanceof JetParameter) {
       JetParameter parameter = (JetParameter) element;
       JetExpression defaultValue = parameter.getDefaultValue();
       if (defaultValue != null) {
         if (defaultValue instanceof JetConstantExpression) {
           JetConstantExpression constantExpression = (JetConstantExpression) defaultValue;
           defaultExpression = constantExpression.getText();
           if (defaultExpression.length() > 10) {
             if (defaultExpression.startsWith("\"")) defaultExpression = "\"...\"";
             else if (defaultExpression.startsWith("\'")) defaultExpression = "\'...\'";
             else defaultExpression = defaultExpression.substring(0, 7) + "...";
           }
         }
       }
     }
     builder.append(" = ").append(defaultExpression);
   }
   if (named) builder.append("]");
   return builder.toString();
 }
 public void serialize(ValueParameterDescriptor valueParameter) {
   sb.append("/*");
   sb.append(valueParameter.getIndex());
   sb.append("*/ ");
   if (valueParameter.getVarargElementType() != null) {
     sb.append("vararg ");
   }
   sb.append(valueParameter.getName());
   sb.append(": ");
   if (valueParameter.getVarargElementType() != null) {
     new TypeSerializer(sb).serialize(valueParameter.getVarargElementType());
   } else {
     new TypeSerializer(sb).serialize(valueParameter.getType());
   }
   if (valueParameter.hasDefaultValue()) {
     sb.append(" = ?");
   }
 }
  @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;
  }
 private static String renderParameter(
     ValueParameterDescriptor parameter, boolean named, BindingContext bindingContext) {
   StringBuilder builder = new StringBuilder();
   if (named) builder.append("[");
   if (parameter.getVarargElementType() != null) {
     builder.append("vararg ");
   }
   builder
       .append(parameter.getName())
       .append(": ")
       .append(
           DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(getActualParameterType(parameter)));
   if (parameter.hasDefaultValue()) {
     PsiElement parameterDeclaration =
         BindingContextUtils.descriptorToDeclaration(bindingContext, parameter);
     builder.append(" = ").append(getDefaultExpressionString(parameterDeclaration));
   }
   if (named) builder.append("]");
   return builder.toString();
 }
  @Nullable
  public static JetChangeSignatureDialog createDialog(
      @NotNull PsiElement element, PsiElement context, Project project, Editor editor) {
    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null;
    BindingContext bindingContext =
        AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile())
            .getBindingContext();
    DeclarationDescriptor descriptor =
        bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);

    if (descriptor instanceof ClassDescriptor) {
      descriptor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor();
    }
    if (descriptor instanceof FunctionDescriptorImpl) {
      for (ValueParameterDescriptor parameter :
          ((FunctionDescriptor) descriptor).getValueParameters()) {
        if (parameter.getVarargElementType() != null) {
          String message = JetRefactoringBundle.message("error.cant.refactor.vararg.functions");
          CommonRefactoringUtil.showErrorHint(
              project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE);
          return null;
        }
      }

      return new JetChangeSignatureDialog(
          project,
          new JetFunctionPlatformDescriptorImpl((FunctionDescriptor) descriptor, element),
          context);
    } else {
      String message =
          RefactoringBundle.getCannotRefactorMessage(
              JetRefactoringBundle.message(
                  "error.wrong.caret.position.function.or.constructor.name"));
      CommonRefactoringUtil.showErrorHint(
          project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE);
      return null;
    }
  }
 private static JetType getActualParameterType(ValueParameterDescriptor descriptor) {
   JetType paramType = descriptor.getType();
   if (descriptor.getVarargElementType() != null) paramType = descriptor.getVarargElementType();
   return paramType;
 }
  private void computeValueParameters(
      @NotNull List<ValueParameterDescriptor> parameterDescriptors) {
    if (parameterDescriptors.size() != altFunDeclaration.getValueParameters().size()) {
      throw new AlternativeSignatureMismatchException(
          "Method signature has %d value parameters, but alternative signature has %d",
          parameterDescriptors.size(), altFunDeclaration.getValueParameters().size());
    }

    List<ValueParameterDescriptor> altParamDescriptors = new ArrayList<ValueParameterDescriptor>();
    for (int i = 0, size = parameterDescriptors.size(); i < size; i++) {
      ValueParameterDescriptor originalParameterDescriptor = parameterDescriptors.get(i);
      JetParameter annotationValueParameter = altFunDeclaration.getValueParameters().get(i);

      //noinspection ConstantConditions
      JetTypeElement alternativeTypeElement =
          annotationValueParameter.getTypeReference().getTypeElement();
      assert alternativeTypeElement != null;

      JetType alternativeType;
      JetType alternativeVarargElementType;

      JetType originalParamVarargElementType = originalParameterDescriptor.getVarargElementType();
      if (originalParamVarargElementType == null) {
        if (annotationValueParameter.isVarArg()) {
          throw new AlternativeSignatureMismatchException(
              "Parameter in method signature is not vararg, but in alternative signature it is vararg");
        }

        alternativeType =
            TypeTransformingVisitor.computeType(
                alternativeTypeElement,
                originalParameterDescriptor.getType(),
                originalToAltTypeParameters,
                MEMBER_SIGNATURE_CONTRAVARIANT);
        alternativeVarargElementType = null;
      } else {
        if (!annotationValueParameter.isVarArg()) {
          throw new AlternativeSignatureMismatchException(
              "Parameter in method signature is vararg, but in alternative signature it is not");
        }

        alternativeVarargElementType =
            TypeTransformingVisitor.computeType(
                alternativeTypeElement, originalParamVarargElementType,
                originalToAltTypeParameters, MEMBER_SIGNATURE_CONTRAVARIANT);
        alternativeType = KotlinBuiltIns.getInstance().getArrayType(alternativeVarargElementType);
      }

      Name altName = annotationValueParameter.getNameAsName();

      altParamDescriptors.add(
          new ValueParameterDescriptorImpl(
              originalParameterDescriptor.getContainingDeclaration(),
              null,
              originalParameterDescriptor.getIndex(),
              originalParameterDescriptor.getAnnotations(),
              altName != null ? altName : originalParameterDescriptor.getName(),
              alternativeType,
              originalParameterDescriptor.declaresDefaultValue(),
              alternativeVarargElementType));
    }

    altValueParameters = altParamDescriptors;
  }