aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/printing/RefinedPrinter.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-11-14 11:58:59 +0100
committerMartin Odersky <odersky@gmail.com>2016-11-16 14:25:40 +0100
commitfe20b9064fca765a38345a09aa484bfb537aa3c0 (patch)
tree99cce659b7c2fe7d79fd5c9c87ba51bcb96a7545 /src/dotty/tools/dotc/printing/RefinedPrinter.scala
parent97b6985c34915b58e0c81fbab464f4bd532c27d0 (diff)
downloaddotty-fe20b9064fca765a38345a09aa484bfb537aa3c0.tar.gz
dotty-fe20b9064fca765a38345a09aa484bfb537aa3c0.tar.bz2
dotty-fe20b9064fca765a38345a09aa484bfb537aa3c0.zip
Pickle and unpickle type trees
Lots of other changes to make positions work out everywhere. One important change is that now trees can be shared, just as types can. This change improves memory requirements (a bit) and also makes positions in shared trees more robust.
Diffstat (limited to 'src/dotty/tools/dotc/printing/RefinedPrinter.scala')
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala55
1 files changed, 45 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 39a21b17b..4818c6eee 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -21,6 +21,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
/** A stack of enclosing DefDef, TypeDef, or ClassDef, or ModuleDefs nodes */
private var enclosingDef: untpd.Tree = untpd.EmptyTree
private var myCtx: Context = _ctx
+ private var printPos = ctx.settings.Yprintpos.value
override protected[this] implicit def ctx: Context = myCtx
def withEnclosingDef(enclDef: Tree[_ >: Untyped])(op: => Text): Text = {
@@ -35,6 +36,18 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
}
+ def inPattern(op: => Text): Text = {
+ val savedCtx = myCtx
+ myCtx = ctx.addMode(Mode.Pattern)
+ try op finally myCtx = savedCtx
+ }
+
+ def withoutPos(op: => Text): Text = {
+ val savedPrintPos = printPos
+ printPos = false
+ try op finally printPos = savedPrintPos
+ }
+
private def enclDefIsClass = enclosingDef match {
case owner: TypeDef[_] => owner.isClassDef
case owner: untpd.ModuleDef => true
@@ -134,6 +147,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
return toTextParents(tp.parentsWithArgs) ~ "{...}"
case JavaArrayType(elemtp) =>
return toText(elemtp) ~ "[]"
+ case tp: AnnotatedType if homogenizedView =>
+ withoutPos(super.toText(tp))
case tp: SelectionProto =>
return "?{ " ~ toText(tp.name) ~ (" " provided !tp.name.decode.last.isLetterOrDigit) ~
": " ~ toText(tp.memberProto) ~ " }"
@@ -249,7 +264,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
def nameIdText(tree: untpd.NameTree): Text =
- toText(tree.name) ~ idText(tree)
+ if (tree.hasType && tree.symbol.exists) nameString(tree.symbol)
+ else toText(tree.name) ~ idText(tree)
def toTextTemplate(impl: Template, ofNew: Boolean = false): Text = {
val Template(constr @ DefDef(_, tparams, vparamss, _, _), parents, self, _) = impl
@@ -284,7 +300,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case tp: NamedType if name != nme.WILDCARD =>
val pre = if (tp.symbol is JavaStatic) tp.prefix.widen else tp.prefix
toTextPrefix(pre) ~ selectionString(tp)
- case _ => toText(name)
+ case _ =>
+ toText(name)
}
case tree @ Select(qual, name) =>
if (qual.isType) toTextLocal(qual) ~ "#" ~ toText(name)
@@ -337,7 +354,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
if (sel.isEmpty) blockText(cases)
else changePrec(GlobalPrec) { toText(sel) ~ " match " ~ blockText(cases) }
case CaseDef(pat, guard, body) =>
- "case " ~ toText(pat) ~ optText(guard)(" if " ~ _) ~ " => " ~ caseBlockText(body)
+ "case " ~ inPattern(toText(pat)) ~ optText(guard)(" if " ~ _) ~ " => " ~ caseBlockText(body)
case Return(expr, from) =>
changePrec(GlobalPrec) { "return" ~ optText(expr)(" " ~ _) }
case Try(expr, cases, finalizer) =>
@@ -519,22 +536,40 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case _ =>
tree.fallbackToText(this)
}
+
var txt = toTextCore(tree)
+
+ def suppressTypes =
+ tree.isType || tree.isDef || // don't print types of types or defs
+ homogenizedView && ctx.mode.is(Mode.Pattern)
+ // When comparing pickled info, disregard types of patterns.
+ // The reason is that GADT matching can rewrite types of pattern trees
+ // without changing the trees themselves. (see Typer.typedCase.indexPatterns.transform).
+ // But then pickling and unpickling the original trees will yield trees
+ // with the original types before they are rewritten, which causes a discrepancy.
+
+ def suppressPositions = tree match {
+ case _: WithoutTypeOrPos[_] | _: TypeTree => true // TypeTrees never have an interesting position
+ case _ => false
+ }
+
if (ctx.settings.printtypes.value && tree.hasType) {
- val tp = tree.typeOpt match {
+ // add type to term nodes; replace type nodes with their types unless -Yprintpos is also set.
+ def tp = tree.typeOpt match {
case tp: TermRef if tree.isInstanceOf[RefTree] && !tp.denot.isOverloaded => tp.underlying
case tp => tp
}
- if (tree.isType) txt = toText(tp)
- else if (!tree.isDef) txt = ("<" ~ txt ~ ":" ~ toText(tp) ~ ">").close
+ if (!suppressTypes)
+ txt = ("<" ~ txt ~ ":" ~ toText(tp) ~ ">").close
+ else if (tree.isType && !homogenizedView)
+ txt = toText(tp)
}
- else if (homogenizedView && tree.isType)
- txt = toText(tree.typeOpt)
- if (ctx.settings.Yprintpos.value && !tree.isInstanceOf[WithoutTypeOrPos[_]]) {
+ if (printPos && !suppressPositions) {
+ // add positions
val pos =
if (homogenizedView && !tree.isInstanceOf[MemberDef]) tree.pos.toSynthetic
else tree.pos
- val clsStr = "" // DEBUG: if (tree.isType) tree.getClass.toString else ""
+ val clsStr = ""//if (tree.isType) tree.getClass.toString else ""
txt = (txt ~ "@" ~ pos.toString ~ clsStr).close
}
tree match {