summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-09-18 17:06:00 +0000
committerMartin Odersky <odersky@gmail.com>2010-09-18 17:06:00 +0000
commite2512790355a505648e1eb1787c571960e58409f (patch)
tree3b255465b98f47690d635011f3305fbcc523021b
parentbc3e3c54fba45125f3ab2e27a6add43ceaa8f49e (diff)
downloadscala-e2512790355a505648e1eb1787c571960e58409f.tar.gz
scala-e2512790355a505648e1eb1787c571960e58409f.tar.bz2
scala-e2512790355a505648e1eb1787c571960e58409f.zip
added typedLastTree functionality to CompilerCo...
added typedLastTree functionality to CompilerControl. Avoid some "tree not found" errors. Review by milessabin.
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala9
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala28
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala7
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala3
4 files changed, 39 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 1772f6f722..77d4f5416a 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -113,6 +113,15 @@ trait CompilerControl { self: Global =>
override def toString = "typecheck"
}
+ /** Set sync var `result` to the last fully attributed & typechecked tree produced from `source`.
+ * If no such tree exists yet, do a normal askType(source, false, result)
+ */
+ def askLastType(source: SourceFile, forceReload: Boolean, result: Response[Tree]) =
+ scheduler postWorkItem new WorkItem {
+ def apply() = self.getLastTypedTree(source, result)
+ override def toString = "reconcile"
+ }
+
/** Set sync var `result' to list of members that are visible
* as members of the tree enclosing `pos`, possibly reachable by an implicit.
*/
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 59221eb348..51aaa5125d 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -60,7 +60,7 @@ self =>
// ----------- Overriding hooks in nsc.Global -----------------------
/** Called from typechecker, which signal hereby that a node has been completely typechecked.
- * If the node is included in unit.targetPos, abandons run and returns newly attributed tree.
+ * If the node includes unit.targetPos, abandons run and returns newly attributed tree.
* Otherwise, if there's some higher priority work to be done, also abandons run with a FreshRunReq.
* @param context The context that typechecked the node
* @param old The original node
@@ -75,7 +75,7 @@ self =>
result.pos.isOpaqueRange &&
(result.pos includes context.unit.targetPos)) {
integrateNew()
- var located = new Locator(context.unit.targetPos) locateIn result
+ var located = new TypedLocator(context.unit.targetPos) locateIn result
if (located == EmptyTree) {
println("something's wrong: no "+context.unit+" in "+result+result.pos)
located = result
@@ -270,6 +270,7 @@ self =>
unit.toCheck.clear()
unit.targetPos = NoPosition
unit.contexts.clear()
+ unit.lastBody = unit.body
unit.body = EmptyTree
unit.status = NotLoaded
}
@@ -394,6 +395,16 @@ self =>
respond(response)(typedTree(source, forceReload))
}
+ /** Set sync var `result` to the last fully attributed tree produced from the entire compilation unit */
+ def getLastTypedTree(source : SourceFile, result: Response[Tree]) {
+ respond(result) {
+ val unit = unitOf(source)
+ if (unit.status > JustParsed) unit.body
+ else if (unit.lastBody ne EmptyTree) unit.lastBody
+ else typedTree(source, false)
+ }
+ }
+
def stabilizedType(tree: Tree): Type = tree match {
case Ident(_) if tree.symbol.isStable => singleType(NoPrefix, tree.symbol)
case Select(qual, _) if qual.tpe != null && tree.symbol.isStable => singleType(qual.tpe, tree.symbol)
@@ -427,7 +438,6 @@ self =>
if (!sym.name.decode.containsName(Dollar) &&
!sym.hasFlag(Flags.SYNTHETIC) &&
!locals.contains(sym.name)) {
- //println("adding scope member: "+pre+" "+sym)
locals(sym.name) = new ScopeMember(
sym,
pre.memberType(sym),
@@ -484,7 +494,7 @@ self =>
if (tree.tpe == null)
tree = analyzer.newTyper(context).typedQualifier(tree)
- println("typeMembers at "+tree+" "+tree.tpe)
+ if (debugIDE) println("typeMembers at "+tree+" "+tree.tpe)
val superAccess = tree.isInstanceOf[Super]
val scope = new Scope
@@ -561,6 +571,7 @@ self =>
override def canRedefine(sym: Symbol) = true
def typeCheck(unit: CompilationUnit): Unit = {
+ activeLocks = 0
applyPhase(typerPhase, unit)
}
@@ -572,18 +583,20 @@ self =>
* (i.e. largest tree that's contained by position)
*/
def typedTreeAt(pos: Position): Tree = {
- println("starting typedTreeAt")
+ if (debugIDE) println("starting typedTreeAt")
val tree = locateTree(pos)
- println("at pos "+pos+" was found: "+tree+tree.pos.show)
+ if (debugIDE) println("at pos "+pos+" was found: "+tree+tree.pos.show)
if (stabilizedType(tree) ne null) {
- println("already attributed")
+ if (debugIDE) println("already attributed")
tree
} else {
val unit = unitOf(pos)
assert(unit.isParsed)
unit.targetPos = pos
+ val lastPrintTypings = printTypings
try {
println("starting targeted type check")
+ if (debugIDE) printTypings = true
typeCheck(unit)
throw new FatalError("tree not found")
} catch {
@@ -591,6 +604,7 @@ self =>
ex.tree
} finally {
unit.targetPos = NoPosition
+ printTypings = lastPrintTypings
}
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 6ef85b2f59..889f51e7ab 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -253,9 +253,10 @@ self: scala.tools.nsc.Global =>
traverse(root)
this.last
}
+ protected def isEligible(t: Tree) = !t.pos.isTransparent
override def traverse(t: Tree) {
if (t.pos includes pos) {
- if (!t.pos.isTransparent) last = t
+ if (isEligible(t)) last = t
super.traverse(t)
} else if (t.symbol != null) {
for(annot <- t.symbol.annotations if (annot.pos includes pos) && !annot.pos.isTransparent) {
@@ -267,4 +268,8 @@ self: scala.tools.nsc.Global =>
}
}
}
+
+ class TypedLocator(pos: Position) extends Locator(pos) {
+ override protected def isEligible(t: Tree) = super.isEligible(t) && t.tpe != null
+ }
}
diff --git a/src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala b/src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala
index 40f9209c1b..83d2270eb7 100644
--- a/src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala
@@ -40,5 +40,8 @@ trait RichCompilationUnits { self: Global =>
def targetPos_=(p: Position) { _targetPos = p }
var contexts: Contexts = new Contexts
+
+ /** The last fully type-checked body of this unit */
+ var lastBody: Tree = EmptyTree
}
}