summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-05-28 17:20:39 +0000
committerMartin Odersky <odersky@gmail.com>2009-05-28 17:20:39 +0000
commit9b2430c7766882b55994fda01bc59130e256d022 (patch)
tree4310b80e1542e5a4577c8798c6ce8fb9cc5b55ee /src/compiler
parent7fc525184be32f405fc027675667c8e8bfa14679 (diff)
downloadscala-9b2430c7766882b55994fda01bc59130e256d022.tar.gz
scala-9b2430c7766882b55994fda01bc59130e256d022.tar.bz2
scala-9b2430c7766882b55994fda01bc59130e256d022.zip
more work on the interactive mode.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala18
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala5
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/Global.scala48
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/Positions.scala51
-rw-r--r--src/compiler/scala/tools/nsc/interactive/REPL.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala1
8 files changed, 78 insertions, 54 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index ecf2bc521c..269c1f4e2d 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -319,6 +319,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this
} with Analyzer
+ /** Switch to turn on detailed type logs */
+ var printTypings = false
+
// phaseName = "superaccessors"
object superAccessors extends {
val global: Global.this.type = Global.this
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 9e9b801d25..b4b207b05e 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -336,15 +336,15 @@ abstract class TreePrinters {
case Literal(x) =>
print(x.escapedStringValue)
- case TypeTree() =>
- print(
- if (tree.tpe eq null)
- "<type ?>"
- else if ((tree.tpe.typeSymbol ne null) && tree.tpe.typeSymbol.isAnonymousClass)
- tree.tpe.typeSymbol.toString()
- else
- tree.tpe.toString()
- )
+ case tt: TypeTree =>
+ if (tree.tpe eq null) {
+ if (tt.original != null) { print("<type: "); print(tt.original); print(">") }
+ else print("<type ?>")
+ } else if ((tree.tpe.typeSymbol ne null) && tree.tpe.typeSymbol.isAnonymousClass) {
+ print(tree.tpe.typeSymbol.toString())
+ } else {
+ tree.tpe.toString()
+ }
case Annotated(Annotation(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), elements), tree) =>
def printAnnot() {
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index ae6003a056..f57eed60b8 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -159,9 +159,12 @@ trait Trees {
/** Is there part of this tree which satisfies predicate `p'? */
def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty
- /** The direct children of this tree */
+ /** The direct child trees of this tree
+ * EmptyTrees are always omitted. Lists are collapsed.
+ */
def children(): List[Tree] = {
def subtrees(x: Any): List[Tree] = x match {
+ case EmptyTree => List()
case t: Tree => List(t)
case xs: List[_] => xs flatMap subtrees
case _ => List()
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index fb448aafc0..4d72f9ae07 100755
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -145,6 +145,7 @@ self =>
*/
private def backgroundCompile() {
inform("Starting new presentation compiler type checking pass")
+ reporter.reset
firsts = firsts filter (s => unitOfFile contains (s.file))
val prefix = firsts map unitOf
val units = prefix ::: (unitOfFile.values.toList diff prefix)
@@ -161,16 +162,23 @@ self =>
unit.toCheck.clear()
unit.targetPos = NoPosition
unit.contexts.clear()
- ResetAttrs.traverse(unit.body)
- currentTyperRun.enterNames(unit)
- unit.status = JustParsed
+ unit.body = EmptyTree
+ unit.status = NotLoaded
}
+ /** Parse unit and create a name index. */
+ def parse(unit: RichCompilationUnit): Unit = {
+ currentTyperRun.compileLate(unit)
+ validatePositions(unit.body)
+ unit.status = JustParsed
+ }
+
/** Make sure symbol and type attributes are reset and recompile unit.
*/
def recompile(unit: RichCompilationUnit) {
- assert(unit.status != NotLoaded)
reset(unit)
+ inform("parsing: "+unit)
+ parse(unit)
inform("type checking: "+unit)
currentTyperRun.typeCheck(unit)
unit.status = currentRunId
@@ -190,9 +198,7 @@ self =>
for (source <- sources) {
val unit = new RichCompilationUnit(source)
unitOfFile(source.file) = unit
- currentTyperRun.compileLate(unit)
- validatePositions(unit.body)
- unit.status = JustParsed
+ parse(unit)
}
moveToFront(sources)
result set Left(())
@@ -208,10 +214,13 @@ self =>
/** Set sync var `result` to a fully attributed tree located at position `pos` */
def typedTreeAt(pos: Position, result: SyncVar[Either[Tree, Throwable]]) {
try {
+ println("typed tree at "+pos.show)
val unit = unitOf(pos)
assert(unit.status != NotLoaded)
moveToFront(List(unit.source))
- result set Left(currentTyperRun.typedTreeAt(pos))
+ val typedTree = currentTyperRun.typedTreeAt(pos)
+ val located = new Locator(pos) locateIn typedTree
+ result set Left(located)
} catch {
case ex =>
result set Right(ex)
@@ -233,15 +242,18 @@ self =>
}
/** A traverser that resets all type and symbol attributes in a tree */
- object ResetAttrs extends Traverser {
- override def traverse(t: Tree) {
+ object ResetAttrs extends Transformer {
+ override def transform(t: Tree): Tree = {
if (t.hasSymbol) t.symbol = NoSymbol
t match {
case EmptyTree =>
- ;
+ t
+ case tt: TypeTree =>
+ if (tt.original != null) tt.original
+ else t
case _ =>
t.tpe = null
- super.traverse(t)
+ super.transform(t)
}
}
}
@@ -252,13 +264,9 @@ self =>
// symSource, symData are ignored
override def compiles(sym: Symbol) = false
- def typeCheck(unit: CompilationUnit) {
- applyPhase(typerPhase, unit)
- }
+ def typeCheck(unit: CompilationUnit): Unit = applyPhase(typerPhase, unit)
- def enterNames(unit: CompilationUnit) {
- applyPhase(namerPhase, unit)
- }
+ def enterNames(unit: CompilationUnit): Unit = applyPhase(namerPhase, unit)
/** Return fully attributed tree at given position
* (i.e. largest tree that's contained by position)
@@ -280,7 +288,9 @@ self =>
}
}
- /** Apply a phase to a compilation unit */
+ /** Apply a phase to a compilation unit
+ * @return true iff typechecked correctly
+ */
private def applyPhase(phase: Phase, unit: CompilationUnit) {
val oldSource = reporter.getSource
try {
diff --git a/src/compiler/scala/tools/nsc/interactive/Positions.scala b/src/compiler/scala/tools/nsc/interactive/Positions.scala
index ce4de1d311..f30fc83a2b 100755
--- a/src/compiler/scala/tools/nsc/interactive/Positions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Positions.scala
@@ -24,7 +24,7 @@ import scala.collection.mutable.ListBuffer
trait Positions extends Trees {
self: Global =>
- private case class Range(val pos: Position, val tree: Tree) {
+ case class Range(val pos: Position, val tree: Tree) {
def isFree = tree == EmptyTree
}
@@ -83,22 +83,26 @@ self: Global =>
* @param ranges The current list of non-overlapping ranges,
* both occupied and free, sorted from later to earlier.
* No TransparentPositions allowed here!
- * @param cts The list of trees to insert in ranges.
+ * @param trees The list of trees to insert in ranges.
*/
- def iterate(ranges: List[Range], cts: List[Tree]): Unit = cts match {
+ def iterate(ranges: List[Range], trees: List[Tree]): Unit = trees match {
case List() =>
;
- case ct :: cts1 =>
- val conflicting = new ListBuffer[Tree]
- val ranges1 = insert(ranges, ct, conflicting)
- if (conflicting.isEmpty) {
- iterate(ranges1, cts1)
- } else {
- val splitNode =
- if (conflicting.size == 1 && (conflicting.head.pos includes ct.pos)) conflicting.head
- else ct
- splitNode setPos new TransparentPosition(splitNode.pos.source.get, splitNode.pos.start, splitNode.pos.point, splitNode.pos.end)
- ensureNonOverlapping(replace(cts, splitNode, solidDescendants(splitNode)))
+ case ct :: trees1 =>
+ if (isTransparent(ct.pos))
+ iterate(ranges, solidDescendants(ct) ::: trees1)
+ else if (ct.pos.isDefined) {
+ val conflicting = new ListBuffer[Tree]
+ val ranges1 = insert(ranges, ct, conflicting)
+ if (conflicting.isEmpty) {
+ iterate(ranges1, trees1)
+ } else {
+ val splitNode =
+ if (conflicting.size == 1 && (conflicting.head.pos includes ct.pos)) conflicting.head
+ else ct
+ splitNode setPos new TransparentPosition(splitNode.pos.source.get, splitNode.pos.start, splitNode.pos.point, splitNode.pos.end)
+ ensureNonOverlapping(replace(cts, splitNode, solidDescendants(splitNode)))
+ }
}
}
@@ -131,15 +135,18 @@ self: Global =>
private def setChildrenPos(pos: Position, trees: List[Tree]) {
var currentPos = pos
for (tree <- trees) {
- val children = tree.children
- if (children.isEmpty)
- tree setPos OffsetPosition(pos.source.get, currentPos.start)
- else {
- setChildrenPos(currentPos, children)
- tree setPos new RangePosition(
- pos.source.get, (children map (_.pos.start)).min, pos.point, (children map (_.pos.end)).max)
+ if (tree != EmptyTree && tree.pos == NoPosition) {
+ val children = tree.children
+ if (children.isEmpty)
+ tree setPos OffsetPosition(pos.source.get, currentPos.start)
+ else {
+ setChildrenPos(currentPos, children)
+ tree setPos new RangePosition(
+ 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)
}
- currentPos = new RangePosition(pos.source.get, tree.pos.end, pos.point, pos.end)
+// println("set children pos "+pos+" of "+trees)
}
ensureNonOverlapping(trees)
}
diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala
index e773f9f281..f63789fc9b 100644
--- a/src/compiler/scala/tools/nsc/interactive/REPL.scala
+++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala
@@ -32,7 +32,9 @@ object REPL {
reporter.info(null, versionMsg, true)
else {
try {
- object compiler extends Global(command.settings, reporter)
+ object compiler extends Global(command.settings, reporter) {
+// printTypings = true
+ }
if (reporter.hasErrors) {
reporter.flush()
return
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c3f0365663..d43d09f79f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -27,8 +27,6 @@ trait Typers { self: Analyzer =>
import global._
import definitions._
- private final val printTypings = false
-
var appcnt = 0
var idcnt = 0
var selcnt = 0
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 1063135b8b..6707bf6243 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -44,6 +44,7 @@ trait Position {
precedes(pos) && start < pos.end
def overlaps(pos: Position) =
+ isDefined && pos.isDefined &&
(pos.start <= start && start < pos.end) || (start <= pos.start && pos.start < end)
def sameRange(pos: Position) =