in rsc/src/main/scala/rsc/pretty/TreeStr.scala [90:770]
private def impl(x: Tree): Unit = {
x match {
case AmbigSelect(qual, id) =>
apply(qual)
p.str(".")
apply(id)
case Case(pat, cond, stats) =>
p.str("case ")
apply(pat, Pat)
cond foreach { term =>
p.str(" if ")
apply(term, PostfixExpr)
}
p.str(" => ")
p.Indent(printStats(stats))
case DefnConstant(mods, id) =>
apply(mods)
apply(id)
case DefnCtor(mods, id, paramss, rhs) =>
l match {
case ScalaLanguage =>
apply(mods)
p.str("def ")
apply(id)
apply(paramss)
p.Prefix(" = ")(apply(rhs, Expr))
case JavaLanguage =>
printJavaMods(mods) {
val _ :: (defnClass: DefnClass) :: _ = stack
p.str(defnClass.id)
apply(paramss)
}
rhs match {
case TermStub() => p.str(" { ??? }")
case rhs => apply(rhs, Expr)
}
}
case DefnField(mods, id, tpt, rhs) =>
l match {
case ScalaLanguage =>
apply(mods)
apply(id)
if (id.isSymbolic) p.str(" ")
p.Prefix(": ")(tpt)(apply(_, "", Typ))
p.Prefix(" = ")(rhs)(apply(_, "", Expr))
case JavaLanguage =>
printJavaMods(mods) {
p.Suffix(" ")(tpt)(apply(_, "", Typ))
apply(id)
}
p.Prefix(" = ")(rhs)(apply(_, "", Expr))
p.str(";")
}
case DefnMacro(mods, id, tparams, paramss, ret, rhs) =>
apply(mods)
p.str("def ")
apply(id)
p.Brackets(tparams)(apply(_, ", "))
apply(paramss)
if (tparams.isEmpty && paramss.isEmpty && id.isSymbolic) p.str(" ")
p.Prefix(": ")(ret)(apply(_, "", Typ))
p.str(" = macro ")
apply(rhs)
case DefnMethod(mods, id, tparams, paramss, ret, rhs) =>
l match {
case ScalaLanguage =>
apply(mods)
p.str("def ")
apply(id)
p.Brackets(tparams)(apply(_, ", "))
apply(paramss)
if (tparams.isEmpty && paramss.isEmpty && id.isSymbolic) p.str(" ")
p.Prefix(": ")(ret)(apply(_, "", Typ))
p.Prefix(" = ")(rhs)(apply(_, "", Expr))
case JavaLanguage =>
printJavaMods(mods) {
p.Suffix(" ")(tparams)(p.Angles(_)(apply(_, ", ")))
p.Suffix(" ")(ret)(apply(_, "", Typ))
apply(id)
apply(paramss)
}
rhs match {
case Some(TermStub()) => p.str(" { ??? }")
case Some(rhs) => apply(rhs, Expr)
case None => p.str(";")
}
}
case DefnPackage(mods, pid, stats) =>
l match {
case ScalaLanguage =>
apply(mods)
p.str("package ")
p.str(pid)
p.Nest.when(stats.nonEmpty)(printStats(stats))
case JavaLanguage =>
printJavaMods(mods) {
p.str("package ")
p.str(pid)
p.str(";")
p.str(EOL)
printStats(stats)
}
}
case DefnPat(mods, pats, tpt, rhs) =>
apply(mods)
apply(pats, ", ")
p.Prefix(": ")(tpt)(apply(_, "", Typ))
p.Prefix(" = ")(rhs)(apply(_, "", Expr))
case DefnProcedure(mods, id, tparams, paramss, rhs) =>
apply(mods)
p.str("def ")
apply(id)
p.Brackets(tparams)(apply(_, ", "))
apply(paramss)
p.Prefix(" ")(rhs)(apply(_, "", Expr))
case x: DefnTemplate =>
l match {
case ScalaLanguage =>
apply(x.mods)
x match {
case _: DefnClass => p.str("")
case _: DefnObject => p.str("object ")
case _: DefnPackageObject => p.str("package object ")
}
apply(x.id)
p.Brackets(x.tparams)(apply(_, ", "))
x match {
case DefnClass(_, _, _, Some(primaryCtor), _, _, _, _) => apply(primaryCtor)
case other => ()
}
if (x.earlies.isEmpty) {
p.Prefix(" extends ")(x.parents)(apply(_, " with "))
} else {
p.str(" extends")
p.Nest(apply(x.earlies, EOL))
p.Prefix(" with ")(x.parents)(apply(_, " with "))
}
p.Nest.when(x.self.nonEmpty || x.stats.nonEmpty) {
p.Suffix(EOL)(x.self)(apply(_, ""))
printStats(x.stats)
}
case JavaLanguage =>
printJavaMods(x.mods) {
apply(x.id)
p.Angles(x.tparams)(apply(_, ", "))
val extendsTpts = x.parents.collect { case ParentExtends(tpt) => tpt }.headOption
p.Prefix(" extends ")(extendsTpts)(apply(_, "", Typ))
val implementsTpts = x.parents.collect { case ParentImplements(tpt) => tpt }
p.Prefix(" implements ").when(implementsTpts.nonEmpty)(apply(implementsTpts, "", Typ))
p.Nest(printStats(x.stats))
}
}
case DefnType(mods, id, tparams, lo, hi, rhs) =>
apply(mods)
p.str("type ")
apply(id)
p.Brackets(tparams)(apply(_, ", "))
p.Prefix(" >: ")(lo)(apply(_, "", Typ))
p.Prefix(" <: ")(hi)(apply(_, "", Typ))
p.Prefix(" = ")(rhs)(apply(_, "", Typ))
case EnumeratorGenerator(pat, rhs) =>
apply(pat, AnyPat3)
p.str(" <- ")
rhs match {
case _: TermApplyPostfix => p.Parens(apply(rhs, Expr))
case _ => apply(rhs, Expr)
}
case EnumeratorGuard(cond) =>
p.str("if ")
apply(cond, PostfixExpr)
case EnumeratorVal(pat, rhs) =>
apply(pat, AnyPat3)
p.str(" = ")
rhs match {
case _: TermApplyPostfix => p.Parens(apply(rhs, Expr))
case _ => apply(rhs, Expr)
}
case x: Id =>
if (x.sym != NoSymbol) p.str("<" + x.sym + ">")
else {
def printValue(value: String): Unit = {
l match {
case ScalaLanguage =>
import rsc.lexis.scala._
x match {
case PatId(value) if value.isPatVar =>
p.str("`" + value + "`")
case _ =>
def hasBackquotes = x.pos.string.startsWith("`")
def guessBackquotes = keywords.containsKey(value) || value == "then"
if (hasBackquotes || guessBackquotes) p.str("`" + value + "`")
else p.str(value)
}
case JavaLanguage =>
p.str(value)
}
}
x match {
case AmbigId(value) => printValue(value)
case AnonId() => p.str("_")
case CtorId() => p.str("this")
case NamedId(value) => printValue(value)
}
}
case Import(importers) =>
l match {
case ScalaLanguage =>
p.str("import ")
apply(importers, ", ")
case JavaLanguage =>
p.str("import ")
apply(importers, ", ")
p.str(";")
}
case ImporteeName(id) =>
apply(id)
case ImporteeRename(from, to) =>
apply(from)
p.str(" => ")
apply(to)
case ImporteeUnimport(id) =>
apply(id)
p.str(" => _")
case ImporteeWildcard() =>
l match {
case ScalaLanguage => p.str("_")
case JavaLanguage => p.str("*")
}
case Importer(mods, qual, importees) =>
printJavaMods(mods) {
apply(qual, SimpleExpr1)
p.str(".")
val needsBraces = importees match {
case List(_: ImporteeRename) => true
case List(_: ImporteeUnimport) => true
case List(_) => false
case _ => true
}
p.Braces.when(needsBraces)(apply(importees, ", "))
}
case Init(tpt, argss) =>
apply(tpt, AnnotTyp)
apply(argss, Expr)
case Mods(trees) =>
p.Suffix(" ")(trees)(apply(_, " "))
case ModAbstract() =>
p.str("abstract")
case ModAnnotation(Init(tpt, argss)) =>
p.str("@")
apply(tpt, SimpleTyp)
apply(argss, Expr)
case ModAnnotationInterface() =>
p.str("@interface")
case ModCase() =>
p.str("case")
case ModClass() =>
p.str("class")
case ModContravariant() =>
p.str("-")
case ModCovariant() =>
p.str("+")
case ModDefault() =>
p.str("default")
case ModDims() =>
p.str("[]")
case ModEnum() =>
p.str("enum")
case ModFinal() =>
p.str("final")
case ModImplicit() =>
p.str("implicit")
case ModInterface() =>
p.str("interface")
case ModLazy() =>
p.str("lazy")
case ModNative() =>
p.str("native")
case ModOverride() =>
p.str("override")
case ModPrivate() =>
p.str("private")
case ModPrivateThis() =>
p.str("private[this]")
case ModPrivateWithin(within) =>
p.str("private")
p.Brackets(apply(within, SimpleExpr1))
case ModProtected() =>
p.str("protected")
case ModProtectedThis() =>
p.str("protected[this]")
case ModProtectedWithin(within) =>
p.str("protected")
p.Brackets(apply(within, SimpleExpr1))
case ModPublic() =>
p.str("public")
case ModSealed() =>
p.str("sealed")
case ModStatic() =>
p.str("static")
case ModStrictfp() =>
p.str("strictfp")
case ModSynchronized() =>
p.str("synchronized")
case ModThrows(tpts) =>
p.str("throws ")
apply(tpts, ", ", Typ)
case ModTrait() =>
p.str("trait")
case ModTransient() =>
p.str("transient")
case ModVal() =>
p.str("val")
case ModVar() =>
p.str("var")
case ModVolatile() =>
p.str("volatile")
case Param(mods, id, tpt, rhs) =>
l match {
case ScalaLanguage =>
apply(mods)
apply(id)
if (id.isSymbolic) p.str(" ")
p.Prefix(": ")(tpt)(apply(_, "", ParamTyp))
p.Prefix(" = ")(rhs)(apply(_, "", Expr))
case JavaLanguage =>
printJavaMods(mods) {
p.Suffix(" ")(tpt)(apply(_, "", ParamTyp))
apply(id)
}
}
case ParentExtends(tpt) =>
apply(tpt, Typ)
case ParentImplements(tpt) =>
apply(tpt, Typ)
case PatAlternative(pats) =>
apply(pats, " | ", Pat)
case PatBind(pats) =>
apply(pats, " @ ", Pat2)
case PatExtract(fun, targs, args) =>
apply(fun, Expr)
p.Brackets(targs)(apply(_, ", "))
p.Parens(apply(args, ", ", Pat))
case PatExtractInfix(lhs, op, rhs) =>
apply(lhs, InfixPat(op))
p.str(" ")
apply(op, SimpleExpr1)
p.str(" ")
apply(rhs, RhsInfixPat(op))
case PatInterpolate(id, unescapedParts, args) =>
val sparts = unescapedParts.map {
case PatLit(value: String) => value
case other => crash(other.repl)
}
printInterpolation(id, sparts, args)
case PatLit(value) =>
printLit(value)
case PatRepeat(pat) =>
apply(pat, Pat2)
p.str("*")
case PatSelect(qual, id) =>
apply(qual, SimpleExpr1)
p.str(".")
apply(id, SimpleExpr1)
case PatTuple(args) =>
p.Parens(apply(args, ", ", Pat))
case PatVar(mods, id, tpt) =>
apply(mods)
id match {
case AnonId() => p.str("_")
case _ => apply(id)
}
p.Prefix(": ")(tpt)(apply(_, "", RefineTyp))
case PatXml(raw) =>
// FIXME: https://github.com/twitter/rsc/issues/81
p.str(raw)
case tree @ PrimaryCtor(mods, paramss) =>
if (mods.trees.nonEmpty) p.str(" ")
apply(mods)
if (tree.id.sym != NoSymbol) p.str("<" + tree.id.sym + ">")
else ()
apply(paramss)
case Self(id, tpt) =>
apply(id)
p.Prefix(": ")(tpt)(apply(_, " ", Typ))
p.str(" => ")
case Source(stats) =>
printStats(stats)
case TermAnnotate(term, mods) =>
apply(term, PostfixExpr)
p.str(": ")
apply(mods)
case TermApply(fun, args) =>
apply(fun, SimpleExpr1)
p.Parens(apply(args, ", ", Expr))
case TermApplyInfix(lhs, op, targs, args) =>
apply(lhs, InfixExpr(op))
p.str(" ")
apply(op, SimpleExpr1)
p.Brackets(targs)(apply(_, ", ", Typ))
p.str(" ")
args match {
case List(arg: TermTuple) => p.Parens(apply(arg, Expr))
case List(arg) => apply(arg, RhsInfixExpr(op))
case args => p.Parens(apply(args, ", ", Expr))
}
case TermApplyPostfix(arg, op) =>
apply(arg, InfixExpr(op))
p.str(" ")
apply(op, SimpleExpr1)
case TermApplyPrefix(op, arg) =>
apply(op, SimpleExpr1)
def needsParens(term: Term): Boolean = term match {
case TermApply(fn, _) => needsParens(fn)
case _: TermApplyPrefix => true
case TermApplyType(fn, _) => needsParens(fn)
case _: TermLit => true
case TermSelect(qual, _) => needsParens(qual)
case _ => false
}
p.Parens.when(needsParens(arg))(apply(arg, PrefixExpr))
case TermApplyType(fun, targs) =>
apply(fun, SimpleExpr)
p.Brackets(apply(targs, ", ", Typ))
case TermAscribe(term, tpt) =>
apply(term, PostfixExpr)
p.str(": ")
apply(tpt, Typ)
case TermAssign(lhs, rhs) =>
apply(lhs, SimpleExpr1)
p.str(" = ")
apply(rhs, Expr)
case TermBlock(stats) =>
stats match {
case List(fn @ TermFunction(List(param), _)) if param.hasImplicit =>
apply(fn)
case _ =>
p.Nest(printStats(stats))
}
case TermDo(body, cond) =>
p.str("do ")
apply(body, Expr)
p.str(" while ")
p.Parens(apply(cond, Expr))
case TermEta(term) =>
apply(term, SimpleExpr1)
p.str(" _")
case TermFor(enums, body) =>
p.str("for ")
p.Nest(apply(enums, EOL))
apply(body, Expr)
case TermForYield(enums, body) =>
p.str("for ")
p.Nest(apply(enums, EOL))
p.str(" yield ")
apply(body, Expr)
case TermFunction(params, body) =>
params match {
case List(param) if param.hasImplicit =>
p.str("{ ")
apply(param)
p.str(" => ")
apply(body)
p.str(" }")
case _ =>
p.Parens(apply(params, ", "))
p.str(" =>")
p.Indent(apply(body, Expr))
}
case TermIf(cond, thenp, elsep) =>
p.str("if ")
p.Parens(apply(cond, Expr))
p.str(" ")
apply(thenp, Expr)
p.Prefix(" else ")(elsep)(apply(_, "", Expr))
case TermInterpolate(id, unescapedParts, args) =>
val sparts = unescapedParts.map {
case TermLit(value: String) => value
case other => crash(other.repl)
}
printInterpolation(id, sparts, args)
case TermLit(value) =>
printLit(value)
case TermMatch(term, cases) =>
apply(term, PostfixExpr)
p.str(" match ")
p.Nest(apply(cases, EOL))
case TermNew(init) =>
p.str("new ")
apply(init)
if (init.argss.isEmpty) p.str("()")
case TermNewAnonymous(earlies, inits, self, stats) =>
p.str("new ")
if (earlies.isEmpty) {
apply(inits, " with ")
} else {
p.Nest(apply(earlies, EOL))
p.Prefix(" with ")(inits)(apply(_, " with "))
}
p.Nest.when(self.nonEmpty || stats.nonEmpty) {
p.Suffix(EOL)(self)(apply(_, ""))
printStats(stats.getOrElse(List()))
}
case TermPartialFunction(cases) =>
p.Nest(apply(cases, EOL))
case TermRepeat(term) =>
apply(term, PostfixExpr)
p.str(": _*")
case TermReturn(term) =>
p.str("return")
p.Prefix(" ")(term)(apply(_, "", Expr))
case TermSelect(qual, id) =>
apply(qual, SimpleExpr)
p.str(".")
apply(id, SimpleExpr1)
case TermStub() =>
p.str("???")
case TermSuper(qual, mix) =>
p.Suffix(".")(qual.opt)(apply(_, "", SimpleExpr1))
p.str("super")
p.Brackets(mix.opt)(apply(_, "", SimpleExpr1))
case TermThis(qual) =>
p.Suffix(".")(qual.opt)(apply(_, "", SimpleExpr1))
p.str("this")
case TermThrow(term) =>
p.str("throw ")
apply(term, Expr)
case TermTry(expr, catchp, finallyp) =>
p.str("try ")
apply(expr, Expr)
if (catchp.nonEmpty) {
p.str(" catch ")
p.Nest(apply(catchp, EOL, Expr))
}
p.Prefix(" finally ")(finallyp)(apply(_, "", Expr))
case TermTryWithHandler(expr, catchp, finallyp) =>
p.str("try ")
apply(expr, Expr)
p.str(" catch ")
apply(catchp, Expr)
p.Prefix(" finally ")(finallyp)(apply(_, "", Expr))
case TermTuple(args) =>
p.Parens(apply(args, ", ", Expr))
case TermWhile(cond, body) =>
p.str(" ")
p.str("while ")
p.Parens(apply(cond, Expr))
apply(body, Expr)
case TermWildcard() =>
p.str("_")
case TermWildcardFunction(_, term) =>
apply(term, Expr)
case TermXml(raw) =>
// FIXME: https://github.com/twitter/rsc/issues/81
p.str(raw)
case TptArray(tpt) =>
apply(tpt, Typ)
p.str("[]")
case TptAnnotate(tpt, mods) =>
apply(tpt, SimpleTyp)
p.str(" ")
apply(mods)
case TptBoolean() =>
p.str("boolean")
case TptByName(tpt) =>
p.str("=>")
apply(tpt, Typ)
case TptByte() =>
p.str("byte")
case TptChar() =>
p.str("char")
case TptDouble() =>
p.str("double")
case TptExistential(tpt, stats) =>
apply(tpt, AnyInfixTyp)
p.str(" forSome ")
p.Braces(apply(stats, "; "))
case TptFloat() =>
p.str("float")
case TptFunction(targs) =>
val params :+ ret = targs
val needsParens = params match {
case List(_: TptTuple | _: TptFunction) => true
case List(_: TptByName | _: TptRepeat) => true
case List(_) => false
case _ => true
}
p.Parens.when(needsParens)(apply(params, ", ", ParamTyp))
p.str(" => ")
apply(ret, Typ)
case TptInt() =>
p.str("int")
case TptIntersect(tpts) =>
apply(tpts, " & ", InfixTyp(TptId("&")))
case TptLit(value) =>
printLit(value)
case TptLong() =>
p.str("long")
case TptParameterize(fun, targs) =>
l match {
case ScalaLanguage =>
apply(fun, SimpleTyp)
p.Brackets(apply(targs, ", ", Typ))
case JavaLanguage =>
apply(fun, SimpleTyp)
p.Angles(apply(targs, ", ", Typ))
}
case TptParameterizeInfix(lhs, op, rhs) =>
apply(lhs, InfixTyp(op))
p.str(" ")
apply(op)
p.str(" ")
apply(rhs, RhsInfixTyp(op))
case TptProject(qual, id) =>
l match {
case ScalaLanguage =>
apply(qual, SimpleTyp)
p.str("#")
apply(id, SimpleTyp)
case JavaLanguage =>
apply(qual, SimpleTyp)
p.str(".")
apply(id, SimpleTyp)
}
case TptRefine(tpt, stats) =>
apply(tpt, " ", WithTyp)
p.Braces(apply(stats, "; "))
case TptRepeat(tpt) =>
l match {
case ScalaLanguage =>
apply(tpt, Typ)
p.str("*")
case JavaLanguage =>
apply(tpt, Typ)
p.str("...")
}
case TptSelect(qual, id) =>
apply(qual, SimpleExpr)
p.str(".")
apply(id, SimpleTyp)
case TptShort() =>
p.str("short")
case TptSingleton(path) =>
apply(path, SimpleExpr)
p.str(".type")
case TptTuple(targs) =>
p.Parens(apply(targs, ", ", Typ))
case TptVoid() =>
p.str("void")
case TptWildcard(lbound, ubound) =>
l match {
case ScalaLanguage =>
p.str("_")
p.Prefix(" >: ")(lbound)(apply(_, ""))
p.Prefix(" <: ")(ubound)(apply(_, ""))
case JavaLanguage =>
p.str("?")
p.Prefix(" extends ")(lbound)(apply(_, ""))
p.Prefix(" supet ")(ubound)(apply(_, ""))
}
case TptWildcardExistential(_, tpt) =>
apply(tpt, Typ)
case TptWith(tpts) =>
apply(tpts, " with ", WithTyp)
case TypeParam(mods, id, tparams, lbound, ubound, vbounds, cbounds) =>
l match {
case ScalaLanguage =>
apply(mods)
apply(id)
p.Brackets(tparams)(apply(_, ", "))
p.Prefix(" >: ")(lbound)(apply(_, ""))
p.Prefix(" <: ")(ubound)(apply(_, ""))
p.Prefix(" <% ")(vbounds)(apply(_, " <% "))
p.Prefix(" : ")(cbounds)(apply(_, " : "))
case JavaLanguage =>
printJavaMods(mods) {
apply(id)
p.Prefix(" extends ")(ubound)(apply(_, ""))
}
}
}
}