private def parametersIn()

in scala/tasty-reader/src/TreePrinter.scala [864:1079]


  private def parametersIn(sb: StringBuilder, node: Node, template: Option[Node] = None, definition: Option[Node] = None, target: Target = Target.Definition, modifiers: StringBuilder => Unit = _ => (), withSynthetic: Boolean = true, resultType: Option[String] = None): Unit = {
    val tps = target match {
      case Target.This => Seq.empty
      case Target.Definition => node.children
      case Target.Extension => node.children.takeWhile(!_.is(PARAM))
      case Target.ExtensionMethod => node.children.dropWhile(!_.is(PARAM))
    }

    val templateTypeParams = template.map(_.children.filter(_.is(TYPEPARAM)).iterator)

    val isPrivateConstructor = node.is(DEFDEF) && node.names == Seq("<init>") && node.contains(PRIVATE)

    lazy val contextBounds = if (!privateMembers && isPrivateConstructor) Seq.empty else node.children.collect {
      case param @ Node3(PARAM, Seq(name), Seq(tail, _*)) if (param.contains(IMPLICIT) || param.contains(GIVEN)) && hasSingleArgument(tail) && (name.startsWith("evidence$") || !name.contains("$") && param.position().zip(tail.firstChild.position()).exists(_ == _)) =>
        val Seq(designator, argument) = tail.children
        (simple(textOfType(argument)), simple(textOfType(designator)), if (name.startsWith("evidence$")) None else Some(name))
    }

    var open = false
    var next = false

    tps.foreach {
      case node @ Node2(TYPEPARAM, Seq(name)) if withSynthetic || !name.startsWith("_$") =>
        if (!open) {
          sb ++= "["
          open = true
          next = false
        }
        if (next) {
          sb ++= ", "
        }
        textOfAnnotationIn(sb, "", node, " ")
        if (template.isEmpty) { // Deduplicate?
          if (node.contains(COVARIANT)) {
            sb ++= "+"
          }
          if (node.contains(CONTRAVARIANT)) {
            sb ++= "-"
          }
        }
        templateTypeParams.map(_.next()).foreach { typeParam =>
          textOfAnnotationIn(sb, "", typeParam, " ")
          if (typeParam.contains(COVARIANT)) {
            sb ++= "+"
          }
          if (typeParam.contains(CONTRAVARIANT)) {
            sb ++= "-"
          }
        }
        val nameId = if (name.startsWith("_$")) "_" else id(name)
        sb ++= nameId // Detect Unique name?
        node.children match {
          case Seq(lambda @ Node1(LAMBDAtpt), _*) =>
            parametersIn(sb, lambda)
            lambda.children.lastOption match { // Deduplicate somehow?
              case Some(bounds @ Node1(TYPEBOUNDStpt)) =>
                boundsIn(sb, bounds)
              case _ =>
            }
          case Seq(bounds @ Node1(TYPEBOUNDStpt), _*) =>
            boundsIn(sb, bounds)
          case _ =>
        }
        contextBounds.foreach { case (id, tpe, symbol) =>
          if (id == name) {
            if (needsSpace(nameId)) {
              sb ++= " "
            }
            sb ++= ": "
            sb ++= tpe
            symbol.foreach { s =>
              sb ++= " as "
              sb ++= s
            }
          }
        }
        next = true
      case _ =>
    }
    if (open) {
      sb ++= "]"
    }

    val previousLength = sb.length
    modifiers(sb)
    val hasModifiers = sb.length > previousLength

    val ps = target match {
      case Target.This | Target.Definition => node.children
      case Target.Extension =>
        popExtensionParams(mutable.Stack[Node](node.children*))
      case Target.ExtensionMethod =>
        val stack = mutable.Stack[Node](node.children*)
        popExtensionParams(stack)
        stack.toSeq.dropWhile(_.is(SPLITCLAUSE))
    }

    val templateValueParams = template.map(_.children.filter(_.is(PARAM)).iterator)

    open = false
    next = false

    var isFirstClause = true
    var isImplicitClause = false
    var isGivenClause = false

    val valueParameterStart = sb.length
    var syntheticParameterNames = List.empty[(String, Int)]

    ps.foreach {
      case Node1(EMPTYCLAUSE) =>
        if (open) {
          sb ++= ")"
          open = false
          isFirstClause = false
        }
        sb ++= "()"
      case Node1(SPLITCLAUSE) =>
        sb ++= ")"
        open = false
        isFirstClause = false
      case node @ Node3(PARAM, Seq(name), Seq(tail, _*)) if !((node.contains(IMPLICIT) || node.contains(GIVEN)) && hasSingleArgument(tail) && (name.startsWith("evidence$") || !name.contains("$") && node.position().zip(tail.firstChild.position()).exists(_ == _))) =>
        if (!open) {
          sb ++= "("
          open = true
          next = false
          if (node.contains(GIVEN)) {
            sb ++= "using "
            isGivenClause = true
          } else {
            if (node.contains(IMPLICIT)) {
              sb ++= "implicit "
              isImplicitClause = true
            }
          }
        }
        val templateValueParam = templateValueParams.map(_.next())
        if (privateMembers || !isPrivateConstructor || templateValueParam.exists(!_.contains(PRIVATE))) { // private (), variables in { ... } ?
          if (next) {
            sb ++= ", "
          }
          textOfAnnotationIn(sb, "", node, " ")
          val tpe = textOfType(tail)
          if (node.contains(INLINE) || tpe.endsWith(" @_root_.scala.annotation.internal.InlineParam")) {
            sb ++= "inline "
          }
          if (!definition.exists(isGivenClass0)) {
            templateValueParam.foreach { valueParam =>
              if (!valueParam.contains(LOCAL) || valueParam.contains(PROTECTED)) {
                textOfAnnotationIn(sb, "", valueParam, " ")
                val sb1 = new StringBuilder() // Reuse?
                val isPrivate = valueParam.contains(PRIVATE)
                modifiersIn(sb1, valueParam, (if (isImplicitClause) Set(IMPLICIT) else if (isGivenClause) Set(GIVEN) else Set.empty) ++ (if (privateMembers || !isPrivate) Set.empty else Set(ABSTRACT, OVERRIDE, PRIVATE, IMPLICIT, FINAL)))
                sb ++= sb1
                if (privateMembers || !isPrivate) {
                  if (valueParam.contains(MUTABLE)) {
                    sb ++= "var "
                  } else {
                    if (!(isFirstClause && definition.exists(_.contains(CASE)) && valueParam.modifierTags.forall(it => it == CASEaccessor || it == HASDEFAULT))) {
                      sb ++= "val "
                    }
                  }
                }
              }
            }
          }
          val isSyntheticParam = node.contains(SYNTHETIC) || templateValueParam.exists(_.contains(SYNTHETIC))
          if (!isSyntheticParam) {
            val nameId = id(name, parameter = true)
            sb ++= nameId
            if (needsSpace(nameId)) {
              sb ++= " "
            }
            sb ++= ": "
          } else {
            syntheticParameterNames ::= (name, sb.length)
          }
          sb ++= simple(tpe).stripSuffix(" @_root_.scala.annotation.internal.InlineParam")
          if (node.contains(HASDEFAULT)) {
            sb ++= " = "
            sb ++= CompiledCode
          }
          next = true
        }
      case _ =>
    }
    if (open) {
      if (!next) {
        if (isImplicitClause) {
          sb.setLength(sb.length - 9)
        } else if (isGivenClause) {
          sb.setLength(sb.length - 6)
        }
      }
      sb ++= ")"
    }
    val valueParameterText = sb.substring(valueParameterStart) // Check nodes rather than text?
    syntheticParameterNames.foreach { (name, index) =>
      //example from `scala.annotation.MacroAnnotation#transform`
      //original code : def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition]
      //printed code  : def transform(using _root_.scala.quoted.Quotes)(tree: x$1.reflect.Definition): List[x$1.reflect.Definition]
      val syntheticParameterIsLikelyUsedInSignature =
        valueParameterText.contains(name) || resultType.exists(_.contains(name))
      val insertSyntheticParameterName = syntheticParameterIsLikelyUsedInSignature
      if (insertSyntheticParameterName) {
        val nameId = id(name)
        val paramNamePrefix = name + (if (needsSpace(nameId)) " " else "") + ": "
        sb.insert(index, paramNamePrefix)
      }
    }
    if (template.isEmpty || hasModifiers || definition.exists(it => it.contains(CASE) && !it.contains(OBJECT))) {} else {
      if (sb.length >= 2 && sb.substring(sb.length - 2, sb.length()) == "()" && !(sb.length > 2 && sb.charAt(sb.length - 3) == ')')) {
        sb.delete(sb.length - 2, sb.length())
      }
    }
  }