summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-06-02 21:32:36 +0000
committerMartin Odersky <odersky@gmail.com>2009-06-02 21:32:36 +0000
commitcf4c6c334a045b6da6ad9ea0249a6602e9558649 (patch)
tree8f75fb6513f42cfc183709b9609da2c183dc97dc
parent02ec6b9c108283f3657f4d1c3f33827da573dc03 (diff)
downloadscala-cf4c6c334a045b6da6ad9ea0249a6602e9558649.tar.gz
scala-cf4c6c334a045b6da6ad9ea0249a6602e9558649.tar.bz2
scala-cf4c6c334a045b6da6ad9ea0249a6602e9558649.zip
fixed some problems with positions.
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala18
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/ContextTrees.scala24
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/Positions.scala63
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala1
-rw-r--r--src/library/scala/Enumeration.scala13
6 files changed, 76 insertions, 45 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 53644c6bee..02768ddb5b 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -113,6 +113,10 @@ trait Trees {
def tpe_=(t: Type) = rawtpe = t
def setPos(pos: Position): this.type = {
+ pos match {
+ case SyntheticAliasPosition(orig) => assert(orig != this)
+ case _ =>
+ } // !!!
rawpos = pos;
this
}
@@ -569,17 +573,19 @@ trait Trees {
// create parameters for <init>
var vparamss1 =
vparamss map (vps => vps.map { vd =>
- ValDef(
- Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM) | PARAM) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.duplicate, vd.rhs.duplicate).setOriginal(vd)
- })
+ atPos(vd) {
+ ValDef(
+ Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations,
+ vd.name, atPos(vd.tpt) { vd.tpt.duplicate }, EmptyTree)
+ }})
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val (lvdefs, gvdefs) = List.unzip {
evdefs map {
case vdef @ ValDef(mods, name, tpt, rhs) =>
- (treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs),
- treeCopy.ValDef(vdef, mods, name, TypeTree(), EmptyTree))
+ val fld = atPos(vdef.pos) { treeCopy.ValDef(vdef, mods, name, TypeTree(), EmptyTree) }
+ val local = atPos(fld) { treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs) }
+ (local, fld)
}
}
val constrs =
diff --git a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala
index 5ed0581bdf..8d188cac62 100755
--- a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala
@@ -23,7 +23,7 @@ trait ContextTrees { self: Global =>
override def toString = "ContextTree("+pos+", "+children+")"
}
- /** Optionally return the smallest context taht contains given `pos`, or None if none exists.
+ /** Optionally return the smallest context that contains given `pos`, or None if none exists.
*/
def locateContext(contexts: Contexts, pos: Position): Option[Context] = {
if (contexts.isEmpty) None
@@ -32,17 +32,17 @@ trait ContextTrees { self: Global =>
if ((contexts(hi).pos precedes pos) || (pos precedes contexts(0).pos)) None
else {
def loop(lo: Int, hi: Int): Option[Context] = {
- assert(lo <= hi)
val mid = (lo + hi) / 2
val midpos = contexts(mid).pos
- if (pos precedes midpos)
- loop(lo, mid - 1)
- else if (midpos precedes pos)
- loop(mid + 1, hi)
+ if ((pos precedes midpos) && (mid < hi))
+ loop(lo, mid)
+ else if ((midpos precedes pos) && (lo < mid))
+ loop(mid, hi)
else if (midpos includes pos)
- locateContext(contexts(mid).children, pos) orElse Some(contexts(mid).context)
- else
- None
+ Some(contexts(mid).context)
+ else if (contexts(mid+1).pos includes pos)
+ Some(contexts(mid+1).context)
+ else None
}
loop(0, hi)
}
@@ -74,7 +74,7 @@ trait ContextTrees { self: Global =>
if (contexts(hi).pos properlyPrecedes cpos)
contexts += new ContextTree(cpos, context)
else if (contexts(hi).pos properlyIncludes cpos) // fast path w/o search
- addContext(contexts(hi).children, context)
+ addContext(contexts(hi).children, context, cpos)
else if (cpos properlyPrecedes contexts(0).pos)
new ContextTree(cpos, context) +: contexts
else {
@@ -84,7 +84,7 @@ trait ContextTrees { self: Global =>
contexts(idx) = new ContextTree(cpos, context, contexts(idx).children)
true
} else if (oldpos includes cpos) {
- addContext(contexts(idx).children, context)
+ addContext(contexts(idx).children, context, cpos)
true
} else if (cpos includes oldpos) {
val start = contexts.indexWhere(cpos includes _.pos)
@@ -116,6 +116,8 @@ trait ContextTrees { self: Global =>
}
} catch {
case ex: Throwable =>
+ println(ex)
+ ex.printStackTrace()
println("failure inserting "+cpos+" into "+contexts+"/"+contexts(contexts.length - 1).pos+"/"+
(contexts(contexts.length - 1).pos includes cpos))
throw ex
diff --git a/src/compiler/scala/tools/nsc/interactive/Positions.scala b/src/compiler/scala/tools/nsc/interactive/Positions.scala
index 2eaf32f6db..e253f2f3d8 100755
--- a/src/compiler/scala/tools/nsc/interactive/Positions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Positions.scala
@@ -66,6 +66,7 @@ self: Global =>
case r :: rs1 =>
assert(!isTransparent(t.pos))
if (r.isFree && (r.pos includes t.pos)) {
+// println("subdividing "+r+"/"+t.pos)
maybeFree(t.pos.end, r.pos.end) ::: List(Range(t.pos, t)) ::: maybeFree(r.pos.start, t.pos.start) ::: rs1
} else {
if (!r.isFree && (r.pos overlaps t.pos)) conflicting += r.tree
@@ -97,21 +98,25 @@ self: Global =>
case ct :: trees1 =>
if (isTransparent(ct.pos))
iterate(ranges, solidDescendants(ct) ::: trees1)
- else if (ct.pos.isDefined && !ct.pos.isSynthetic) {
+ else if (!ct.pos.isDefined || ct.pos.isSynthetic)
+ iterate(ranges, trees1)
+ else {
val conflicting = new ListBuffer[Tree]
val ranges1 = insert(ranges, ct, conflicting)
+// println("inserted "+ct+"; ranges = "+ranges1)
if (conflicting.isEmpty) {
iterate(ranges1, trees1)
} else {
val splitNode =
if (conflicting.size == 1 && (conflicting.head.pos includes ct.pos)) conflicting.head
else ct
+ println("splitting "+splitNode)
splitNode setPos new TransparentPosition(splitNode.pos.source.get, splitNode.pos.start, splitNode.pos.point, splitNode.pos.end)
ensureNonOverlapping(replace(cts, splitNode, solidDescendants(splitNode)))
}
}
}
-
+// println("ensure non overlap "+cts)
iterate(List(maxFree), cts)
}
@@ -137,26 +142,28 @@ self: Global =>
* Uses the point of the position as the point of all positions it assigns.
* Uses the start of this position as an Offset position for unpositioed trees
* without children.
- * @param trees The children to position
+ * @param trees The children to position. All children must be positionable.
*/
- private def setChildrenPos(pos: Position, trees: List[Tree]) {
+ private def setChildrenPos(pos: Position, trees: List[Tree]): Unit = try {
var currentPos = pos
for (tree <- trees) {
- if (isPositionable(tree) && tree.pos == NoPosition) {
- val children = tree.children
+ if (tree.pos == NoPosition) {
+ val children = tree.children filter isPositionable
if (children.isEmpty)
tree setPos OffsetPosition(pos.source.get, currentPos.start)
else {
setChildrenPos(currentPos, children)
- val positionableChildren = children filter (isPositionable(_))
tree setPos new RangePosition(
- pos.source.get, (positionableChildren map (_.pos.start)).min, pos.point, (positionableChildren map (_.pos.end)).max)
+ pos.source.get, (children map (_.pos.start)).min, pos.point, (children map (_.pos.end)).max)
}
currentPos = new RangePosition(pos.source.get, tree.pos.end, pos.point, pos.end)
}
-// println("set children pos "+pos+" of "+trees)
}
ensureNonOverlapping(trees)
+ } catch {
+ case ex: Exception =>
+ println("error while set children pos "+pos+" of "+trees)
+ throw ex
}
/** Position a tree.
@@ -169,7 +176,13 @@ self: Global =>
val children = tree.children
if (children.nonEmpty) {
if (children.tail.isEmpty) atPos(pos)(children.head)
- else setChildrenPos(pos, children)
+ else if (tree.isInstanceOf[Template]) {
+ println("setting children "+children)
+ setChildrenPos(pos, children filter isPositionable)
+ println("set children "+children)
+ } else {
+ setChildrenPos(pos, children filter isPositionable)
+ }
}
}
tree
@@ -186,20 +199,30 @@ self: Global =>
inform("================= in =================")
inform(tree.toString)
}
- def validate(tree: Tree, encltree: Tree) {
- if (isPositionable(tree) && !tree.pos.isDefined)
- error("tree without position: "+tree)
- if (encltree.pos.isSynthetic && !tree.pos.isDefined && tree.pos.isSynthetic)
- error("synthetic "+encltree+" contains nonsynthetic" + tree)
- if (tree.pos.isDefined && !(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)
+ def validate(tree: Tree, encltree: Tree): Unit = try {
+ if (isPositionable(tree)) {
+ if (!tree.pos.isDefined) {
+ error("tree without position: "+tree)
+ throw new ValidateError
+ }
+ if (encltree.pos.isSynthetic && !tree.pos.isDefined && tree.pos.isSynthetic)
+ error("synthetic "+encltree+" contains nonsynthetic" + tree)
+ if (tree.pos.isDefined && !(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)
+ }
+ } catch {
+ case ex: ValidateError =>
+ println("error while validating "+tree)
+ throw ex
}
validate(tree, tree)
}
+ class ValidateError extends Exception
+
// ---------------- Locating trees ----------------------------------
/** A locator for trees with given positions.
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index ec00d7fd96..75ecd9dfca 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -3899,7 +3899,7 @@ A type's typeSymbol should never be inspected directly.
val up = if (variance != CONTRAVARIANT) upper else !upper
tvar.constr.inst = null
val bound: Type = if (up) tparam.info.bounds.hi else tparam.info.bounds.lo
- // Console.println("solveOne0 "+tvar+" "+config+" "+bound);//DEBUG
+ //Console.println("solveOne0 "+tvar+" "+config+" "+bound);//DEBUG
var cyclic = bound contains tparam
for ((tvar2, (tparam2, variance2)) <- config) {
if (tparam2 != tparam &&
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 7a340176d9..e57e8bcc71 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -595,6 +595,7 @@ trait Infer {
}
()
}
+// println("solve "+tvars+" "+(tvars map (_.constr)))
val targs = solvedTypes(tvars, tparams, tparams map varianceInTypes(formals),
false, lubDepth(formals) max lubDepth(argtpes))
// val res =
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index f3a6b2f68c..7edd390c02 100644
--- a/src/library/scala/Enumeration.scala
+++ b/src/library/scala/Enumeration.scala
@@ -64,13 +64,12 @@ abstract class Enumeration(initial: Int, names: String*) {
/** The name of this enumeration.
*/
override def toString = {
- val cname = this.getClass().getName()
- if (cname endsWith "$")
- cname.substring(0, cname.length() - 1)
- else if (cname endsWith "$class")
- cname.substring(0, cname.length() - 6)
- else
- cname
+ var string = getClass.getName
+ val idx1 = string.lastIndexOf('.' : Int)
+ if (idx1 != -1) string = string.substring(idx1 + 1)
+ val idx2 = string.indexOf('$')
+ if (idx2 != -1) string = string.substring(0, idx2)
+ string
}
/** The mapping from the integer used to identifying values to the actual