diff options
Diffstat (limited to 'src/dotty/tools/dotc/printing/RefinedPrinter.scala')
-rw-r--r-- | src/dotty/tools/dotc/printing/RefinedPrinter.scala | 652 |
1 files changed, 0 insertions, 652 deletions
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala deleted file mode 100644 index 29e1d4869..000000000 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ /dev/null @@ -1,652 +0,0 @@ -package dotty.tools.dotc -package printing - -import core._ -import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._ -import TypeErasure.ErasedValueType -import Contexts.Context, Scopes.Scope, Denotations._, SymDenotations._, Annotations.Annotation -import StdNames.{nme, tpnme} -import ast.{Trees, untpd, tpd} -import typer.{Namer, Inliner} -import typer.ProtoTypes.{SelectionProto, ViewProto, FunProto, IgnoredProto, dummyTreeOfType} -import Trees._ -import TypeApplications._ -import Decorators._ -import config.Config -import scala.annotation.switch -import language.implicitConversions - -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 = { - val savedCtx = myCtx - if (enclDef.hasType && enclDef.symbol.exists) - myCtx = ctx.withOwner(enclDef.symbol) - val savedDef = enclosingDef - enclosingDef = enclDef - try op finally { - myCtx = savedCtx - enclosingDef = savedDef - } - } - - 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 - case _ => false - } - - override protected def recursionLimitExceeded() = {} - - protected val PrintableFlags = (SourceModifierFlags | Label | Module | Local).toCommonFlags - - override def nameString(name: Name): String = name.decode.toString - - override protected def simpleNameString(sym: Symbol): String = { - val name = sym.originalName - nameString(if (sym is ExpandedTypeParam) name.asTypeName.unexpandedName else name) - } - - override def fullNameString(sym: Symbol): String = - if (isEmptyPrefix(sym.maybeOwner)) nameString(sym) - else super.fullNameString(sym) - - override protected def fullNameOwner(sym: Symbol) = { - val owner = super.fullNameOwner(sym) - if (owner is ModuleClass) owner.sourceModule else owner - } - - override def toTextRef(tp: SingletonType): Text = controlled { - tp match { - case tp: ThisType => - if (tp.cls.isAnonymousClass) return "this" - if (tp.cls is ModuleClass) return fullNameString(tp.cls.sourceModule) - case _ => - } - super.toTextRef(tp) - } - - override def toTextPrefix(tp: Type): Text = controlled { - def isOmittable(sym: Symbol) = - if (ctx.settings.verbose.value) false - else if (homogenizedView) isEmptyPrefix(sym) // drop <root> and anonymous classes, but not scala, Predef. - else isOmittablePrefix(sym) - tp match { - case tp: ThisType => - if (isOmittable(tp.cls)) return "" - case tp @ TermRef(pre, _) => - val sym = tp.symbol - if (sym.isPackageObject) return toTextPrefix(pre) - if (isOmittable(sym)) return "" - case _ => - } - super.toTextPrefix(tp) - } - - override protected def refinementNameString(tp: RefinedType): String = - if (tp.parent.isInstanceOf[WildcardType] || tp.refinedName == nme.WILDCARD) - super.refinementNameString(tp) - else { - val tsym = tp.parent.member(tp.refinedName).symbol - if (!tsym.exists) super.refinementNameString(tp) - else simpleNameString(tsym) - } - - override def toText(tp: Type): Text = controlled { - def toTextTuple(args: List[Type]): Text = - "(" ~ Text(args.map(argText), ", ") ~ ")" - def toTextFunction(args: List[Type]): Text = - changePrec(GlobalPrec) { - val argStr: Text = - if (args.length == 2 && !defn.isTupleType(args.head)) - atPrec(InfixPrec) { argText(args.head) } - else - toTextTuple(args.init) - argStr ~ " => " ~ argText(args.last) - } - homogenize(tp) match { - case AppliedType(tycon, args) => - val cls = tycon.typeSymbol - if (tycon.isRepeatedParam) return toTextLocal(args.head) ~ "*" - if (defn.isFunctionClass(cls)) return toTextFunction(args) - if (defn.isTupleClass(cls)) return toTextTuple(args) - return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close - case tp: TypeRef => - val hideType = tp.symbol is AliasPreferred - if (hideType && !ctx.phase.erasedTypes && !tp.symbol.isCompleting) { - tp.info match { - case TypeAlias(alias) => return toText(alias) - case _ => if (tp.prefix.isInstanceOf[ThisType]) return nameString(tp.symbol) - } - } - else if (tp.symbol.isAnonymousClass && !ctx.settings.uniqid.value) - return toText(tp.info) - case ExprType(result) => - return "=> " ~ toText(result) - case ErasedValueType(tycon, underlying) => - return "ErasedValueType(" ~ toText(tycon) ~ ", " ~ toText(underlying) ~ ")" - case tp: ClassInfo => - return toTextParents(tp.parentsWithArgs) ~ "{...}" - case JavaArrayType(elemtp) => - return toText(elemtp) ~ "[]" - case tp: AnnotatedType if homogenizedView => - // Positions of annotations in types are not serialized - // (they don't need to because we keep the original type tree with - // the original annotation anyway. Therefore, there will always be - // one version of the annotation tree that has the correct positions). - withoutPos(super.toText(tp)) - case tp: SelectionProto => - return "?{ " ~ toText(tp.name) ~ (" " provided !tp.name.decode.last.isLetterOrDigit) ~ - ": " ~ toText(tp.memberProto) ~ " }" - case tp: ViewProto => - return toText(tp.argType) ~ " ?=>? " ~ toText(tp.resultType) - case tp @ FunProto(args, resultType, _) => - val argsText = args match { - case dummyTreeOfType(tp) :: Nil if !(tp isRef defn.NullClass) => "null: " ~ toText(tp) - case _ => toTextGlobal(args, ", ") - } - return "FunProto(" ~ argsText ~ "):" ~ toText(resultType) - case tp: IgnoredProto => - return "?" - case _ => - } - super.toText(tp) - } - - def blockText[T >: Untyped](trees: List[Tree[T]]): Text = - ("{" ~ toText(trees, "\n") ~ "}").close - - override def toText[T >: Untyped](tree: Tree[T]): Text = controlled { - - import untpd.{modsDeco => _, _} - - /** Print modifiers from symbols if tree has type, overriding the untpd behavior. */ - implicit def modsDeco(mdef: untpd.MemberDef)(implicit ctx: Context): untpd.ModsDecorator = - new untpd.ModsDecorator { - def mods = if (mdef.hasType) Modifiers(mdef.symbol) else mdef.rawMods - } - - def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers = untpd.Modifiers( - sym.flags & (if (sym.isType) ModifierFlags | VarianceFlags else ModifierFlags), - if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY, - sym.annotations map (_.tree)) - - def isLocalThis(tree: Tree) = tree.typeOpt match { - case tp: ThisType => tp.cls == ctx.owner.enclosingClass - case _ => false - } - - def optDotPrefix(tree: This) = optText(tree.qual)(_ ~ ".") provided !isLocalThis(tree) - - def optAscription(tpt: untpd.Tree) = optText(tpt)(": " ~ _) - // Dotty deviation: called with an untpd.Tree, so cannot be a untpd.Tree[T] (seems to be a Scala2 problem to allow this) - // More deviations marked below as // DD - - def tparamsText[T >: Untyped](params: List[Tree]): Text = - "[" ~ toText(params, ", ") ~ "]" provided params.nonEmpty - - def addVparamssText(txt: Text, vparamss: List[List[ValDef]]): Text = - (txt /: vparamss)((txt, vparams) => txt ~ "(" ~ toText(vparams, ", ") ~ ")") - - def caseBlockText(tree: Tree): Text = tree match { - case Block(stats, expr) => toText(stats :+ expr, "\n") - case expr => toText(expr) - } - - def enumText(tree: untpd.Tree) = tree match { // DD - case _: untpd.GenFrom | _: untpd.GenAlias => toText(tree) - case _ => "if " ~ toText(tree) - } - - def forText(enums: List[untpd.Tree], expr: untpd.Tree, sep: String): Text = // DD - changePrec(GlobalPrec) { "for " ~ Text(enums map enumText, "; ") ~ sep ~ toText(expr) } - - def cxBoundToText(bound: untpd.Tree): Text = bound match { // DD - case AppliedTypeTree(tpt, _) => " : " ~ toText(tpt) - case untpd.Function(_, tpt) => " <% " ~ toText(tpt) - } - - def constrText(tree: untpd.Tree): Text = toTextLocal(tree).stripPrefix("new ") // DD - - def annotText(tree: untpd.Tree): Text = "@" ~ constrText(tree) // DD - - def useSymbol = - tree.hasType && tree.symbol.exists && ctx.settings.YprintSyms.value - - def modText(mods: untpd.Modifiers, kw: String): Text = { // DD - val suppressKw = if (enclDefIsClass) mods is ParamAndLocal else mods is Param - var flagMask = - if (ctx.settings.debugFlags.value) AnyFlags - else if (suppressKw) PrintableFlags &~ Private - else PrintableFlags - if (homogenizedView && mods.flags.isTypeFlags) flagMask &~= Implicit // drop implicit from classes - val flagsText = (mods.flags & flagMask).toString - Text(mods.annotations.map(annotText), " ") ~~ flagsText ~~ (kw provided !suppressKw) - } - - def varianceText(mods: untpd.Modifiers) = - if (mods is Covariant) "+" - else if (mods is Contravariant) "-" - else "" - - def argText(arg: Tree): Text = arg match { - case arg: TypeBoundsTree => "_" ~ toTextGlobal(arg) - case arg: TypeTree => - arg.typeOpt match { - case tp: TypeBounds => "_" ~ toTextGlobal(arg) - case _ => toTextGlobal(arg) - } - case _ => toTextGlobal(arg) - } - - def dclTextOr(treeText: => Text) = - if (useSymbol) - annotsText(tree.symbol) ~~ dclText(tree.symbol) ~ - ( " <in " ~ toText(tree.symbol.owner) ~ ">" provided ctx.settings.debugOwners.value) - else treeText - - def idText(tree: untpd.Tree): Text = { - if (ctx.settings.uniqid.value && tree.hasType && tree.symbol.exists) s"#${tree.symbol.id}" else "" - } - - def nameIdText(tree: untpd.NameTree): Text = - 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 - val tparamsTxt = withEnclosingDef(constr) { tparamsText(tparams) } - val primaryConstrs = if (constr.rhs.isEmpty) Nil else constr :: Nil - val prefix: Text = - if (vparamss.isEmpty || primaryConstrs.nonEmpty) tparamsTxt - else { - var modsText = modText(constr.mods, "") - if (!modsText.isEmpty) modsText = " " ~ modsText - if (constr.mods.hasAnnotations && !constr.mods.hasFlags) modsText = modsText ~~ " this" - withEnclosingDef(constr) { addVparamssText(tparamsTxt ~~ modsText, vparamss) } - } - val parentsText = Text(parents map constrText, " with ") - val selfText = { - val selfName = if (self.name == nme.WILDCARD) "this" else self.name.toString - (selfName ~ optText(self.tpt)(": " ~ _) ~ " =>").close - } provided !self.isEmpty - val bodyText = "{" ~~ selfText ~~ toTextGlobal(primaryConstrs ::: impl.body, "\n") ~ "}" - prefix ~ (" extends" provided !ofNew) ~~ parentsText ~~ bodyText - } - - def toTextPackageId(pid: Tree): Text = - if (homogenizedView && pid.hasType) toTextLocal(pid.tpe) - else toTextLocal(pid) - - def toTextCore(tree: Tree): Text = tree match { - case id: Trees.BackquotedIdent[_] if !homogenizedView => - "`" ~ toText(id.name) ~ "`" - case Ident(name) => - tree.typeOpt match { - 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 tree @ Select(qual, name) => - if (qual.isType) toTextLocal(qual) ~ "#" ~ toText(name) - else toTextLocal(qual) ~ ("." ~ nameIdText(tree) provided name != nme.CONSTRUCTOR) - case tree: This => - optDotPrefix(tree) ~ "this" ~ idText(tree) - case Super(qual: This, mix) => - optDotPrefix(qual) ~ "super" ~ optText(mix)("[" ~ _ ~ "]") - case Apply(fun, args) => - if (fun.hasType && fun.symbol == defn.throwMethod) - changePrec (GlobalPrec) { - "throw " ~ toText(args.head) - } - else - toTextLocal(fun) ~ "(" ~ toTextGlobal(args, ", ") ~ ")" - case TypeApply(fun, args) => - toTextLocal(fun) ~ "[" ~ toTextGlobal(args, ", ") ~ "]" - case Literal(c) => - tree.typeOpt match { - case ConstantType(tc) => toText(tc) - case _ => toText(c) - } - case New(tpt) => - "new " ~ { - tpt match { - case tpt: Template => toTextTemplate(tpt, ofNew = true) - case _ => - if (tpt.hasType) - toTextLocal(tpt.typeOpt.underlyingClassRef(refinementOK = false)) - else - toTextLocal(tpt) - } - } - case Typed(expr, tpt) => - changePrec(InfixPrec) { toText(expr) ~ ": " ~ toText(tpt) } - case NamedArg(name, arg) => - toText(name) ~ " = " ~ toText(arg) - case Assign(lhs, rhs) => - changePrec(GlobalPrec) { toTextLocal(lhs) ~ " = " ~ toText(rhs) } - case Block(stats, expr) => - blockText(stats :+ expr) - case If(cond, thenp, elsep) => - changePrec(GlobalPrec) { - "if " ~ toText(cond) ~ (" then" provided !cond.isInstanceOf[Parens]) ~~ toText(thenp) ~ optText(elsep)(" else " ~ _) - } - case Closure(env, ref, target) => - "closure(" ~ (toTextGlobal(env, ", ") ~ " | " provided env.nonEmpty) ~ - toTextGlobal(ref) ~ (":" ~ toText(target) provided !target.isEmpty) ~ ")" - case Match(sel, cases) => - if (sel.isEmpty) blockText(cases) - else changePrec(GlobalPrec) { toText(sel) ~ " match " ~ blockText(cases) } - case CaseDef(pat, guard, body) => - "case " ~ inPattern(toText(pat)) ~ optText(guard)(" if " ~ _) ~ " => " ~ caseBlockText(body) - case Return(expr, from) => - changePrec(GlobalPrec) { "return" ~ optText(expr)(" " ~ _) } - case Try(expr, cases, finalizer) => - changePrec(GlobalPrec) { - "try " ~ toText(expr) ~ optText(cases)(" catch " ~ _) ~ optText(finalizer)(" finally " ~ _) - } - case Throw(expr) => - changePrec(GlobalPrec) { - "throw " ~ toText(expr) - } - case SeqLiteral(elems, elemtpt) => - "[" ~ toTextGlobal(elems, ",") ~ " : " ~ toText(elemtpt) ~ "]" - case tree @ Inlined(call, bindings, body) => - (("/* inlined from " ~ toText(call) ~ "*/ ") provided !homogenizedView) ~ - blockText(bindings :+ body) - case tpt: untpd.DerivedTypeTree => - "<derived typetree watching " ~ summarized(toText(tpt.watched)) ~ ">" - case TypeTree() => - toText(tree.typeOpt) - case SingletonTypeTree(ref) => - toTextLocal(ref) ~ ".type" - case AndTypeTree(l, r) => - changePrec(AndPrec) { toText(l) ~ " & " ~ toText(r) } - case OrTypeTree(l, r) => - changePrec(OrPrec) { toText(l) ~ " | " ~ toText(r) } - case RefinedTypeTree(tpt, refines) => - toTextLocal(tpt) ~ " " ~ blockText(refines) - case AppliedTypeTree(tpt, args) => - toTextLocal(tpt) ~ "[" ~ Text(args map argText, ", ") ~ "]" - case PolyTypeTree(tparams, body) => - changePrec(GlobalPrec) { - tparamsText(tparams) ~ " -> " ~ toText(body) - } - case ByNameTypeTree(tpt) => - "=> " ~ toTextLocal(tpt) - case TypeBoundsTree(lo, hi) => - optText(lo)(" >: " ~ _) ~ optText(hi)(" <: " ~ _) - case Bind(name, body) => - changePrec(InfixPrec) { toText(name) ~ " @ " ~ toText(body) } - case Alternative(trees) => - changePrec(OrPrec) { toText(trees, " | ") } - case UnApply(fun, implicits, patterns) => - val extractor = fun match { - case Select(extractor, nme.unapply) => extractor - case _ => fun - } - toTextLocal(extractor) ~ - "(" ~ toTextGlobal(patterns, ", ") ~ ")" ~ - ("(" ~ toTextGlobal(implicits, ", ") ~ ")" provided implicits.nonEmpty) - case tree @ ValDef(name, tpt, _) => - dclTextOr { - modText(tree.mods, if (tree.mods is Mutable) "var" else "val") ~~ - nameIdText(tree) ~ optAscription(tpt) ~ - withEnclosingDef(tree) { optText(tree.rhs)(" = " ~ _) } - } - case tree @ DefDef(name, tparams, vparamss, tpt, _) => - dclTextOr { - val prefix = modText(tree.mods, "def") ~~ nameIdText(tree) - withEnclosingDef(tree) { - addVparamssText(prefix ~ tparamsText(tparams), vparamss) ~ optAscription(tpt) ~ - optText(tree.rhs)(" = " ~ _) - } - } - case tree @ TypeDef(name, rhs) => - def typeDefText(tparamsText: => Text, rhsText: => Text) = - dclTextOr { - modText(tree.mods, "type") ~~ (varianceText(tree.mods) ~ nameIdText(tree)) ~ - withEnclosingDef(tree) { - if (tree.hasType) toText(tree.symbol.info) // TODO: always print RHS, once we pickle/unpickle type trees - else tparamsText ~ rhsText - } - } - def recur(rhs: Tree, tparamsTxt: => Text): Text = rhs match { - case impl: Template => - modText(tree.mods, if ((tree).mods is Trait) "trait" else "class") ~~ - nameIdText(tree) ~ withEnclosingDef(tree) { toTextTemplate(impl) } ~ - (if (tree.hasType && ctx.settings.verbose.value) i"[decls = ${tree.symbol.info.decls}]" else "") - case rhs: TypeBoundsTree => - typeDefText(tparamsTxt, toText(rhs)) - case PolyTypeTree(tparams, body) => - recur(body, tparamsText(tparams)) - case rhs => - typeDefText(tparamsTxt, optText(rhs)(" = " ~ _)) - } - recur(rhs, "") - case Import(expr, selectors) => - def selectorText(sel: Tree): Text = sel match { - case Thicket(l :: r :: Nil) => toTextGlobal(l) ~ " => " ~ toTextGlobal(r) - case _ => toTextGlobal(sel) - } - val selectorsText: Text = selectors match { - case id :: Nil => toText(id) - case _ => "{" ~ Text(selectors map selectorText, ", ") ~ "}" - } - "import " ~ toTextLocal(expr) ~ "." ~ selectorsText - case PackageDef(pid, stats) => - val statsText = stats match { - case (pdef: PackageDef) :: Nil => toText(pdef) - case _ => toTextGlobal(stats, "\n") - } - val bodyText = - if (currentPrecedence == TopLevelPrec) "\n" ~ statsText else " {" ~ statsText ~ "}" - "package " ~ toTextPackageId(pid) ~ bodyText - case tree: Template => - toTextTemplate(tree) - case Annotated(arg, annot) => - toTextLocal(arg) ~~ annotText(annot) - case EmptyTree => - "<empty>" - case TypedSplice(t) => - toText(t) - case tree @ ModuleDef(name, impl) => - withEnclosingDef(tree) { - modText(tree.mods, "object") ~~ nameIdText(tree) ~ toTextTemplate(impl) - } - case SymbolLit(str) => - "'" + str - case InterpolatedString(id, segments) => - def strText(str: Literal) = Str(escapedString(str.const.stringValue)) - def segmentText(segment: Tree) = segment match { - case Thicket(List(str: Literal, expr)) => strText(str) ~ "{" ~ toTextGlobal(expr) ~ "}" - case str: Literal => strText(str) - } - toText(id) ~ "\"" ~ Text(segments map segmentText, "") ~ "\"" - case Function(args, body) => - var implicitSeen: Boolean = false - def argToText(arg: Tree) = arg match { - case arg @ ValDef(name, tpt, _) => - val implicitText = - if ((arg.mods is Implicit) && !implicitSeen) { implicitSeen = true; "implicit " } - else "" - implicitText ~ toText(name) ~ optAscription(tpt) - case _ => - toText(arg) - } - val argsText = args match { - case (arg @ ValDef(_, tpt, _)) :: Nil if tpt.isEmpty => argToText(arg) - case _ => "(" ~ Text(args map argToText, ", ") ~ ")" - } - changePrec(GlobalPrec) { - argsText ~ " => " ~ toText(body) - } - case InfixOp(l, op, r) => - val opPrec = parsing.precedence(op) - changePrec(opPrec) { toText(l) ~ " " ~ toText(op) ~ " " ~ toText(r) } - case PostfixOp(l, op) => - changePrec(InfixPrec) { toText(l) ~ " " ~ toText(op) } - case PrefixOp(op, r) => - changePrec(DotPrec) { toText(op) ~ " " ~ toText(r) } - case Parens(t) => - "(" ~ toTextGlobal(t) ~ ")" - case Tuple(ts) => - "(" ~ toTextGlobal(ts, ", ") ~ ")" - case WhileDo(cond, body) => - changePrec(GlobalPrec) { "while " ~ toText(cond) ~ " do " ~ toText(body) } - case DoWhile(cond, body) => - changePrec(GlobalPrec) { "do " ~ toText(body) ~ " while " ~ toText(cond) } - case ForYield(enums, expr) => - forText(enums, expr, " yield ") - case ForDo(enums, expr) => - forText(enums, expr, " do ") - case GenFrom(pat, expr) => - toText(pat) ~ " <- " ~ toText(expr) - case GenAlias(pat, expr) => - toText(pat) ~ " = " ~ toText(expr) - case ContextBounds(bounds, cxBounds) => - (toText(bounds) /: cxBounds) {(t, cxb) => - t ~ cxBoundToText(cxb) - } - case PatDef(mods, pats, tpt, rhs) => - modText(mods, "val") ~~ toText(pats, ", ") ~ optAscription(tpt) ~ - optText(rhs)(" = " ~ _) - case ParsedTry(expr, handler, finalizer) => - changePrec(GlobalPrec) { - "try " ~ toText(expr) ~ " catch {" ~ toText(handler) ~ "}" ~ optText(finalizer)(" finally " ~ _) - } - case Thicket(trees) => - "Thicket {" ~~ toTextGlobal(trees, "\n") ~~ "}" - 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) { - // 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 (!suppressTypes) - txt = ("<" ~ txt ~ ":" ~ toText(tp) ~ ">").close - else if (tree.isType && !homogenizedView) - txt = toText(tp) - } - if (printPos && !suppressPositions) { - // add positions - val pos = - if (homogenizedView && !tree.isInstanceOf[MemberDef]) tree.pos.toSynthetic - else tree.pos - val clsStr = ""//if (tree.isType) tree.getClass.toString else "" - txt = (txt ~ "@" ~ pos.toString ~ clsStr).close - } - tree match { - case Block(_, _) | Template(_, _, _, _) => txt - case _ => txt.close - } - } - - def optText(name: Name)(encl: Text => Text): Text = - if (name.isEmpty) "" else encl(toText(name)) - - def optText[T >: Untyped](tree: Tree[T])(encl: Text => Text): Text = - if (tree.isEmpty) "" else encl(toText(tree)) - - def optText[T >: Untyped](tree: List[Tree[T]])(encl: Text => Text): Text = - if (tree.exists(!_.isEmpty)) encl(blockText(tree)) else "" - - override protected def polyParamNameString(name: TypeName): String = - name.unexpandedName.toString - - override protected def treatAsTypeParam(sym: Symbol): Boolean = sym is TypeParam - - override protected def treatAsTypeArg(sym: Symbol) = - sym.isType && (sym is ProtectedLocal) && - (sym.allOverriddenSymbols exists (_ is TypeParam)) - - override def toText(sym: Symbol): Text = { - if (sym.isImport) { - def importString(tree: untpd.Tree) = s"import ${tree.show}" - sym.infoOrCompleter match { - case info: Namer#Completer => return importString(info.original) - case info: ImportType => return importString(info.expr) - case _ => - } - } - if (sym.is(ModuleClass)) - kindString(sym) ~~ (nameString(sym.name.stripModuleClassSuffix) + idString(sym)) - else - super.toText(sym) - } - - override def kindString(sym: Symbol) = { - val flags = sym.flagsUNSAFE - if (flags is Package) "package" - else if (sym.isPackageObject) "package object" - else if (flags is Module) "object" - else if (flags is ImplClass) "class" - else if (sym.isClassConstructor) "constructor" - else super.kindString(sym) - } - - override protected def keyString(sym: Symbol): String = { - val flags = sym.flagsUNSAFE - if (sym.isType && sym.owner.isTerm) "" - else super.keyString(sym) - } - - override def toTextFlags(sym: Symbol) = - if (ctx.settings.debugFlags.value) - super.toTextFlags(sym) - else { - var flags = sym.flagsUNSAFE - if (flags is TypeParam) flags = flags &~ Protected - Text((flags & PrintableFlags).flagStrings map stringToText, " ") - } - - override def toText(denot: Denotation): Text = denot match { - case denot: MultiDenotation => Text(denot.alternatives.map(dclText), " <and> ") - case NoDenotation => "NoDenotation" - case _ => - if (denot.symbol.exists) toText(denot.symbol) - else "some " ~ toText(denot.info) - } - - override def plain = new PlainPrinter(_ctx) -} |