diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/Interpreter.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/InterpreterLoop.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Settings.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreePrinters.scala | 307 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/MatchSupport.scala | 132 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Names.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 1 | ||||
-rw-r--r-- | test/files/run/treePrint.check | 5 | ||||
-rw-r--r-- | test/files/run/treePrint.scala | 40 |
12 files changed, 353 insertions, 208 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index 6ef1c19eac..e413911eb0 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -80,7 +80,10 @@ class Interpreter(val settings: Settings, out: PrintWriter) { /** have to be careful completion doesn't start querying global before it's ready */ private var _initialized = false def isInitialized = _initialized - private[nsc] def setInitialized = { + def initialize() = { + // forces something to be compiled + isettings + _initialized = true } diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala index 7a4668abcf..ab643def53 100644 --- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala +++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala @@ -222,19 +222,6 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) { /** Available commands */ def commands: List[Command] = standardCommands ::: (if (powerUserOn) powerCommands else Nil) - /* For some reason, the first interpreted command always takes - * a second or two. So, wait until the welcome message - * has been printed before calling isettings. That way, - * the user can read the welcome message while this - * command executes. - */ - private def initInterpreter() { - // forces something to be compiled - interpreter.isettings - // signals completion it's okay to proceed - interpreter.setInitialized - } - /** The main read-eval-print loop for the interpreter. It calls * <code>command()</code> for each line of input, and stops when * <code>command()</code> returns <code>false</code>. @@ -255,12 +242,12 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) { /* For some reason, the first interpreted command always takes * a second or two. So, wait until the welcome message - * has been printed before calling initInterpreter. That way, + * has been printed before calling initialize. That way, * the user can read the welcome message while this * command executes. */ val futLine = scala.concurrent.ops.future(readOneLine) - initInterpreter() + interpreter.initialize() if (!processLine(futLine())) return diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 05e12760a2..f15017f933 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -892,6 +892,7 @@ trait ScalacSettings { val check = PhasesSetting ("-Ycheck", "Check the tree at the end of") val Xcloselim = BooleanSetting ("-Yclosure-elim", "Perform closure elimination") val Xcodebase = StringSetting ("-Ycodebase", "codebase", "Specify the URL containing the Scala libraries", "") + val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees") val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL") val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination") val debug = BooleanSetting ("-Ydebug", "Output debugging messages") diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index fd7227c371..aa0e484578 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -350,4 +350,21 @@ abstract class TreeInfo { case TypeDef(_, _, _, _) => !isAbsTypeDef(tree) case _ => false } + + /** Some handy extractors for spotting true and false expressions + * through the haze of braces. + */ + abstract class SeeThroughBlocks[T] { + protected def unapplyImpl(x: Tree): T + def unapply(x: Tree): T = x match { + case Block(Nil, expr) => unapply(expr) + case _ => unapplyImpl(x) + } + } + object IsTrue extends SeeThroughBlocks[Boolean] { + protected def unapplyImpl(x: Tree): Boolean = x equalsStructure Literal(Constant(true)) + } + object IsFalse extends SeeThroughBlocks[Boolean] { + protected def unapplyImpl(x: Tree): Boolean = x equalsStructure Literal(Constant(false)) + } } diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 4ba5f17a40..c0b2fb41be 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -8,14 +8,14 @@ package scala.tools.nsc package ast import compat.Platform.{EOL => LINE_SEPARATOR} -import java.io.{OutputStream, PrintWriter, Writer} +import java.io.{ OutputStream, PrintWriter, StringWriter, Writer } import symtab.Flags._ import symtab.SymbolTable abstract class TreePrinters { - val trees: SymbolTable import trees._ + import treeInfo.{ IsTrue, IsFalse } final val showOuterTests = false @@ -29,6 +29,9 @@ abstract class TreePrinters { def indent = indentMargin += indentStep def undent = indentMargin -= indentStep + protected def doPrintPositions = settings.Xprintpos.value + def printPosition(tree: Tree) = if (doPrintPositions) print(tree.pos.show) + def println { out.println() while (indentMargin > indentString.length()) @@ -75,11 +78,11 @@ abstract class TreePrinters { def printParam(tree: Tree) { tree match { case ValDef(mods, name, tp, rhs) => - if (settings.Xprintpos.value) print(tree.pos.show) + printPosition(tree) printAnnotations(tree) print(symName(tree, name)); printOpt(": ", tp); printOpt(" = ", rhs) case TypeDef(mods, name, tparams, rhs) => - if (settings.Xprintpos.value) print(tree.pos.show) + printPosition(tree) print(symName(tree, name)) printTypeParams(tparams); print(rhs) } @@ -93,46 +96,49 @@ abstract class TreePrinters { printColumn(List(tree), "{", ";", "}") } } - def symName(tree: Tree, name: Name): String = - if (tree.symbol != null && tree.symbol != NoSymbol) { - ((if (tree.symbol.isMixinConstructor) "/*"+tree.symbol.owner.name+"*/" else "") + - tree.symbol.nameString) - } else name.toString(); + + private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = { + val nameToString: Name => String = if (decoded) _.decode else _.toString + + tree.symbol match { + case null | NoSymbol => nameToString(name) + case sym => + val prefix = if (sym.isMixinConstructor) "/*%s*/".format(nameToString(sym.owner.name)) else "" + prefix + tree.symbol.nameString + } + } + + def decodedSymName(tree: Tree, name: Name) = symNameInternal(tree, name, true) + def symName(tree: Tree, name: Name) = symNameInternal(tree, name, false) def printOpt(prefix: String, tree: Tree) { if (!tree.isEmpty) { print(prefix); print(tree) } } def printModifiers(tree: Tree, mods: Modifiers) { - if (tree.symbol == NoSymbol) - printFlags(mods.flags, mods.privateWithin.toString) - else if (tree.symbol.privateWithin == NoSymbol || - tree.symbol.privateWithin == tree.symbol.owner) - printFlags(tree.symbol.flags, "") - else - printFlags(tree.symbol.flags, tree.symbol.privateWithin.name.toString) + def pw = tree.symbol.privateWithin + val args = + if (tree.symbol == NoSymbol) (mods.flags, mods.privateWithin) + else if (pw == NoSymbol || pw == tree.symbol.owner) (tree.symbol.flags, "") + else (tree.symbol.flags, pw.name) + + printFlags(args._1, args._2.toString) } def printFlags(flags: Long, privateWithin: String) { var mask: Long = if (settings.debug.value) -1L else PrintableFlags val s = flagsToString(flags & mask, privateWithin) - if (s.length() != 0) print(s + " ") + if (s != "") print(s + " ") } def printAnnotations(tree: Tree) { - if (!tree.symbol.rawAnnotations.isEmpty) { - val annots = tree.symbol.annotations - if (!annots.isEmpty) { - annots foreach { annot => print("@"+annot+" ") } - println - } - } else { - val annots = tree.asInstanceOf[MemberDef].mods.annotations - if (!annots.isEmpty) { - annots foreach { annot => print("@"+annot+" ") } - println - } - } + val annots = + if (tree.symbol.rawAnnotations.nonEmpty) tree.symbol.annotations + else tree.asInstanceOf[MemberDef].mods.annotations + + annots foreach (annot => print("@"+annot+" ")) + if (annots.nonEmpty) + println } def print(str: String) { out.print(str) } @@ -165,7 +171,7 @@ abstract class TreePrinters { case ValDef(mods, name, tp, rhs) => printAnnotations(tree) printModifiers(tree, mods) - print(if (mods.hasFlag(MUTABLE)) "var " else "val ") + print(if (mods.isVariable) "var " else "val ") print(symName(tree, name)) printOpt(": ", tp) if (!mods.hasFlag(DEFERRED)) { @@ -389,7 +395,7 @@ abstract class TreePrinters { } def print(tree: Tree) { - if (settings.Xprintpos.value) print(tree.pos.show) + printPosition(tree) printRaw( if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) { tree match { @@ -417,11 +423,242 @@ abstract class TreePrinters { } } + + /** A tree printer which is stingier about vertical whitespace and unnecessary + * punctuation than the standard one. + */ + class CompactTreePrinter(out: PrintWriter) extends TreePrinter(out) { + override def printRow(ts: List[Tree], start: String, sep: String, end: String) { + print(start) + printSeq(ts)(print)(print(sep)) + print(end) + } + + // drill down through Blocks and pull out the real statements. + def allStatements(t: Tree): List[Tree] = t match { + case Block(stmts, expr) => (stmts flatMap allStatements) ::: List(expr) + case _ => List(t) + } + + def printLogicalOr(t1: (Tree, Boolean), t2: (Tree, Boolean)) = + printLogicalOp(t1, t2, "||") + + def printLogicalAnd(t1: (Tree, Boolean), t2: (Tree, Boolean)) = + printLogicalOp(t1, t2, "&&") + + def printLogicalOp(t1: (Tree, Boolean), t2: (Tree, Boolean), op: String) = { + def maybenot(tvalue: Boolean) = if (tvalue) "" else "!" + + print("%s(" format maybenot(t1._2)) + printRaw(t1._1) + print(") %s %s(".format(op, maybenot(t2._2))) + printRaw(t2._1) + print(")") + } + + override def printRaw(tree: Tree): Unit = { + // routing supercalls through this for debugging ease + def s() = super.printRaw(tree) + + tree match { + // labels used for jumps - does not map to valid scala code + case LabelDef(name, params, rhs) => + print("labeldef %s(%s) = ".format(name, params mkString ",")) + printRaw(rhs) + + case Ident(name) => + print(decodedSymName(tree, name)) + + // target.method(arg) ==> target method arg + case Apply(Select(target, method), List(arg)) => + if (method.decode.toString == "||") + printLogicalOr(target -> true, arg -> true) + else if (method.decode.toString == "&&") + printLogicalAnd(target -> true, arg -> true) + else (target, arg) match { + case (_: Ident, _: Literal | _: Ident) => + printRaw(target) + print(" ") + printRaw(Ident(method)) + print(" ") + printRaw(arg) + case _ => s() + } + + // target.unary_! ==> !target + case Select(qualifier, name) if (name.decode startsWith "unary_") => + print(name.decode drop 6) + printRaw(qualifier) + + case Select(qualifier, name) => + printRaw(qualifier) + print(".") + print(name.decode) + + // target.toString() ==> target.toString + case Apply(fn, Nil) => printRaw(fn) + + // if a Block only continues one actual statement, just print it. + case Block(stats, expr) => + allStatements(tree) match { + case List(x) => printRaw(x) + case xs => s() + } + + // We get a lot of this stuff + case If( IsTrue(), x, _) => printRaw(x) + case If(IsFalse(), _, x) => printRaw(x) + + case If(cond, IsTrue(), elsep) => printLogicalOr(cond -> true, elsep -> true) + case If(cond, IsFalse(), elsep) => printLogicalAnd(cond -> false, elsep -> true) + case If(cond, thenp, IsTrue()) => printLogicalOr(cond -> false, thenp -> true) + case If(cond, thenp, IsFalse()) => printLogicalAnd(cond -> true, thenp -> true) + + // If thenp or elsep has only one statement, it doesn't need more than one line. + case If(cond, thenp, elsep) => + def ifIndented(x: Tree) = { + indent ; println ; printRaw(x) ; undent + } + + val List(thenStmts, elseStmts) = List(thenp, elsep) map allStatements + print("if ("); print(cond); print(")") + + thenStmts match { + case List(x: If) => ifIndented(x) + case List(x) => printRaw(x) + case _ => printRaw(thenp) + } + + if (elseStmts.nonEmpty) { + print("else") + indent ; println + elseStmts match { + case List(x) => printRaw(x) + case _ => printRaw(elsep) + } + undent ; println + } + case _ => s() + } + } + } + + /** This must guarantee not to force any evaluation, so we can learn + * a little bit about trees in the midst of compilation without altering + * the natural course of events. + */ + class SafeTreePrinter(out: PrintWriter) extends TreePrinter(out) { + override def print(tree: Tree) { + printPosition(tree) + printRaw(tree) + } + private def default(t: Tree) = t.getClass.getName.reverse.takeWhile(_ != '.').reverse + private def params(trees: List[Tree]): String = trees map safe mkString ", " + + private def safe(name: Name): String = name.decode + private def safe(tree: Tree): String = tree match { + case Apply(fn, args) => "%s(%s)".format(safe(fn), params(args)) + case Select(qual, name) => safe(qual) + "." + safe(name) + case This(qual) => safe(qual) + ".this" + case Ident(name) => safe(name) + case Literal(value) => value.stringValue + case _ => "(?: %s)".format(default(tree)) + } + + override def printRaw(tree: Tree) { print(safe(tree)) } + } + + class TreeMatchTemplate { + // non-trees defined in Trees + // + // case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) + // case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree], positions: Map[Long, Position]) + // + def apply(t: Tree): Unit = t match { + // eliminated by typer + case Annotated(annot, arg) => + case AssignOrNamedArg(lhs, rhs) => + case DocDef(comment, definition) => + case Import(expr, selectors) => + + // eliminated by refchecks + case ModuleDef(mods, name, impl) => + + // eliminated by erasure + case TypeDef(mods, name, tparams, rhs) => + case Typed(expr, tpt) => + + // eliminated by cleanup + case ApplyDynamic(qual, args) => + + // eliminated by explicitouter + case Alternative(trees) => + case Bind(name, body) => + case CaseDef(pat, guard, body) => + case Star(elem) => + case UnApply(fun, args) => + + // eliminated by lambdalift + case Function(vparams, body) => + + // eliminated by uncurry + case AppliedTypeTree(tpt, args) => + case CompoundTypeTree(templ) => + case ExistentialTypeTree(tpt, whereClauses) => + case SelectFromTypeTree(qual, selector) => + case SingletonTypeTree(ref) => + case TypeBoundsTree(lo, hi) => + + // survivors + case Apply(fun, args) => + case ArrayValue(elemtpt, trees) => + case Assign(lhs, rhs) => + case Block(stats, expr) => + case ClassDef(mods, name, tparams, impl) => + case DefDef(mods, name, tparams, vparamss, tpt, rhs) => + case EmptyTree => + case Ident(name) => + case If(cond, thenp, elsep) => + case LabelDef(name, params, rhs) => + case Literal(value) => + case Match(selector, cases) => + case New(tpt) => + case PackageDef(pid, stats) => + case Return(expr) => + case Select(qualifier, selector) => + case Super(qual, mix) => + case Template(parents, self, body) => + case This(qual) => + case Throw(expr) => + case Try(block, catches, finalizer) => + case TypeApply(fun, args) => + case TypeTree() => + case ValDef(mods, name, tpt, rhs) => + + // missing from the Trees comment + case Parens(args) => // only used during parsing + case SelectFromArray(qual, name, erasure) => // only used during erasure + } + } + + private def asStringInternal(t: Tree, f: PrintWriter => TreePrinter): String = { + val buffer = new StringWriter() + val printer = f(new PrintWriter(buffer)) + printer.print(t) + printer.flush() + buffer.toString + } + def asString(t: Tree): String = asStringInternal(t, create) + def asCompactString(t: Tree): String = asStringInternal(t, createCompact) + def create(writer: PrintWriter): TreePrinter = new TreePrinter(writer) def create(stream: OutputStream): TreePrinter = create(new PrintWriter(stream)) - def create(): TreePrinter = { - create(new PrintWriter(ConsoleWriter)) - } + def create(): TreePrinter = create(new PrintWriter(ConsoleWriter)) + + def createCompact(writer: PrintWriter): CompactTreePrinter = new CompactTreePrinter(writer) + def createCompact(stream: OutputStream): CompactTreePrinter = createCompact(new PrintWriter(stream)) + def createCompact(): CompactTreePrinter = createCompact(new PrintWriter(ConsoleWriter)) + /** A writer that writes to the current Console and * is sensitive to replacement of the Console's * output stream. diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 0d94048f67..21f2919535 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -36,7 +36,9 @@ trait Trees { val trees: Trees.this.type = Trees.this } with TreePrinters - lazy val treePrinter = treePrinters.create() + lazy val treePrinter = + if (settings.Ycompacttrees.value) treePrinters.createCompact() + else treePrinters.create() object treeInfo extends { val trees: Trees.this.type = Trees.this @@ -197,13 +199,9 @@ trait Trees { productIterator.toList flatMap subtrees } - override def toString(): String = { - val buffer = new StringWriter() - val printer = treePrinters.create(new PrintWriter(buffer)) - printer.print(this) - printer.flush() - buffer.toString - } + override def toString(): String = + if (settings.Ycompacttrees.value) treePrinters.asCompactString(this) + else treePrinters.asString(this) override def hashCode(): Int = super.hashCode() @@ -834,9 +832,10 @@ trait Trees { /** Self reference */ case class This(qual: Name) - extends TermTree with SymTree + extends TermTree with SymTree { // The symbol of a This is the class to which the this refers. // For instance in C.this, it would be C. + } def This(sym: Symbol): Tree = This(sym.name) setSymbol sym diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala index 1722500066..e51919b7c2 100644 --- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala +++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala @@ -102,26 +102,13 @@ trait MatchSupport extends ast.TreeDSL pp(x match { case s: String => return clean(s) - case x: Tree => treeToCompactString(x) + case x: Tree => treePrinters asCompactString x case xs: List[_] => pplist(xs map pp) case x: Tuple2[_,_] => "%s -> %s".format(pp(x._1), pp(x._2)) case x => x.toString }) } - object compactTreePrinter extends CompactTreePrinter - - // def treeChildrenString(t: Tree): String = - // nodeToString(t) - - def treeToCompactString(t: Tree): String = { - val buffer = new StringWriter() - val printer = compactTreePrinter.create(new PrintWriter(buffer)) - printer.print(t) - printer.flush() - buffer.toString - } - def ifDebug(body: => Unit): Unit = { if (settings.debug.value) body } def DBG(msg: => String): Unit = { ifDebug(println(msg)) } @@ -166,121 +153,4 @@ trait MatchSupport extends ast.TreeDSL */ def extractIndex[T](xs: List[T], n: Int): (T, List[T]) = (xs(n), dropIndex(xs, n)) - - /** A tree printer which is stingier about vertical whitespace and unnecessary - * punctuation than the standard one. - */ - class CompactTreePrinter extends { - val trees: global.type = global - } with TreePrinters { - import trees._ - - override def create(writer: PrintWriter): TreePrinter = new TreePrinter(writer) { - // drill down through Blocks and pull out the real statements. - def allStatements(t: Tree): List[Tree] = t match { - case Block(stmts, expr) => (stmts flatMap allStatements) ::: List(expr) - case _ => List(t) - } - - def printLogicalOr(t1: (Tree, Boolean), t2: (Tree, Boolean)) = - printLogicalOp(t1, t2, "||") - - def printLogicalAnd(t1: (Tree, Boolean), t2: (Tree, Boolean)) = - printLogicalOp(t1, t2, "&&") - - def printLogicalOp(t1: (Tree, Boolean), t2: (Tree, Boolean), op: String) = { - def maybenot(tvalue: Boolean) = if (tvalue) "" else "!" - - printRow(List(t1._1, t2._1), - " %s(" format maybenot(t1._2), - ") %s %s(".format(op, maybenot(t2._2)), - ")" - ) - } - - override def printRaw(tree: Tree): Unit = { - // routing supercalls through this for debugging ease - def s() = super.printRaw(tree) - - tree match { - // labels used for jumps - does not map to valid scala code - case LabelDef(name, params, rhs) => - print("labeldef %s(%s) = ".format(name, params mkString ",")) - printRaw(rhs) - - // target.method(arg) ==> target method arg - case Apply(Select(target, method), List(arg)) => - (target, arg) match { - case (_: Ident, _: Literal | _: Ident) => - printRaw(target) - print(" %s " format symName(tree, method)) - printRaw(arg) - case _ => s() - } - - // target.unary_! ==> !target - case Select(qualifier, name) => - val n = symName(tree, name) - if (n startsWith "unary_") { - print(n drop 6) - print(qualifier) - } - else s() - - // target.toString() ==> target.toString - case Apply(fn, Nil) => printRaw(fn) - - // if a Block only continues one actual statement, just print it. - case Block(stats, expr) => - allStatements(tree) match { - case List(x) => printRow(List(x), "", ";", "") - case _ => s() - } - - // We get a lot of this stuff - case If( IsTrue(), x, _) => printRaw(x) - case If(IsFalse(), _, x) => printRaw(x) - - case If(cond, IsTrue(), elsep) => - printLogicalOr(cond -> true, elsep -> true) - - case If(cond, IsFalse(), elsep) => - printLogicalAnd(cond -> false, elsep -> true) - - case If(cond, thenp, IsTrue()) => - printLogicalOr(cond -> false, thenp -> true) - - case If(cond, thenp, IsFalse()) => - printLogicalAnd(cond -> true, thenp -> true) - - // If thenp or elsep has only one statement, it doesn't need more than one line. - case If(cond, thenp, elsep) => - printRow(List(cond), "if (", "", ") ") - - def ifIndented(x: Tree) = { - indent ; println ; printRaw(x) ; undent - } - - indent ; println ; - allStatements(thenp) match { - case List(x: If) => ifIndented(x) - case List(x) => printRaw(x) - case _ => printRaw(thenp) - } - undent ; println ; - val elseStmts = allStatements(elsep) - if (!elseStmts.isEmpty) { - print("else") - indent ; println - elseStmts match { - case List(x) => printRaw(x) - case xs => printRaw(elsep) - } - undent ; println - } - case _ => s() - } - } - } - } } diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala index 4f13d4fd99..fd55945d50 100644 --- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala +++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala @@ -20,22 +20,7 @@ trait MatrixAdditions extends ast.TreeDSL import symtab.Flags import CODE._ import Debug._ - - // Extractors which can spot pure true/false expressions - // even through the haze of braces - abstract class SeeThroughBlocks[T] { - protected def unapplyImpl(x: Tree): T - def unapply(x: Tree): T = x match { - case Block(Nil, expr) => unapply(expr) - case _ => unapplyImpl(x) - } - } - object IsTrue extends SeeThroughBlocks[Boolean] { - protected def unapplyImpl(x: Tree): Boolean = x equalsStructure TRUE - } - object IsFalse extends SeeThroughBlocks[Boolean] { - protected def unapplyImpl(x: Tree): Boolean = x equalsStructure FALSE - } + import treeInfo.{ IsTrue, IsFalse } /** The Squeezer, responsible for all the squeezing. */ diff --git a/src/compiler/scala/tools/nsc/symtab/Names.scala b/src/compiler/scala/tools/nsc/symtab/Names.scala index 5f5a220b8a..ddadc32202 100644 --- a/src/compiler/scala/tools/nsc/symtab/Names.scala +++ b/src/compiler/scala/tools/nsc/symtab/Names.scala @@ -390,6 +390,8 @@ class Names { def decode: String = ( NameTransformer.decode(toString()) + (if (nameDebug && isTypeName) "!" else ""))//debug + + def isOperatorName: Boolean = decode != toString } private class TermName(index: Int, len: Int, hash: Int) extends Name(index, len) { diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index f50dee615b..d6f4ef5672 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1745,7 +1745,6 @@ trait Symbols { /** A class for module symbols */ class ModuleSymbol(initOwner: Symbol, initPos: Position, initName: Name) extends TermSymbol(initOwner, initPos, initName) { - private var flatname = nme.EMPTY override def owner: Symbol = diff --git a/test/files/run/treePrint.check b/test/files/run/treePrint.check new file mode 100644 index 0000000000..3360815ac1 --- /dev/null +++ b/test/files/run/treePrint.check @@ -0,0 +1,5 @@ +def foo = { + var q: Boolean = false; + val x = 5; + ((x == 5) || (!q)) || (true) +} diff --git a/test/files/run/treePrint.scala b/test/files/run/treePrint.scala new file mode 100644 index 0000000000..ffe9a392d4 --- /dev/null +++ b/test/files/run/treePrint.scala @@ -0,0 +1,40 @@ +/** Testing compact tree printers. + */ +object Test { + import scala.tools.nsc._ + import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter} + + val code = """ + def foo = { + var q: Boolean = false + val x = if (true) { + if (true) { + if (true) { + 5 + } + else if (true) { + 5 + } else { + 10 + } + } + else 20 + } + else 30 + + (x == 5) || !q || true + } + """ + + class NullOutputStream extends OutputStream { def write(b: Int) { } } + + def main(args: Array[String]) { + val settings = new Settings + settings.classpath.value = System.getProperty("java.class.path") + settings.Ycompacttrees.value = true + + val repl = new Interpreter(settings, new PrintWriter(new NullOutputStream)) + repl.interpret("""def initialize = "Have to interpret something or we get errors." """) + println(repl mkTree code) + } +} |