summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-20 16:03:15 +0000
committerPaul Phillips <paulp@improving.org>2009-06-20 16:03:15 +0000
commit533764a7180c005024e997246a56ee9fce337bb5 (patch)
tree3e19fb5968da8bec0b4ec5541fa88f02ce2f308a /src
parent0e170e4b695adafb3f3d5823026ccf8d10047be3 (diff)
downloadscala-533764a7180c005024e997246a56ee9fce337bb5.tar.gz
scala-533764a7180c005024e997246a56ee9fce337bb5.tar.bz2
scala-533764a7180c005024e997246a56ee9fce337bb5.zip
Exposing more identifiers for tab-completion.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Completion.scala56
2 files changed, 47 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index 1beeeb2529..470dadc7b1 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -159,8 +159,11 @@ class Interpreter(val settings: Settings, out: PrintWriter)
/** the previous requests this interpreter has processed */
private val prevRequests = new ArrayBuffer[Request]()
+ val prevImports = new ListBuffer[Import]()
+
private def allUsedNames = prevRequests.toList.flatMap(_.usedNames).removeDuplicates
private def allBoundNames = prevRequests.toList.flatMap(_.boundNames).removeDuplicates
+ // private def allImportedNames = prevImports.toList.flatMap(_.importedNames).removeDuplicates
/** Generates names pre0, pre1, etc. via calls to apply method */
class NameCreator(pre: String) {
@@ -615,6 +618,9 @@ class Interpreter(val settings: Settings, out: PrintWriter)
}
yield name
+ // record the import
+ prevImports += imp
+
override def resultExtractionCode(req: Request, code: PrintWriter) =
code println codegenln(imp.toString)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/Completion.scala b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
index bbda31e2e8..2239f7cc3a 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Completion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
@@ -32,19 +32,29 @@ class Completion(val interpreter: Interpreter) extends Completor {
import java.util.{ List => JList }
import interpreter.compilerClasspath
- // it takes a little while to look through the jars so we use a future and a concurrent map
- val dottedPaths = new ConcurrentHashMap[String, List[String]]
-
- private var doneExaminingJars = false
- scala.concurrent.ops.future {
- getDottedPaths(dottedPaths, interpreter)
- doneExaminingJars = true
+ // This is a wrapper which lets us use a def until some lengthy
+ // action is complete, and then a val from that point on.
+ class LazyValFuture[T](f: () => T, body: => Unit) {
+ private[this] var isDone = false
+ private[this] lazy val complete = f()
+ def apply(): T = if (isDone) complete else f()
+
+ scala.concurrent.ops.future {
+ body
+ isDone = true
+ }
}
- // Would like to find a nicer way to do this, but this works for now
- lazy val topLevelPackagesVal = topLevelPackagesDef
- def topLevelPackagesDef() = enumToList(dottedPaths.keys) filter (x => !x.contains('.'))
- def topLevelPackages = if (doneExaminingJars) topLevelPackagesVal else topLevelPackagesDef
+ // it takes a little while to look through the jars so we use a future and a concurrent map
+ class CompletionAgent {
+ val dottedPaths = new ConcurrentHashMap[String, List[String]]
+ val topLevelPackages = new LazyValFuture(
+ () => enumToList(dottedPaths.keys) filterNot (_ contains '.'),
+ getDottedPaths(dottedPaths, interpreter)
+ )
+ }
+ val agent = new CompletionAgent
+ import agent._
// One instance of a command line
class Buffer(s: String) {
@@ -110,8 +120,19 @@ class Completion(val interpreter: Interpreter) extends Completor {
def isValidPath(s: String) = dottedPaths containsKey s
def membersOfPath(s: String) = if (isValidPath(s)) dottedPaths get s else Nil
- def pkgsStartingWith(s: String) = topLevelPackages filter (_ startsWith s)
- def idsStartingWith(s: String) = interpreter.unqualifiedIds filter (_ startsWith s)
+ // XXX generalize this to look through imports
+ def membersOfScala() = membersOfPath("scala")
+ def membersOfJavaLang() = membersOfPath("java.lang")
+ def membersOfPredef() = membersOfId("scala.Predef")
+ def defaultMembers = {
+ val xs = membersOfScala ::: membersOfJavaLang ::: membersOfPredef
+ val excludes = List("""Tuple\d+""".r, """Product\d+""".r, """Function\d+""".r,
+ """.*Exception$""".r, """.*Error$""".r)
+ xs filter (x => excludes forall (r => r.findFirstMatchIn(x).isEmpty))
+ }
+
+ def pkgsStartingWith(s: String) = topLevelPackages() filter (_ startsWith s)
+ def idsStartingWith(s: String) = (interpreter.unqualifiedIds ::: defaultMembers) filter (_ startsWith s)
def complete(clist: JList[String]): Int = {
val res = analyzeBuffer(clist)
@@ -136,10 +157,15 @@ class Completion(val interpreter: Interpreter) extends Completor {
map (_.getName) .
filter (isValidCompletion)
+ def getClassObject(path: String): Option[Class[_]] =
+ (interpreter getClassObject path) orElse
+ (interpreter getClassObject ("scala." + path)) orElse
+ (interpreter getClassObject ("java.lang." + path))
+
// java style, static methods
- val js = (interpreter getClassObject path).map(getMembers(_, true)) getOrElse Nil
+ val js = getClassObject(path) map (getMembers(_, true)) getOrElse Nil
// scala style, methods on companion object
- val ss = (interpreter getClassObject (path + "$")).map(getMembers(_, false)) getOrElse Nil
+ val ss = getClassObject(path + "$") map (getMembers(_, false)) getOrElse Nil
js ::: ss
}