summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-01-24 16:40:32 +0000
committerMartin Odersky <odersky@gmail.com>2011-01-24 16:40:32 +0000
commit6300d5e277ed7241f83b2286efe2307b0392484e (patch)
treebb7a06cff620b22319311f8e265cf6131bc21479 /src
parent19b45e964354069137266b101ca06d8541d5d1c3 (diff)
downloadscala-6300d5e277ed7241f83b2286efe2307b0392484e.tar.gz
scala-6300d5e277ed7241f83b2286efe2307b0392484e.tar.bz2
scala-6300d5e277ed7241f83b2286efe2307b0392484e.zip
Better behavior on completions.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala17
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala39
-rw-r--r--src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala2
3 files changed, 38 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 3171df2fdc..a0104c2395 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -53,11 +53,11 @@ trait CompilerControl { self: Global =>
* if it does not yet exist create a new one atomically
* Note: We want to get roid of this operation as it messes compiler invariants.
*/
- @deprecated("use getUnitOf(s) instead")
+ @deprecated("use getUnitOf(s) or onUnitOf(s) instead")
def unitOf(s: SourceFile): RichCompilationUnit = getOrCreateUnitOf(s)
/** The compilation unit corresponding to a position */
- @deprecated("use getUnitOf(pos.source) instead")
+ @deprecated("use getUnitOf(pos.source) or onUnitOf(pos.source) instead")
def unitOf(pos: Position): RichCompilationUnit = getOrCreateUnitOf(pos.source)
/** Removes the CompilationUnit corresponding to the given SourceFile
@@ -75,14 +75,14 @@ trait CompilerControl { self: Global =>
}
/** Locate smallest tree that encloses position
+ * @pre Position must be loaded
*/
- def locateTree(pos: Position): Tree =
- new Locator(pos) locateIn unitOf(pos).body
+ def locateTree(pos: Position): Tree = onUnitOf(pos.source) { unit => new Locator(pos) locateIn unit.body }
/** Locates smallest context that encloses position as an optional value.
*/
def locateContext(pos: Position): Option[Context] =
- locateContext(unitOf(pos).contexts, pos)
+ for (unit <- getUnit(pos.source); cx <- locateContext(unit.contexts, pos)) yield cx
/** Returns the smallest context that contains given `pos`, throws FatalError if none exists.
*/
@@ -113,8 +113,13 @@ trait CompilerControl { self: Global =>
/** Sets sync var `response` to the fully attributed & typechecked tree contained in `source`.
* @pre `source` needs to be loaded.
*/
- def askType(source: SourceFile, forceReload: Boolean, response: Response[Tree]) =
+ def askType(source: SourceFile, forceReload: Boolean, response: Response[Tree]) = {
+ if (debugIDE) {
+ println("ask type called")
+ new Exception().printStackTrace()
+ }
scheduler postWorkItem new AskTypeItem(source, forceReload, response)
+ }
/** Sets sync var `response` to the position of the definition of the given link in
* the given sourcefile.
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 4c67f20b01..f41e543ea4 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -42,6 +42,7 @@ self =>
import log.logreplay
debugLog("interactive compiler from 23 Jan")
debugLog("logger: " + log.getClass + " writing to " + (new java.io.File(logName)).getAbsolutePath)
+ debugLog("classpath: "+classPath)
/** Print msg only when debugIDE is true. */
@inline final def debugLog(msg: => String) =
@@ -64,19 +65,22 @@ self =>
* if it does not yet exist create a new one atomically
* Note: We want to rmeove this.
*/
- protected[interactive] def getOrCreateUnitOf(s: SourceFile): RichCompilationUnit =
+ protected[interactive] def getOrCreateUnitOf(source: SourceFile): RichCompilationUnit =
unitOfFile.synchronized {
- unitOfFile get s.file match {
+ unitOfFile get source.file match {
case Some(unit) =>
unit
case None =>
- println("*** precondition violated: executing operation on non-loaded file " + s)
- val unit = new RichCompilationUnit(s)
- unitOfFile(s.file) = unit
+ println("*** precondition violated: executing operation on non-loaded file " + source)
+ val unit = new RichCompilationUnit(source)
+ unitOfFile(source.file) = unit
unit
}
}
+ protected [interactive] def onUnitOf[T](source: SourceFile)(op: RichCompilationUnit => T): T =
+ op(unitOfFile.getOrElse(source.file, new RichCompilationUnit(source)))
+
/** Work through toBeRemoved list to remove any units.
* Then return optionlly unit associated with given source.
*/
@@ -91,7 +95,6 @@ self =>
unitOfFile get s.file
}
-
/** A list giving all files to be typechecked in the order they should be checked.
*/
var allSources: List[SourceFile] = List()
@@ -450,7 +453,7 @@ self =>
/** A fully attributed tree located at position `pos` */
def typedTreeAt(pos: Position): Tree = {
- debugLog("typedTreeAt " + pos)
+ informIDE("typedTreeAt " + pos)
val tree = locateTree(pos)
debugLog("at pos "+pos+" was found: "+tree+tree.pos.show)
if (stabilizedType(tree) ne null) {
@@ -475,7 +478,7 @@ self =>
/** A fully attributed tree corresponding to the entire compilation unit */
def typedTree(source: SourceFile, forceReload: Boolean): Tree = {
- informIDE("typedTree" + source + " forceReload: " + forceReload)
+ informIDE("typedTree " + source + " forceReload: " + forceReload)
val unit = getOrCreateUnitOf(source)
if (forceReload) reset(unit)
if (unit.status <= PartiallyChecked) {
@@ -487,7 +490,6 @@ self =>
/** Set sync var `response` to a fully attributed tree located at position `pos` */
def getTypedTreeAt(pos: Position, response: Response[Tree]) {
- informIDE("getTypedTreeAt" + pos)
respond(response)(typedTreeAt(pos))
}
@@ -502,7 +504,7 @@ self =>
def getLastTypedTree(source: SourceFile, response: Response[Tree]) {
informIDE("getLastTyped" + source)
respond(response) {
- val unit = unitOf(source)
+ val unit = getOrCreateUnitOf(source)
if (unit.status > PartiallyChecked) unit.body
else if (unit.lastBody ne EmptyTree) unit.lastBody
else typedTree(source, false)
@@ -520,7 +522,7 @@ self =>
val newsym = pre.decl(sym.name) filter { alt =>
sym.isType || {
try {
- val tp1 = pre.memberType(alt)
+ val tp1 = pre.memberType(alt) onTypeError NoType
val tp2 = adaptToNewRunMap(sym.tpe)
matchesType(tp1, tp2, false)
} catch {
@@ -587,7 +589,7 @@ self =>
!locals.contains(sym.name)) {
locals(sym.name) = new ScopeMember(
sym,
- pre.memberType(sym),
+ pre.memberType(sym) onTypeError ErrorType,
context.isAccessible(sym, pre, false),
viaImport)
}
@@ -643,7 +645,7 @@ self =>
val members = new LinkedHashMap[Symbol, TypeMember]
def addTypeMember(sym: Symbol, pre: Type, inherited: Boolean, viaView: Symbol) {
- val symtpe = pre.memberType(sym)
+ val symtpe = pre.memberType(sym) onTypeError ErrorType
if (scope.lookupAll(sym.name) forall (sym => !(members(sym).tpe matches symtpe))) {
scope enter sym
members(sym) = new TypeMember(
@@ -746,6 +748,17 @@ self =>
class TyperResult(val tree: Tree) extends ControlThrowable
assert(globalPhase.id == 0)
+
+ implicit def addOnTypeError[T](x: => T): OnTypeError[T] = new OnTypeError(x)
+
+ class OnTypeError[T](op: => T) {
+ def onTypeError(alt: => T) = try {
+ op
+ } catch {
+ case ex: TypeError => alt
+ }
+ }
}
object CancelException extends Exception
+
diff --git a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
index 998b855111..fc67a260c4 100644
--- a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
@@ -90,7 +90,7 @@ abstract class BrowsingLoaders extends SymbolLoaders {
// System.out.println("Browsing "+src)
val source = new BatchSourceFile(src)
val body = new OutlineParser(source).parse()
- System.out.println(body)
+// System.out.println(body)
val browser = new BrowserTraverser
browser.traverse(body)
if (browser.entered == 0)