in scala/scala-impl/src/org/jetbrains/plugins/scala/lang/parameterInfo/ScalaFunctionParameterInfoHandler.scala [71:330]
override def updateUI(p: Any, context: ParameterInfoUIContext): Unit = {
if (context == null || context.getParameterOwner == null || !context.getParameterOwner.isValid) return
context.getParameterOwner match {
case args: PsiElement =>
implicit val tpc: TypePresentationContext = TypePresentationContext(args)
val color: Color = context.getDefaultParameterColor
val index = context.getCurrentParameterIndex
val buffer: StringBuilder = new StringBuilder("")
var isGrey = false
var isDeprecated = false
def paramText(param: ScParameter, subst: ScSubstitutor) = {
val typeRenderer: TypeRenderer = subst(_).presentableText
val renderer = new ParameterRenderer(
typeRenderer,
ModifiersRenderer.SimpleText(),
new TypeAnnotationRenderer(typeRenderer, ParameterTypeDecorator.DecorateAllMinimized),
withAnnotations = true
)
renderer.render(param)
}
def typeParamText(param: ScTypeParam, subst: ScSubstitutor) = {
new TypeParamsRenderer(subst(_).presentableText).render(param)
}
p match {
case x: String if x == "" =>
noParams(buffer)
case (a: AnnotationParameters, _: Int) =>
val seq = a.seq
if (seq.isEmpty) noParams(buffer)
else {
val paramsSeq: Seq[(Parameter, String)] = seq.zipWithIndex.map {
case ((name, tp, value), paramIndex) =>
val valueText = Option(value).map(_.getText)
.map(" = " + _)
.getOrElse("")
(new Parameter(name, None, tp, tp, value != null, false, false, paramIndex),
s"$name: ${tp.presentableText}$valueText")
}
isGrey = applyToParameters(paramsSeq, ScSubstitutor.empty, canBeNaming = true)(args, buffer, index)
}
case (sign: PhysicalMethodSignature, i: Int) => //i can be -1 (it's update method)
val subst = sign.substitutor
def processMethod(psiMethod: PsiMethod): Unit = {
def processApplyMethod(tpe: ScType): Unit = {
val maybeApplyMethod = tpe.extractClass.flatMap(_.getAllMethods.collectFirst {
case fn: ScFunction if fn.isApplyMethod =>
fn
case wrapper: ScFunctionWrapper if wrapper.delegate.isApplyMethod =>
wrapper.delegate
})
maybeApplyMethod.fold(noParams(buffer))(processMethod)
}
if (psiMethod != null)
isDeprecated = psiMethod.isDeprecated
psiMethod match {
case method: ScFunction =>
val isEffective = method.allClauses.length <= i
val clauses = if (isEffective) method.effectiveParameterClauses else method.allClauses
if (clauses.length <= i || (i == -1 && clauses.isEmpty)) {
if (clauses.isEmpty && i == 0) { // SCL-20512
method.returnType.fold(_ => noParams(buffer), processApplyMethod)
}
else noParams(buffer)
}
else {
val clause: ScParameterClause = if (i >= 0) clauses(i) else clauses.head
val length = clause.effectiveParameters.length
val precedingClauses = if (i == -1) Seq.empty else clauses.take(i)
val remainingClauses = if (i == -1) Seq.empty else clauses.drop(i + 1)
val typeParameters = method.typeParameters
val multipleLists = typeParameters.nonEmpty || precedingClauses.nonEmpty || remainingClauses.nonEmpty
def parametersOf(clause: ScParameterClause): Seq[(Parameter, String)] = {
val parameters0 = if (isEffective) clause.effectiveParameters else clause.parameters
val parameters: Seq[ScParameter] = if (i != -1) parameters0 else parameters0.take(length - 1)
parameters.map(param => (Parameter(param), paramText(param, subst)))
}
if (typeParameters.nonEmpty) {
buffer.append("[")
buffer.append(typeParameters.map(typeParamText(_, subst)).mkString(", "))
buffer.append("]")
}
precedingClauses.foreach { clause =>
buffer.append("(")
val parameters = parametersOf(clause)
if (parameters.nonEmpty) {
applyToParameters(parameters, subst, clause, canBeNaming = true)(args, buffer, -1)
}
buffer.append(")")
}
if (multipleLists) {
buffer.append("(")
}
isGrey = applyToParameters(parametersOf(clause), subst, clause, canBeNaming = true)(args, buffer, index)
if (multipleLists) {
buffer.append(")")
}
remainingClauses.foreach { clause =>
buffer.append("(")
val parameters = parametersOf(clause)
if (parameters.nonEmpty) {
applyToParameters(parameters, subst, clause, canBeNaming = true)(args, buffer, -1)
}
buffer.append(")")
}
}
case method: FakePsiMethod =>
val params = method.params
if (params.length == 0) processApplyMethod(method.retType)
else {
buffer.append(params.
map((param: Parameter) => {
val buffer: StringBuilder = new StringBuilder("")
val paramType = param.paramType
val name = param.name
if (name != "") {
buffer.append(name)
buffer.append(": ")
}
buffer.append(paramType.presentableText)
if (param.isRepeated) buffer.append("*")
if (param.isDefault) buffer.append(" = _")
val isBold = if (params.indexOf(param) == index || (param.isRepeated && params.indexOf(param) <= index)) true
else {
//todo: check type
false
}
val paramText = buffer.toString()
if (isBold) "<b>" + paramText + "</b>" else paramText
}).mkString(", "))
}
case method: PsiMethod =>
val p = method.getParameterList
if (p.getParameters.isEmpty) noParams(buffer)
else {
buffer.append(p.getParameters.
map((param: PsiParameter) => {
val buffer: StringBuilder = new StringBuilder("")
val list = param.getModifierList
if (list == null) return
val lastSize = buffer.length
for (a <- list.getAnnotations) {
if (lastSize != buffer.length) buffer.append(" ")
val element = a.getNameReferenceElement
if (element != null) buffer.append("@").append(element.getText)
}
if (lastSize != buffer.length) buffer.append(" ")
val name = param.name
if (name != null) {
buffer.append(name)
}
buffer.append(": ")
buffer.append(subst(param.paramType()).presentableText)
if (param.isVarArgs) buffer.append("*")
val isBold = if (p.getParameters.indexOf(param) == index || (param.isVarArgs && p.getParameters.indexOf(param) <= index)) true
else {
//todo: check type
false
}
val paramText = buffer.toString()
if (isBold) "<b>" + paramText + "</b>" else paramText
}).mkString(", "))
}
}
}
processMethod(sign.method)
case (constructor: ScPrimaryConstructor, subst: ScSubstitutor, i: Int) if constructor.isValid =>
isDeprecated = constructor.isDeprecated
val isEffective = constructor.allClauses.length <= i
val clauses = if (isEffective) constructor.effectiveParameterClauses else constructor.allClauses
if (clauses.length <= i) noParams(buffer)
else {
val clause: ScParameterClause = clauses(i)
val preceedingClauses = clauses.take(i)
val remainingClauses = clauses.drop(i + 1)
val typeParameters = constructor.getParent match {
case owner: ScTypeParametersOwner => owner.typeParameters
case _ => Seq.empty
}
val multipleLists = typeParameters.nonEmpty || preceedingClauses.nonEmpty || remainingClauses.nonEmpty
def parametersOf(clause: ScParameterClause) = {
val parameters = if (isEffective) clause.effectiveParameters else clause.parameters
parameters.map(param => (Parameter(param), paramText(param, subst)))
}
if (typeParameters.nonEmpty) {
buffer.append("[")
buffer.append(typeParameters.map(typeParamText(_, subst)).mkString(", "))
buffer.append("]")
}
preceedingClauses.foreach { clause =>
buffer.append("(")
val parameters = parametersOf(clause)
if (parameters.nonEmpty) {
applyToParameters(parameters, subst, clause, canBeNaming = true)(args, buffer, -1)
}
buffer.append(")")
}
if (multipleLists) {
buffer.append("(")
}
isGrey = applyToParameters(parametersOf(clause), subst, clause, canBeNaming = true)(args, buffer, index)
if (multipleLists) {
buffer.append(")")
}
remainingClauses.foreach { clause =>
buffer.append("(")
val parameters = parametersOf(clause)
if (parameters.nonEmpty) {
applyToParameters(parameters, subst, clause, canBeNaming = true)(args, buffer, -1)
}
buffer.append(")")
}
}
case _ =>
}
val startOffset = buffer.indexOf("<b>")
if (startOffset != -1) buffer.replace(startOffset, startOffset + 3, "")
val endOffset = buffer.indexOf("</b>")
if (endOffset != -1) buffer.replace(endOffset, endOffset + 4, "")
if (buffer.toString != "")
context.setupUIComponentPresentation(
buffer.toString(),
startOffset,
endOffset,
isGrey,
isDeprecated && !context.isSingleParameterInfo && !context.isSingleOverload,
false,
color
)
else
context.setUIComponentEnabled(false)
case _ =>
}
}