summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-03-19 15:07:57 -0700
committerPaul Phillips <paulp@improving.org>2012-03-19 15:44:39 -0700
commit50bf852c9a48312e60b441d052150fdd78b52a1a (patch)
tree9447a262361a8a9642d2bb69f1ffbc2efa9bc0ac
parent78c15103d54e58b0ecd193b90e2d56b967967d6c (diff)
downloadscala-50bf852c9a48312e60b441d052150fdd78b52a1a.tar.gz
scala-50bf852c9a48312e60b441d052150fdd78b52a1a.tar.bz2
scala-50bf852c9a48312e60b441d052150fdd78b52a1a.zip
Tree adjustments.
I noticed that if we gave Ident a "qualifier" method which is always EmptyTree, a whole bunch of code could be simplified. A transparent subclass of Apply which preserves the source level "new" a little longer than never. Since productPrefix is tied up in reification - and oh I detest this "String"-based programming, we shouldn't have to wait until everyone learns this independently to change it - I added "printingPrefix" to Tree, which defaults to productPrefix but can be changed without breaking reify.
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala1
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala2
-rw-r--r--src/library/scala/reflect/api/TreePrinters.scala2
-rw-r--r--src/library/scala/reflect/api/Trees.scala25
6 files changed, 24 insertions, 10 deletions
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 1003fa804f..04381937d1 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -351,6 +351,8 @@ trait Importers { self: SymbolTable =>
new ApplyToImplicitArgs(importTree(fun), args map importTree)
case _: from.ApplyImplicitView =>
new ApplyImplicitView(importTree(fun), args map importTree)
+ case _: from.ApplyConstructor =>
+ new ApplyConstructor(importTree(fun), args map importTree)
case _ =>
new Apply(importTree(fun), args map importTree)
}
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 9678d2b8cd..d8e7ce68a2 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -1985,6 +1985,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isTrait) ("trait", "trait", "TRT")
else if (isClass) ("class", "class", "CLS")
else if (isType) ("type", "type", "TPE")
+ else if (isClassConstructor && isPrimaryConstructor) ("primary constructor", "constructor", "PCTOR")
else if (isClassConstructor) ("constructor", "constructor", "CTOR")
else if (isSourceMethod) ("method", "method", "METH")
else if (isTerm) ("value", "value", "VAL")
diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala
index f823110440..8ed0ee6357 100644
--- a/src/compiler/scala/reflect/internal/TreePrinters.scala
+++ b/src/compiler/scala/reflect/internal/TreePrinters.scala
@@ -433,7 +433,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
/** Hook for extensions */
def xprintTree(treePrinter: TreePrinter, tree: Tree) =
- treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")"))
+ treePrinter.print(tree.printingPrefix+tree.productIterator.mkString("(", ", ", ")"))
def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream))
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index d08a363a9d..88e3827403 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -189,7 +189,7 @@ self: scala.tools.nsc.Global =>
override def validatePositions(tree: Tree) {
def reportTree(prefix : String, tree : Tree) {
val source = if (tree.pos.isDefined) tree.pos.source else ""
- inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source)
+ inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.printingPrefix+" at "+tree.pos.show+source)
inform("")
inform(treeStatus(tree))
inform("")
diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala
index 21b55e9c0e..43865915d3 100644
--- a/src/library/scala/reflect/api/TreePrinters.scala
+++ b/src/library/scala/reflect/api/TreePrinters.scala
@@ -41,7 +41,7 @@ trait TreePrinters { self: Universe =>
else if (tree.original != null)
print(".setOriginal(", tree.original, ")")
case tree: Tree =>
- print(tree.productPrefix+"(")
+ print(tree.printingPrefix+"(")
val it = tree.productIterator
while (it.hasNext) {
it.next() match {
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index a355207ff0..a8276dc853 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -76,6 +76,12 @@ trait Trees { self: Universe =>
private[this] var rawpos: Position = NoPosition
+ /** Prefix under which to print this tree type. Defaults to product
+ * prefix (e.g. DefTree) but because that is used in reification
+ * it cannot be altered without breaking reflection.
+ */
+ def printingPrefix = productPrefix
+
def pos = rawpos
def pos_=(pos: Position) = rawpos = pos
def setPos(pos: Position): this.type = { rawpos = pos; this }
@@ -249,6 +255,7 @@ trait Trees { self: Universe =>
* are in DefTrees.
*/
trait RefTree extends SymTree {
+ def qualifier: Tree // empty for Idents
def name: Name
}
@@ -489,16 +496,14 @@ trait Trees { self: Universe =>
/** Factory method for object creation `new tpt(args_1)...(args_n)`
* A `New(t, as)` is expanded to: `(new t).<init>(as)`
*/
- def New(tpt: Tree, argss: List[List[Tree]]): Tree = {
- // todo. we need to expose names in scala.reflect.api
- val superRef: Tree = Select(New(tpt), nme.CONSTRUCTOR)
- if (argss.isEmpty) Apply(superRef, Nil)
- else (superRef /: argss) (Apply)
+ def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match {
+ case Nil => new ApplyConstructor(tpt, Nil)
+ case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply)
}
/** 0-1 argument list new, based on a type.
*/
def New(tpe: Type, args: Tree*): Tree =
- New(TypeTree(tpe), List(args.toList))
+ new ApplyConstructor(TypeTree(tpe), args.toList)
/** Type annotation, eliminated by explicit outer */
case class Typed(expr: Tree, tpt: Tree)
@@ -537,6 +542,10 @@ trait Trees { self: Universe =>
class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args)
+ class ApplyConstructor(tpt: Tree, args: List[Tree]) extends Apply(Select(New(tpt), nme.CONSTRUCTOR), args) {
+ override def printingPrefix = "ApplyConstructor"
+ }
+
/** Dynamic value application.
* In a dynamic application q.f(as)
* - q is stored in qual
@@ -575,7 +584,9 @@ trait Trees { self: Universe =>
Select(qualifier, sym.name) setSymbol sym
/** Identifier <name> */
- case class Ident(name: Name) extends RefTree
+ case class Ident(name: Name) extends RefTree {
+ def qualifier: Tree = EmptyTree
+ }
def Ident(name: String): Ident =
Ident(newTermName(name))