summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-05-29 14:30:07 +0000
committerMartin Odersky <odersky@gmail.com>2009-05-29 14:30:07 +0000
commit02827fb0819f36d5cebd52ff2c1f5688f7fc2575 (patch)
tree7112b926ba796e296bab31df0e4e0d922bfd697d
parent3f04dd4462d59bfb8c5b5fc659c31cfaa4ce7653 (diff)
downloadscala-02827fb0819f36d5cebd52ff2c1f5688f7fc2575.tar.gz
scala-02827fb0819f36d5cebd52ff2c1f5688f7fc2575.tar.bz2
scala-02827fb0819f36d5cebd52ff2c1f5688f7fc2575.zip
minor twiddling with position.
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala38
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/Positions.scala14
-rw-r--r--src/compiler/scala/tools/nsc/interactive/REPL.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala24
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala59
5 files changed, 109 insertions, 28 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index f57eed60b8..3de4df932f 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -116,6 +116,10 @@ trait Trees {
this
}
+ def setOriginal(tree: Tree): this.type = {
+ setPos(SyntheticAliasPosition(tree))
+ }
+
def setType(tp: Type): this.type = {
/*assert(kindingIrrelevant(tp) || !kindStar || !tp.isHigherKinded,
tp+" should not be higher-kinded");*/
@@ -424,6 +428,7 @@ trait Trees {
object emptyValDef
extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) {
override def isEmpty = true
+ setPos(NoPosition)
}
/** Method definition
@@ -585,7 +590,7 @@ trait Trees {
vparamss map (vps => vps.map { vd =>
ValDef(
Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos)
+ vd.name, vd.tpt.duplicate, EmptyTree).setOriginal(vd)
})
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
@@ -607,7 +612,7 @@ trait Trees {
!vparamss1.head.isEmpty && (vparamss1.head.head.mods.flags & IMPLICIT) != 0)
vparamss1 = List() :: vparamss1;
val superRef: Tree = Select(Super(nme.EMPTY.toTypeName, nme.EMPTY.toTypeName), nme.CONSTRUCTOR)
- val superCall = atPos(parents.head.pos) { (superRef /: argss) (Apply) }
+ val superCall = atPos(parents.head) { (superRef /: argss) (Apply) }
List(
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(()))))
}
@@ -824,12 +829,8 @@ trait Trees {
case class TypeTree() extends TypTree {
override def symbol = if (tpe == null) null else tpe.typeSymbol
- def setOriginal(tree: Tree): this.type = {
- setPos(SyntheticPosition(tree))
- }
-
def original: Tree = pos match {
- case SyntheticPosition(orig) => orig
+ case SyntheticAliasPosition(orig) => orig
case _ => null
}
@@ -1705,12 +1706,29 @@ trait Trees {
}
}
+ object syntheticMaker extends Traverser {
+ override def traverse(t: Tree) {
+ if (!t.pos.isSynthetic) {
+ t setPos t.pos.toSynthetic
+ super.traverse(t)
+ }
+ }
+ }
+
def atPos[T <: Tree](pos: Position)(tree: T): T = {
posAssigner.pos = pos
posAssigner.traverse(tree)
tree
}
+ def atPos[T <: Tree](original: Tree)(tree: T): T =
+ atPos(SyntheticAliasPosition(original))(tree)
+
+ def makeSynthetic[T <: Tree](tree: T): T = {
+ syntheticMaker.traverse(tree)
+ tree
+ }
+
class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
override def traverse(t: Tree) {
f(t)
@@ -1789,7 +1807,7 @@ trait Trees {
/** A position to be used for synthetic trees that correspond to some original tree
* @note Trees with synthetic positions may not contain trees with real positions inside them!
*/
- case class SyntheticPosition(original: Tree) extends Position {
+ case class SyntheticAliasPosition(original: Tree) extends Position {
override def isDefined: Boolean = true
override def isSynthetic: Boolean = true
override def offset: Option[Int] = original.pos.offset
@@ -1798,7 +1816,9 @@ trait Trees {
override def point: Int = original.pos.point
override def end: Int = original.pos.end
override def underlying = original.pos.underlying
- override def focus = original.pos.focus
+ override def focusStart = original.pos.focusStart
+ override def focusPoint = original.pos.focusPoint
+ override def focusEnd = original.pos.focusEnd
override def show = "["+ underlying.show +"]"
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/Positions.scala b/src/compiler/scala/tools/nsc/interactive/Positions.scala
index f30fc83a2b..36c60e7a2c 100755
--- a/src/compiler/scala/tools/nsc/interactive/Positions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Positions.scala
@@ -91,7 +91,7 @@ self: Global =>
case ct :: trees1 =>
if (isTransparent(ct.pos))
iterate(ranges, solidDescendants(ct) ::: trees1)
- else if (ct.pos.isDefined) {
+ else if (ct.pos.isDefined && !ct.pos.isSynthetic) {
val conflicting = new ListBuffer[Tree]
val ranges1 = insert(ranges, ct, conflicting)
if (conflicting.isEmpty) {
@@ -113,9 +113,11 @@ self: Global =>
def findOverlapping(cts: List[Tree]): List[(Tree, Tree)] = {
var ranges = List(maxFree)
for (ct <- cts) {
- val conflicting = new ListBuffer[Tree]
- ranges = insert(ranges, ct, conflicting)
- if (conflicting.nonEmpty) return conflicting.toList map (t => (t, ct))
+ if (ct.pos.isDefined && !ct.pos.isSynthetic) {
+ val conflicting = new ListBuffer[Tree]
+ ranges = insert(ranges, ct, conflicting)
+ if (conflicting.nonEmpty) return conflicting.toList map (t => (t, ct))
+ }
}
List()
}
@@ -124,7 +126,6 @@ self: Global =>
/** The sorted list of descendant nodes, a long positions */
-
/** Set position of all children of a node
* @param pos A target position.
* Uses the point of the position as the point of all positions it assigns.
@@ -179,12 +180,15 @@ self: Global =>
inform(tree.toString)
}
def validate(tree: Tree, encltree: Tree) {
+ if (tree != EmptyTree && !tree.pos.isDefined)
+ error("tree without position: "+tree)
if (encltree.pos.isSynthetic && !tree.pos.isSynthetic)
error("synthetic "+encltree+" contains nonsynthetic" + tree)
if (!(encltree.pos includes tree.pos))
error(encltree+" does not include "+tree)
for ((t1, t2) <- findOverlapping(tree.children flatMap solidDescendants))
error("overlapping trees: "+t1+" === and === "+t2)
+ for (ct <- tree.children flatMap solidDescendants) validate(ct, tree)
}
validate(tree, tree)
}
diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala
index f63789fc9b..331cdd597a 100644
--- a/src/compiler/scala/tools/nsc/interactive/REPL.scala
+++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala
@@ -33,7 +33,7 @@ object REPL {
else {
try {
object compiler extends Global(command.settings, reporter) {
-// printTypings = true
+ printTypings = true
}
if (reporter.hasErrors) {
reporter.flush()
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 915786597c..002830bd0c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -576,13 +576,13 @@ trait Typers { self: Analyzer =>
case _ =>
}
}
- val qual = typedQualifier {
+ val qual = typedQualifier { atPos(tree.pos.focusStart) {
tree match {
case Ident(_) => Ident(nme.PACKAGEkw)
case Select(qual, _) => Select(qual, nme.PACKAGEkw)
case SelectFromTypeTree(qual, _) => Select(qual, nme.PACKAGEkw)
}
- }
+ }}
val tree1 = atPos(tree.pos) {
tree match {
case Ident(name) => Select(qual, name)
@@ -1226,12 +1226,12 @@ trait Typers { self: Analyzer =>
assert(getter != NoSymbol, stat)
if (getter hasFlag OVERLOADED)
error(getter.pos, getter+" is defined twice")
- val getterDef: DefDef = {
+ val getterDef: DefDef = atPos(vdef) {
getter.attributes = value.initialize.attributes
val result = DefDef(getter, vparamss =>
if (mods hasFlag DEFERRED) EmptyTree
else typed(
- atPos(vdef.pos) { gen.mkCheckInit(Select(This(value.owner), value)) },
+ atPos(vdef) { gen.mkCheckInit(Select(This(value.owner), value)) },
EXPRmode, value.tpe))
result.tpt.asInstanceOf[TypeTree] setOriginal tpt /* setPos tpt.pos */
checkNoEscaping.privates(getter, result.tpt)
@@ -1242,7 +1242,7 @@ trait Typers { self: Analyzer =>
def setterDef: DefDef = {
val setr = getter.setter(value.owner)
setr.attributes = value.attributes
- val result = atPos(vdef.pos)(
+ val result = atPos(vdef)(
DefDef(setr, vparamss =>
if ((mods hasFlag DEFERRED) || (setr hasFlag OVERLOADED))
EmptyTree
@@ -3071,7 +3071,7 @@ trait Typers { self: Analyzer =>
else if (!defSym.owner.isClass || defSym.owner.isPackageClass || defSym.isTypeParameterOrSkolem)
pre = NoPrefix
else
- qual = atPos(tree.pos)(gen.mkAttributedQualifier(pre))
+ qual = atPos(tree.pos.focusStart)(gen.mkAttributedQualifier(pre))
} else {
if (impSym.exists) {
var impSym1 = NoSymbol
@@ -3097,7 +3097,7 @@ trait Typers { self: Analyzer =>
imports1 = imports1.tail
}
defSym = impSym
- qual = atPos(tree.pos)(resetPos(imports.head.qual.duplicate))
+ qual = atPos(tree.pos.focusStart)(resetPos(imports.head.qual.duplicate))
pre = qual.tpe
} else {
if (settings.debug.value) {
@@ -3267,10 +3267,12 @@ trait Typers { self: Analyzer =>
if (selector == EmptyTree) {
val arity = if (isFunctionType(pt)) pt.normalize.typeArgs.length - 1 else 1
val params = for (i <- List.range(0, arity)) yield
- ValDef(Modifiers(PARAM | SYNTHETIC),
- unit.fresh.newName(tree.pos, "x" + i + "$"), TypeTree(), EmptyTree)
+ atPos(tree.pos.focusStart) {
+ ValDef(Modifiers(PARAM | SYNTHETIC),
+ unit.fresh.newName(tree.pos, "x" + i + "$"), TypeTree(), EmptyTree)
+ }
val ids = for (p <- params) yield Ident(p.name)
- val selector1 = atPos(tree.pos) { if (arity == 1) ids.head else gen.mkTuple(ids) }
+ val selector1 = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) }
val body = copy.Match(tree, selector1, cases)
typed1(atPos(tree.pos) { Function(params, body) }, mode, pt)
} else {
@@ -3426,7 +3428,7 @@ trait Typers { self: Analyzer =>
case TypeTree() =>
tree.pos match {
- case SyntheticPosition(original) =>
+ case SyntheticAliasPosition(original) =>
tree setType typedType(original, mode).tpe
case _ =>
// we should get here only when something before failed
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 6707bf6243..07b0a785d5 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -17,6 +17,7 @@ trait Position {
def source: Option[SourceFile] = None
def isDefined: Boolean = false
def isSynthetic: Boolean = false
+ def toSynthetic: Position = this
def start: Int = point
def point: Int = offset.get
@@ -26,8 +27,31 @@ trait Position {
def pointOrElse(d: Int) = offset.getOrElse(d)
def endOrElse(d: Int) = offset.getOrElse(d)
+ def withStart(off: Int) = this
+ def withEnd(off: Int) = this
+ def withPoint(off: Int) = this
+
+ /** If this is a range, the union with the other range, with the point of this position.
+ * Otherwise, this position
+ */
+ def union(pos: Position) = this
+
def underlying = this
- def focus = this
+
+ /** If this is a range position, the offset position of its start.
+ * Otherwise the position itself
+ */
+ def focusStart = this
+
+ /** If this is a range position, the offset position of its point.
+ * Otherwise the position itself
+ */
+ def focusPoint = this
+
+ /** If this is a range position, the offset position of its end.
+ * Otherwise the position itself
+ */
+ def focusEnd = this
def includes(pos: Position) =
isDefined && pos.isDefined && start <= pos.start && pos.end <= end
@@ -113,7 +137,9 @@ case class FakePos(msg: String) extends Position {
case class OffsetPosition(source0: SourceFile, offset0: Int) extends Position {
override def source = Some(source0)
override def offset = Some(offset0)
+ override def withPoint(off: Int) = new OffsetPosition(source0, off)
override def isDefined = true
+ override def toSynthetic: Position = new SyntheticOffsetPosition(source0, offset0)
override def equals(that : Any) = that match {
case that : OffsetPosition => offset0 == that.offset0 && source0.file == that.source0.file
case that => false
@@ -122,17 +148,46 @@ case class OffsetPosition(source0: SourceFile, offset0: Int) extends Position {
override def show = "["+point+"]"
}
+class SyntheticOffsetPosition(source0: SourceFile, offset0: Int) extends OffsetPosition(source0, offset0) {
+ override def isSynthetic = true
+ override def toSynthetic = this
+ override def withPoint(off: Int) = new SyntheticOffsetPosition(source0, off)
+}
+
/** new for position ranges */
class RangePosition(source0: SourceFile, override val start: Int, override val point: Int, override val end: Int)
extends OffsetPosition(source0, point) {
override def isDefined = true
override def startOrElse(d: Int) = start
override def pointOrElse(d: Int) = point
+ override def withStart(off: Int) = new RangePosition(source0, off, point, end)
+ override def withEnd(off: Int) = new RangePosition(source0, start, off, end)
+ override def withPoint(off: Int) = new RangePosition(source0, start, point, off)
+ override def union(pos: Position) = new RangePosition(source0, start min pos.start, point, end max pos.end)
override def endOrElse(d: Int) = end
- override def focus = OffsetPosition(source0, point)
+ override def focusStart = OffsetPosition(source0, start)
+ override def focusPoint = OffsetPosition(source0, point)
+ override def focusEnd = OffsetPosition(source0, end)
+ override def toSynthetic = new SyntheticRangePosition(source0, start, point, end)
override def toString = "RangePosition("+source0+", "+start+", "+point+", "+end+")"
override def show = "["+start+":"+end+"]"
}
+/** A position to be used for synthetic trees that do not correspond to some original tree
+ * @note Trees with synthetic positions may not contain trees with real positions inside them!
+ */
+class SyntheticRangePosition(source0: SourceFile, start: Int, point: Int, end: Int) extends RangePosition(source0, start, point, end) {
+ override def isSynthetic = true
+ override def toSynthetic = this
+ override def withStart(off: Int) = new SyntheticRangePosition(source0, off, point, end)
+ override def withEnd(off: Int) = new SyntheticRangePosition(source0, start, off, end)
+ override def withPoint(off: Int) = new SyntheticRangePosition(source0, start, point, off)
+ override def union(pos: Position) = new SyntheticRangePosition(source0, start min pos.start, point, end max pos.end)
+ override def focusStart = new SyntheticOffsetPosition(source0, start)
+ override def focusPoint = new SyntheticOffsetPosition(source0, point)
+ override def focusEnd = new SyntheticOffsetPosition(source0, end)
+}
+
+