summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala18
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala15
4 files changed, 26 insertions, 11 deletions
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 9a65ddaa96..3837517a3b 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -75,11 +75,26 @@ trait Trees { self: Universe =>
def isDef: Boolean
/** Is this tree one of the empty trees?
+ *
* Empty trees are: the `EmptyTree` null object, `TypeTree` instances that don't carry a type
* and the special `emptyValDef` singleton.
+ *
+ * In the compiler the `isEmpty` check and the derived `orElse` method are mostly used
+ * as a check for a tree being a null object (`EmptyTree` for term trees and empty TypeTree for type trees).
+ *
+ * Unfortunately `emptyValDef` is also considered to be `isEmpty`, but this is deemed to be
+ * a conceptual mistake pending a fix in https://issues.scala-lang.org/browse/SI-6762.
+ *
+ * @see `canHaveAttrs`
*/
def isEmpty: Boolean
+ /** Can this tree carry attributes (i.e. symbols, types or positions)?
+ * Typically the answer is yes, except for the `EmptyTree` null object and
+ * two special singletons: `emptyValDef` and `pendingSuperCall`.
+ */
+ def canHaveAttrs: Boolean
+
/** The canonical way to test if a Tree represents a term.
*/
def isTerm: Boolean
@@ -2852,7 +2867,8 @@ trait Trees { self: Universe =>
trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef])
/** Transforms a `ValDef`. */
def transformValDef(tree: ValDef): ValDef =
- if (tree.isEmpty) tree else transform(tree).asInstanceOf[ValDef]
+ if (tree eq emptyValDef) tree
+ else transform(tree).asInstanceOf[ValDef]
/** Transforms a list of `ValDef` nodes. */
def transformValDefs(trees: List[ValDef]): List[ValDef] =
trees mapConserve (transformValDef(_))
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index b65df0e70b..f8c670827a 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -38,7 +38,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
protected class DefaultPosAssigner extends PosAssigner {
var pos: Position = _
override def traverse(t: Tree) {
- if (t.isDummy) ()
+ if (!t.canHaveAttrs) ()
else if (t.pos == NoPosition) {
t.setPos(pos)
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 6f834803c4..a8085a4c58 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -435,7 +435,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case tree =>
xprintTree(this, tree)
}
- if (printTypes && tree.isTerm && !tree.isEmpty) {
+ if (printTypes && tree.isTerm && tree.canHaveAttrs) {
print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
}
}
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 5b7afdf5dd..dceec18e57 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -36,7 +36,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def isDef = false
def isEmpty = false
- def isDummy = false
+ def canHaveAttrs = true
/** The canonical way to test if a Tree represents a term.
*/
@@ -955,9 +955,8 @@ trait Trees extends api.Trees { self: SymbolTable =>
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
- trait DummyTree extends Tree {
- override def isEmpty = true
- override def isDummy = true
+ trait CannotHaveAttrs extends Tree {
+ override def canHaveAttrs = false
private def unsupported(what: String, args: Any*) =
throw new UnsupportedOperationException(s"$what($args) inapplicable for "+self.toString)
@@ -969,9 +968,9 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def tpe_=(t: Type) = if (t != NoType) unsupported("tpe_=", t)
}
- case object EmptyTree extends TermTree with DummyTree { val asList = List(this) }
- object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with DummyTree
- object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with DummyTree
+ case object EmptyTree extends TermTree with CannotHaveAttrs { override def isEmpty = true; val asList = List(this) }
+ object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with CannotHaveAttrs
+ object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with CannotHaveAttrs
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
atPos(sym.pos) {
@@ -1123,7 +1122,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
traverse(annot); traverse(arg)
case Template(parents, self, body) =>
traverseTrees(parents)
- if (!self.isEmpty) traverse(self)
+ if (self ne emptyValDef) traverse(self)
traverseStats(body, tree.symbol)
case Block(stats, expr) =>
traverseTrees(stats); traverse(expr)