def pprint()

in scalafix/rules/src/main/scala/rsc/rules/pretty/SemanticdbPrinter.scala [24:188]


  def pprint(tpe: s.Type): Unit = {
    def prefix(tpe: s.Type): Unit = {
      tpe match {
        case s.TypeRef(pre, sym, args) =>
          if (sym.startsWith("scala/Tuple")) {
            str("(")
            rep(args, ", ")(normal)
            str(")")
          } else if (sym.startsWith("scala/Function")) {
            val params :+ ret = args
            val hasByNameArg = params.exists(_.isInstanceOf[s.ByNameType])
            val hasFunctionArg = params.exists {
              case s.TypeRef(pre, sym, args) if sym.startsWith("scala/Function") => true
              case _ => false
            }
            val singleTupleArg = params.length == 1 && (params.head match {
              case s.TypeRef(_, argSym, _) => argSym.startsWith("scala/Tuple")
              case _ => false
            })

            val needsExtraParens = hasFunctionArg ||
              hasByNameArg ||
              singleTupleArg ||
              (params.length != 1)

            if (needsExtraParens) str("(")
            rep(params, ", ") { normal }
            if (needsExtraParens) str(")")
            str(" => ")
            normal(ret)
          } else {
            // TODO: At the moment, we return None for local symbols, since they don't have a desc.
            // The logic to improve on this is left for future work.
            val name = sym.desc match {
              case d.Term(value) => Some(n.TermName(value))
              case d.Type(value) => Some(n.TypeName(value))
              case d.Package(value) => Some(n.TermName(value))
              case d.Parameter(value) => Some(n.TermName(value))
              case d.TypeParameter(value) => Some(n.TypeName(value))
              case other => None
            }
            def printPrettyPrefix: Unit = {
              val prettyPre = if (pre == s.NoType) sym.trivialPrefix(env) else pre
              prettyPre match {
                case _: s.SingleType | _: s.ThisType | _: s.SuperType =>
                  prefix(prettyPre)
                  str(".")
                case s.NoType =>
                  ()
                case _ =>
                  prefix(prettyPre)
                  str("#")
              }
            }
            if (config.better) {
              name.map(fullEnv.lookup) match {
                case Some(x) if !symbols.sameOrTypeAlias(x, sym) =>
                  if (config.autoimport && x.isEmpty && pre == s.NoType) {
                    addedImportsScope.addImport(sym)
                  } else {
                    printPrettyPrefix
                  }
                case _ =>
                  ()
              }
            } else {
              printPrettyPrefix
            }
            pprint(sym)
            rep("[", args, ", ", "]")(normal)
          }
        case s.SingleType(pre, sym) =>
          lazy val fromEnv = fullEnv.lookup(sym.desc.name)
          lazy val renamed = fullEnv.getRename(sym.desc.name)
          lazy val isRenamedSymbol = renamed.nonEmpty && renamed != sym.desc.value
          if (config.better && symbols.sameOrTypeAlias(fromEnv, sym)) {
            str(sym.desc.value)
          } else if (config.better && isRenamedSymbol) {
            str(fullEnv.getRename(sym.desc.name))
          } else if (config.better && config.autoimport && fromEnv.isEmpty) {
            addedImportsScope.addImport(sym)
            str(sym.desc.value)
          } else {
            val prettyPre = if (pre == s.NoType) sym.trivialPrefix(env) else pre
            opt(prettyPre, ".")(prefix)
            pprint(sym)
          }
        case s.ThisType(sym) =>
          opt(sym, ".")(pprint)
          str("this")
        case s.WithType(types) =>
          val filteredTypes = if (config.better) {
            types.filter {
              case s.TypeRef(_, "scala/AnyRef#", _) | s.TypeRef(_, "java/lang/Object#", _) => false
              case _ => true
            } match {
              case Nil => types
              case ts => ts
            }
          } else {
            types
          }

          rep(filteredTypes, " with ") { tpe =>
            // FIXME: https://github.com/twitter/rsc/issues/142
            val needsParens = tpe.isInstanceOf[s.ExistentialType]
            if (needsParens) str("(")
            normal(tpe)
            if (needsParens) str(")")
          }
        case s.StructuralType(utpe, decls) =>
          decls.infos.foreach(symbols.append)
          opt(utpe)(normal)
          if (!config.better) {
            if (decls.infos.nonEmpty) {
              rep(" { ", decls.infos, "; ", " }")(pprint)
            } else {
              utpe match {
                case s.WithType(tpes) if tpes.length > 1 => ()
                case _ => str(" {}")
              }
            }
          }
        case s.AnnotatedType(anns, utpe) =>
          opt(utpe)(normal)
          anns.toList match {
            case s.Annotation(s.NoType) :: Nil =>
              ()
            case _ =>
              rep(" ", anns, " ", "")(pprint)
          }
        case s.ExistentialType(utpe, decls) =>
          decls.infos.foreach(symbols.append)
          opt(utpe)(normal)
          rep(" forSome { ", decls.infos, "; ", " }")(pprint)
        case s.UniversalType(tparams, utpe) =>
          // FIXME: https://github.com/twitter/rsc/issues/150
          str("({ type λ")
          tparams.infos.foreach(symbols.append)
          rep("[", tparams.infos, ", ", "] = ")(pprint)
          opt(utpe)(normal)
          str(" })#λ")
        case s.ByNameType(utpe) =>
          str("=> ")
          opt(utpe)(normal)
        case s.RepeatedType(utpe) =>
          opt(utpe)(normal)
          str("*")
        case _: s.SuperType | _: s.ConstantType | _: s.IntersectionType | _: s.UnionType |
            s.NoType =>
          val details = tpe.asMessage.toProtoString
          sys.error(s"unsupported type: $details")
      }
    }
    def normal(tpe: s.Type): Unit = {
      tpe match {
        case _: s.SingleType | _: s.ThisType | _: s.SuperType =>
          prefix(tpe)
          str(".type")
        case _ =>
          prefix(tpe)
      }
    }
    normal(tpe)
  }