summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.number2
-rwxr-xr-xbuild.xml2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala237
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala111
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala270
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala4
-rw-r--r--src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/MutableSettings.scala24
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/Warnings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala41
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala41
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala5
-rw-r--r--src/jline/LICENSE.txt33
-rw-r--r--src/jline/README.md24
-rw-r--r--src/jline/build.sbt49
-rwxr-xr-xsrc/jline/manual-test.sh9
-rw-r--r--src/jline/project/build.properties1
-rw-r--r--src/jline/project/plugins.sbt3
-rw-r--r--src/jline/src/main/java/scala/tools/jline/AnsiWindowsTerminal.java90
-rw-r--r--src/jline/src/main/java/scala/tools/jline/NoInterruptUnixTerminal.java44
-rw-r--r--src/jline/src/main/java/scala/tools/jline/Terminal.java59
-rw-r--r--src/jline/src/main/java/scala/tools/jline/TerminalFactory.java173
-rw-r--r--src/jline/src/main/java/scala/tools/jline/TerminalSupport.java179
-rw-r--r--src/jline/src/main/java/scala/tools/jline/UnixTerminal.java248
-rw-r--r--src/jline/src/main/java/scala/tools/jline/UnsupportedTerminal.java25
-rw-r--r--src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java468
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java2185
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/CursorBuffer.java106
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/Key.java82
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/Operation.java291
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/AggregateCompleter.java108
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/ArgumentCompleter.java398
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/CandidateListCompletionHandler.java193
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/Completer.java37
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/CompletionHandler.java25
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/EnumCompleter.java35
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/FileNameCompleter.java133
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/NullCompleter.java39
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/StringsCompleter.java79
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/completer/package-info.java22
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/history/FileHistory.java106
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/history/History.java71
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/history/MemoryHistory.java318
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/history/PersistentHistory.java34
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/history/package-info.java22
-rw-r--r--src/jline/src/main/java/scala/tools/jline/console/package-info.java22
-rw-r--r--src/jline/src/main/java/scala/tools/jline/internal/Configuration.java127
-rw-r--r--src/jline/src/main/java/scala/tools/jline/internal/Log.java112
-rw-r--r--src/jline/src/main/java/scala/tools/jline/internal/ReplayPrefixOneCharInputStream.java95
-rw-r--r--src/jline/src/main/java/scala/tools/jline/internal/TerminalLineSettings.java217
-rw-r--r--src/jline/src/main/java/scala/tools/jline/internal/package-info.java22
-rw-r--r--src/jline/src/main/java/scala/tools/jline/package-info.java22
-rw-r--r--src/jline/src/main/resources/scala/tools/jline/console/completer/CandidateListCompletionHandler.properties4
-rw-r--r--src/jline/src/main/resources/scala/tools/jline/keybindings.properties71
-rw-r--r--src/jline/src/main/resources/scala/tools/jline/windowsbindings.properties71
-rw-r--r--src/jline/src/test/java/scala/tools/jline/TerminalFactoryTest.java34
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTest.java261
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTestSupport.java143
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/EditLineTest.java208
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/completer/ArgumentCompleterTest.java46
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/completer/NullCompleterTest.java39
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/completer/StringsCompleterTest.java40
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/history/HistoryTest.java79
-rw-r--r--src/jline/src/test/java/scala/tools/jline/console/history/MemoryHistoryTest.java99
-rw-r--r--src/jline/src/test/java/scala/tools/jline/example/Example.java107
-rw-r--r--src/jline/src/test/java/scala/tools/jline/internal/TerminalLineSettingsTest.java146
-rw-r--r--src/library/scala/StringContext.scala4
-rw-r--r--src/library/scala/collection/immutable/Range.scala19
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala101
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala7
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala11
-rw-r--r--src/reflect/scala/reflect/runtime/SymbolLoaders.scala11
-rw-r--r--test/files/jvm/varargs.check3
-rw-r--r--test/files/jvm/varargs/JavaClass.java1
-rw-r--r--test/files/jvm/varargs/VaClass.scala2
-rw-r--r--test/files/neg/t5148.check9
-rw-r--r--test/files/neg/t8736-c.check11
-rw-r--r--test/files/neg/t8736-c.flags1
-rw-r--r--test/files/neg/t8736-c.scala7
-rw-r--r--test/files/pos/t8736-b.flags1
-rw-r--r--test/files/pos/t8736-b.scala7
-rw-r--r--test/files/pos/t8736.flags1
-rw-r--r--test/files/pos/t8736.scala7
-rw-r--r--test/files/pos/t8743.scala15
-rw-r--r--test/files/pos/t8781/Macro_1.scala13
-rw-r--r--test/files/pos/t8781/Test_2.flags1
-rw-r--r--test/files/pos/t8781/Test_2.scala5
-rw-r--r--test/files/run/private-override.check1
-rw-r--r--test/files/run/t6440.check9
-rw-r--r--test/files/run/t6440b.check9
-rw-r--r--test/files/run/t8738.scala16
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_lookup.scala4
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala4
-rw-r--r--versions.properties12
104 files changed, 654 insertions, 8066 deletions
diff --git a/build.number b/build.number
index 4a0898529e..21ce660958 100644
--- a/build.number
+++ b/build.number
@@ -1,7 +1,7 @@
#Tue Sep 11 19:21:09 CEST 2007
version.major=2
version.minor=11
-version.patch=2
+version.patch=3
# This is the -N part of a version. if it's 0, it's dropped from maven versions.
version.bnum=0
diff --git a/build.xml b/build.xml
index a89e694ac2..b7950f971c 100755
--- a/build.xml
+++ b/build.xml
@@ -558,6 +558,7 @@ TODO:
<echo message="scala-swing.version.number = ${scala-swing.version.number}"/>
<echo message="akka-actor.version.number = ${akka-actor.version.number}"/>
<echo message="actors-migration.version.number = ${actors-migration.version.number}"/>
+ <echo message="jline.version = ${jline.version}"/>
<echo message="partest.version.number = ${partest.version.number}"/>
<echo message="scalacheck.version.number = ${scalacheck.version.number}"/>
@@ -572,6 +573,7 @@ TODO:
<entry key="scala-swing.version.number" value="${scala-swing.version.number}"/>
<entry key="akka-actor.version.number" value="${akka-actor.version.number}"/>
<entry key="actors-migration.version.number" value="${actors-migration.version.number}"/>
+ <entry key="jline.version" value="${jline.version}"/>
<entry key="partest.version.number" value="${partest.version.number}"/>
<entry key="scalacheck.version.number" value="${scalacheck.version.number}"/>
</propertyfile>
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 572e579aca..5bf0d8d9f7 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -831,198 +831,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
} reverse
}
- // ------------ Invalidations ---------------------------------
-
- /** Is given package class a system package class that cannot be invalidated?
- */
- private def isSystemPackageClass(pkg: Symbol) =
- pkg == RootClass ||
- pkg == definitions.ScalaPackageClass || {
- val pkgname = pkg.fullName
- (pkgname startsWith "scala.") && !(pkgname startsWith "scala.tools")
- }
-
- /** Invalidates packages that contain classes defined in a classpath entry, and
- * rescans that entry.
- * @param paths Fully qualified names that refer to directories or jar files that are
- * a entries on the classpath.
- * First, causes the classpath entry referred to by `path` to be rescanned, so that
- * any new files or deleted files or changes in subpackages are picked up.
- * Second, invalidates any packages for which one of the following considitions is met:
-
- * - the classpath entry contained during the last compilation run classfiles
- * that represent a member in the package
- * - the classpath entry now contains classfiles
- * that represent a member in the package
- * - the set of subpackages has changed.
- *
- * The invalidated packages are reset in their entirety; all member classes and member packages
- * are re-accessed using the new classpath.
- * Not invalidated are system packages that the compiler needs to access as parts
- * of standard definitions. The criterion what is a system package is currently:
- * any package rooted in "scala", with the exception of packages rooted in "scala.tools".
- * This can be refined later.
- * @return A pair consisting of
- * - a list of invalidated packages
- * - a list of of packages that should have been invalidated but were not because
- * they are system packages.
- */
- def invalidateClassPathEntries(paths: String*): (List[ClassSymbol], List[ClassSymbol]) = {
- val invalidated, failed = new mutable.ListBuffer[ClassSymbol]
- classPath match {
- case cp: MergedClassPath[_] =>
- def assoc(path: String): List[(PlatformClassPath, PlatformClassPath)] = {
- val dir = AbstractFile getDirectory path
- val canonical = dir.canonicalPath
- def matchesCanonical(e: ClassPath[_]) = e.origin match {
- case Some(opath) =>
- (AbstractFile getDirectory opath).canonicalPath == canonical
- case None =>
- false
- }
- cp.entries find matchesCanonical match {
- case Some(oldEntry) =>
- List(oldEntry -> cp.context.newClassPath(dir))
- case None =>
- println(s"canonical = $canonical, origins = ${cp.entries map (_.origin)}")
- error(s"cannot invalidate: no entry named $path in classpath $classPath")
- List()
- }
- }
- val subst = Map(paths flatMap assoc: _*)
- if (subst.nonEmpty) {
- platform updateClassPath subst
- informProgress(s"classpath updated on entries [${subst.keys mkString ","}]")
- def mkClassPath(elems: Iterable[PlatformClassPath]): PlatformClassPath =
- if (elems.size == 1) elems.head
- else new MergedClassPath(elems, classPath.context)
- val oldEntries = mkClassPath(subst.keys)
- val newEntries = mkClassPath(subst.values)
- reSync(RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed)
- }
- }
- def show(msg: String, syms: scala.collection.Traversable[Symbol]) =
- if (syms.nonEmpty)
- informProgress(s"$msg: ${syms map (_.fullName) mkString ","}")
- show("invalidated packages", invalidated)
- show("could not invalidate system packages", failed)
- (invalidated.toList, failed.toList)
- }
-
- /** Re-syncs symbol table with classpath
- * @param root The root symbol to be resynced (a package class)
- * @param allEntries Optionally, the corresponding package in the complete current classPath
- * @param oldEntries Optionally, the corresponding package in the old classPath entries
- * @param newEntries Optionally, the corresponding package in the new classPath entries
- * @param invalidated A listbuffer collecting the invalidated package classes
- * @param failed A listbuffer collecting system package classes which could not be invalidated
- * The resyncing strategy is determined by the absence or presence of classes and packages.
- * If either oldEntries or newEntries contains classes, root is invalidated, provided a corresponding package
- * exists in allEntries, or otherwise is removed.
- * Otherwise, the action is determined by the following matrix, with columns:
- *
- * old new all sym action
- * + + + + recurse into all child packages of old ++ new
- * + - + + invalidate root
- * + - - + remove root from its scope
- * - + + + invalidate root
- * - + + - create and enter root
- * - - * * no action
- *
- * Here, old, new, all mean classpaths and sym means symboltable. + is presence of an
- * entry in its column, - is absence, * is don't care.
- *
- * Note that new <= all and old <= sym, so the matrix above covers all possibilities.
- */
- private def reSync(root: ClassSymbol,
- allEntries: OptClassPath, oldEntries: OptClassPath, newEntries: OptClassPath,
- invalidated: mutable.ListBuffer[ClassSymbol], failed: mutable.ListBuffer[ClassSymbol]) {
- ifDebug(informProgress(s"syncing $root, $oldEntries -> $newEntries"))
-
- val getName: ClassPath[AbstractFile] => String = (_.name)
- def hasClasses(cp: OptClassPath) = cp.isDefined && cp.get.classes.nonEmpty
- def invalidateOrRemove(root: ClassSymbol) = {
- allEntries match {
- case Some(cp) => root setInfo new loaders.PackageLoader(cp)
- case None => root.owner.info.decls unlink root.sourceModule
- }
- invalidated += root
- }
- def packageNames(cp: PlatformClassPath): Set[String] = cp.packages.toSet map getName
- def subPackage(cp: PlatformClassPath, name: String): OptClassPath =
- cp.packages find (cp1 => getName(cp1) == name)
-
- val classesFound = hasClasses(oldEntries) || hasClasses(newEntries)
- if (classesFound && !isSystemPackageClass(root)) {
- invalidateOrRemove(root)
- } else {
- if (classesFound) {
- if (root.isRoot) invalidateOrRemove(EmptyPackageClass)
- else failed += root
- }
- (oldEntries, newEntries) match {
- case (Some(oldcp) , Some(newcp)) =>
- for (pstr <- packageNames(oldcp) ++ packageNames(newcp)) {
- val pname = newTermName(pstr)
- val pkg = (root.info decl pname) orElse {
- // package was created by external agent, create symbol to track it
- assert(!subPackage(oldcp, pstr).isDefined)
- loaders.enterPackage(root, pstr, new loaders.PackageLoader(allEntries.get))
- }
- reSync(
- pkg.moduleClass.asInstanceOf[ClassSymbol],
- subPackage(allEntries.get, pstr), subPackage(oldcp, pstr), subPackage(newcp, pstr),
- invalidated, failed)
- }
- case (Some(oldcp), None) =>
- invalidateOrRemove(root)
- case (None, Some(newcp)) =>
- invalidateOrRemove(root)
- case (None, None) =>
- }
- }
- }
-
- /** Invalidate contents of setting -Yinvalidate */
- def doInvalidation() = settings.Yinvalidate.value match {
- case "" =>
- case entry => invalidateClassPathEntries(entry)
- }
-
// ----------- Runs ---------------------------------------
private var curRun: Run = null
private var curRunId = 0
- /** A hook that lets subclasses of `Global` define whether a package or class should be kept loaded for the
- * next compiler run. If the parameter `sym` is a class or object, and `clearOnNextRun(sym)` returns `true`,
- * then the symbol is unloaded and reset to its state before the last compiler run. If the parameter `sym` is
- * a package, and clearOnNextRun(sym)` returns `true`, the package is recursively searched for
- * classes to drop.
- *
- * Example: Let's say I want a compiler that drops all classes corresponding to the current project
- * between runs. Then `keepForNextRun` of a toplevel class or object should return `true` if the
- * class or object does not form part of the current project, `false` otherwise. For a package,
- * clearOnNextRun should return `true` if no class in that package forms part of the current project,
- * `false` otherwise.
- *
- * @param sym A class symbol, object symbol, package, or package class.
- */
- @deprecated("use invalidateClassPathEntries instead", "2.10.0")
- def clearOnNextRun(sym: Symbol) = false
- /* To try out clearOnNext run on the scala.tools.nsc project itself
- * replace `false` above with the following code
-
- settings.Xexperimental.value && { sym.isRoot || {
- sym.fullName match {
- case "scala" | "scala.tools" | "scala.tools.nsc" => true
- case _ => sym.owner.fullName.startsWith("scala.tools.nsc")
- }
- }}
-
- * Then, fsc -Xexperimental clears the nsc project between successive runs of `fsc`.
- */
-
object typeDeconstruct extends {
val global: Global.this.type = Global.this
} with typechecker.StructuredTypeStrings
@@ -1292,47 +1105,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
first
}
- /** Reset all classes contained in current project, as determined by
- * the clearOnNextRun hook
- */
- @deprecated("use invalidateClassPathEntries instead", "2.10.0")
- def resetProjectClasses(root: Symbol): Unit = try {
- def unlink(sym: Symbol) =
- if (sym != NoSymbol) root.info.decls.unlink(sym)
- if (settings.verbose) inform("[reset] recursing in "+root)
- val toReload = mutable.Set[String]()
- for (sym <- root.info.decls) {
- if (sym.isInitialized && clearOnNextRun(sym))
- if (sym.hasPackageFlag) {
- resetProjectClasses(sym.moduleClass)
- openPackageModule(sym.moduleClass)
- } else {
- unlink(sym)
- unlink(root.info.decls.lookup(
- if (sym.isTerm) sym.name.toTypeName else sym.name.toTermName))
- toReload += sym.fullName
- // note: toReload could be set twice with the same name
- // but reinit must happen only once per name. That's why
- // the following classPath.findClass { ... } code cannot be moved here.
- }
- }
- for (fullname <- toReload)
- classPath.findClass(fullname) match {
- case Some(classRep) =>
- if (settings.verbose) inform("[reset] reinit "+fullname)
- loaders.initializeFromClassPath(root, classRep)
- case _ =>
- }
- } catch {
- case ex: Throwable =>
- // this handler should not be nessasary, but it seems that `fsc`
- // eats exceptions if they appear here. Need to find out the cause for
- // this and fix it.
- inform("[reset] exception happened: "+ex)
- ex.printStackTrace()
- throw ex
- }
-
// --------------- Miscellania -------------------------------
/** Progress tracking. Measured in "progress units" which are 1 per
@@ -1542,8 +1314,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
compileUnitsInternal(units, fromPhase)
private def compileUnitsInternal(units: List[CompilationUnit], fromPhase: Phase) {
- doInvalidation()
-
units foreach addUnit
val startTime = currentTime
@@ -1619,13 +1389,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// Clear any sets or maps created via perRunCaches.
perRunCaches.clearAll()
-
- // Reset project
- if (!stopPhase("namer")) {
- enteringPhase(namerPhase) {
- resetProjectClasses(RootClass)
- }
- }
}
/** Compile list of abstract files. */
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 4583462b71..2d1030121e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -977,7 +977,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
if (!isModuleInitialized &&
jMethodName == INSTANCE_CONSTRUCTOR_NAME &&
jname == INSTANCE_CONSTRUCTOR_NAME &&
- isStaticModule(siteSymbol)) {
+ isStaticModuleClass(siteSymbol)) {
isModuleInitialized = true
mnode.visitVarInsn(asm.Opcodes.ALOAD, 0)
mnode.visitFieldInsn(
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 31a392ed55..de1587c7c3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -460,6 +460,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
// Can't call .toInterface (at this phase) or we trip an assertion.
// See PackratParser#grow for a method which fails with an apparent mismatch
// between "object PackratParsers$class" and "trait PackratParsers"
+ // TODO @lry do we have a test for that?
if (sym.isImplClass) {
// pos/spec-List.scala is the sole failure if we don't check for NoSymbol
val traitSym = sym.owner.info.decl(tpnme.interfaceName(sym.name))
@@ -469,6 +470,8 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
}
}
+ // TODO @lry: code duplication between here and method asmClassType.
+
assert(hasInternalName(sym), s"Invoked for a symbol lacking JVM internal name: ${sym.fullName}")
assert(!phantomTypeMap.contains(sym), "phantom types not supposed to reach here.")
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
index 9b7c975960..2343d378db 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
@@ -34,6 +34,7 @@ abstract class BCodeIdiomatic extends SubComponent {
case "jvm-1.5" => asm.Opcodes.V1_5
case "jvm-1.6" => asm.Opcodes.V1_6
case "jvm-1.7" => asm.Opcodes.V1_7
+ case "jvm-1.8" => asm.Opcodes.V1_8
}
val majorVersion: Int = (classfileVersion & 0xFF)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
index 8845ffa0cd..0d67a07e0f 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
@@ -95,7 +95,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
claszSymbol = cd.symbol
isCZParcelable = isAndroidParcelableClass(claszSymbol)
- isCZStaticModule = isStaticModule(claszSymbol)
+ isCZStaticModule = isStaticModuleClass(claszSymbol)
isCZRemote = isRemote(claszSymbol)
thisName = internalName(claszSymbol)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
index 62dfb4917d..b373f8d74d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
@@ -21,8 +21,9 @@ abstract class BCodeTypes extends BCodeIdiomatic {
import global._
import bTypes._
- // when compiling the Scala library, some assertions don't hold (e.g., scala.Boolean has null superClass although it's not an interface)
- val isCompilingStdLib = !(settings.sourcepath.isDefault)
+ // Used only for assertions. When compiling the Scala library, some assertions don't hold
+ // (e.g., scala.Boolean has null superClass although it's not an interface)
+ private val isCompilingStdLib = !(settings.sourcepath.isDefault)
// special names
var StringReference : ClassBType = null
@@ -175,12 +176,21 @@ abstract class BCodeTypes extends BCodeIdiomatic {
// ------------------------------------------------
/**
- * TODO @lry should probably be a map form ClassBType to Tracked
+ * Type information for classBTypes.
+ *
+ * TODO rename Tracked
*/
- val exemplars = new java.util.concurrent.ConcurrentHashMap[BType, Tracked]
+ val exemplars = new java.util.concurrent.ConcurrentHashMap[ClassBType, Tracked]
/**
* Maps class symbols to their corresponding `Tracked` instance.
+ *
+ * This map is only used during the first backend phase (Worker1) where ClassDef trees are
+ * transformed into ClassNode asm trees. In this phase, ClassBTypes and their Tracked are created
+ * and added to the `exemplars` map. The `symExemplars` map is only used to know if a symbol has
+ * already been visited.
+ *
+ * TODO move this map to the builder class. it's only used during building. can be gc'd with the builder.
*/
val symExemplars = new java.util.concurrent.ConcurrentHashMap[Symbol, Tracked]
@@ -313,7 +323,7 @@ abstract class BCodeTypes extends BCodeIdiomatic {
final def isDeprecated(sym: Symbol): Boolean = { sym.annotations exists (_ matches definitions.DeprecatedAttr) }
/* must-single-thread */
- final def hasInternalName(sym: Symbol) = { sym.isClass || (sym.isModule && !sym.isMethod) }
+ final def hasInternalName(sym: Symbol) = sym.isClass || sym.isModuleNotMethod
/* must-single-thread */
def getSuperInterfaces(csym: Symbol): List[Symbol] = {
@@ -617,20 +627,52 @@ abstract class BCodeTypes extends BCodeIdiomatic {
false
}
- /*
+ /**
* must-single-thread
+ *
+ * True for module classes of package level objects. The backend will generate a mirror class for
+ * such objects.
*/
- def isTopLevelModule(sym: Symbol): Boolean = {
- exitingPickler { sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass }
+ def isTopLevelModuleClass(sym: Symbol): Boolean = exitingPickler {
+ // phase travel to pickler required for isNestedClass (looks at owner)
+ val r = sym.isModuleClass && !sym.isNestedClass
+ // The mixin phase adds the `lateMODULE` flag to trait implementation classes. Since the flag
+ // is late, it should not be visible here inside the time travel. We check this.
+ if (r) assert(!sym.isImplClass, s"isModuleClass should be false for impl class $sym")
+ r
}
- /*
+ /**
* must-single-thread
+ *
+ * True for module classes of modules that are top-level or owned only by objects. Module classes
+ * for such objects will get a MODULE$ flag and a corresponding static initializer.
*/
- def isStaticModule(sym: Symbol): Boolean = {
- sym.isModuleClass && !sym.isImplClass && !sym.isLifted
+ def isStaticModuleClass(sym: Symbol): Boolean = {
+ /* The implementation of this method is tricky because it is a source-level property. Various
+ * phases changed the symbol's properties in the meantime.
+ *
+ * (1) Phase travel to to pickler is required to exclude implementation classes; they have the
+ * lateMODULEs after mixin, so isModuleClass would be true.
+ *
+ * (2) We cannot use `sym.isStatic` because lambdalift modified (destructively) the owner. For
+ * example, in
+ * object T { def f { object U } }
+ * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here.
+ * So we basically re-implement `sym.isStaticOwner`, but using the original owner chain.
+ */
+
+ def isOriginallyStaticOwner(sym: Symbol): Boolean = {
+ sym.isPackageClass || sym.isModuleClass && isOriginallyStaticOwner(sym.originalOwner)
+ }
+
+ exitingPickler { // (1)
+ sym.isModuleClass &&
+ isOriginallyStaticOwner(sym.originalOwner) // (2)
+ }
}
+
// ---------------------------------------------------------------------
// ---------------- InnerClasses attribute (JVMS 4.7.6) ----------------
// ---------------------------------------------------------------------
@@ -702,6 +744,10 @@ abstract class BCodeTypes extends BCodeIdiomatic {
var x = ics
while (x ne NoSymbol) {
assert(x.isClass, s"not a class symbol: ${x.fullName}")
+ // Uses `rawowner` because `owner` reflects changes in the owner chain due to flattening.
+ // The owner chain of a class only contains classes. This is because the lambdalift phase
+ // changes the `rawowner` destructively to point to the enclosing class. Before, the owner
+ // might be for example a method.
val isInner = !x.rawowner.isPackageClass
if (isInner) {
chain ::= x
@@ -729,7 +775,7 @@ abstract class BCodeTypes extends BCodeIdiomatic {
null
else {
val outerName = innerSym.rawowner.javaBinaryName
- if (isTopLevelModule(innerSym.rawowner)) nme.stripModuleSuffix(outerName)
+ if (isTopLevelModuleClass(innerSym.rawowner)) nme.stripModuleSuffix(outerName)
else outerName
}
}
@@ -741,12 +787,23 @@ abstract class BCodeTypes extends BCodeIdiomatic {
innerSym.rawname + innerSym.moduleSuffix
}
- val flagsWithFinal: Int = mkFlags(
+ // TODO @lry compare with table in spec: for example, deprecated should not be there it seems.
+ // http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1
+ // including "deprecated" was added in the initial commit of GenASM, but it was never in GenJVM.
+ val flags: Int = mkFlags(
+ // TODO @lry adding "static" whenever the class is owned by a module seems wrong.
+ // class C { object O { class I } }
+ // here, I is marked static in the InnerClass attribute. But the I constructor takes an outer instance.
+ // was added in 0469d41
+ // what should it be? check what would make sense for java reflection.
+ // member of top-level object should be static? how about anonymous / local class that has
+ // been lifted to a top-level object?
+ // member that is only nested in objects should be static?
+ // verify: will ICodeReader still work after that? the code was introduced because of icode reader.
if (innerSym.rawowner.hasModuleFlag) asm.Opcodes.ACC_STATIC else 0,
javaFlags(innerSym),
if (isDeprecated(innerSym)) asm.Opcodes.ACC_DEPRECATED else 0 // ASM pseudo-access flag
) & (INNER_CLASSES_FLAGS | asm.Opcodes.ACC_DEPRECATED)
- val flags = if (innerSym.isModuleClass) flagsWithFinal & ~asm.Opcodes.ACC_FINAL else flagsWithFinal // For SI-5676, object overriding.
val jname = innerSym.javaBinaryName.toString // never null
val oname = { // null when method-enclosed
@@ -794,14 +851,23 @@ abstract class BCodeTypes extends BCodeIdiomatic {
* must-single-thread
*/
def javaFlags(sym: Symbol): Int = {
- // constructors of module classes should be private
- // PP: why are they only being marked private at this stage and not earlier?
+ // constructors of module classes should be private. introduced in b06edbc, probably to prevent
+ // creating module instances from java. for nested modules, the constructor needs to be public
+ // since they are created by the outer class and stored in a field. a java client can create
+ // new instances via outerClassInstance.new InnerModuleClass$().
+ // TODO: do this early, mark the symbol private.
val privateFlag =
- sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner))
+ sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModuleClass(sym.owner))
- // Final: the only fields which can receive ACC_FINAL are eager vals.
- // Neither vars nor lazy vals can, because:
+ // Symbols marked in source as `final` have the FINAL flag. (In the past, the flag was also
+ // added to modules and module classes, not anymore since 296b706).
+ // Note that the presence of the `FINAL` flag on a symbol does not correspond 1:1 to emitting
+ // ACC_FINAL in bytecode.
+ //
+ // Top-level modules are marked ACC_FINAL in bytecode (even without the FINAL flag). Nested
+ // objects don't get the flag to allow overriding (under -Yoverride-objects, SI-5676).
//
+ // For fields, only eager val fields can receive ACC_FINAL. vars or lazy vals can't:
// Source: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3
// "Another problem is that the specification allows aggressive
// optimization of final fields. Within a thread, it is permissible to
@@ -818,10 +884,9 @@ abstract class BCodeTypes extends BCodeIdiomatic {
// we can exclude lateFINAL. Such symbols are eligible for inlining, but to
// avoid breaking proxy software which depends on subclassing, we do not
// emit ACC_FINAL.
- // Nested objects won't receive ACC_FINAL in order to allow for their overriding.
val finalFlag = (
- (((sym.rawflags & symtab.Flags.FINAL) != 0) || isTopLevelModule(sym))
+ (((sym.rawflags & symtab.Flags.FINAL) != 0) || isTopLevelModuleClass(sym))
&& !sym.enclClass.isInterface
&& !sym.isClassConstructor
&& !sym.isMutable // lazy vals and vars both
@@ -845,6 +910,10 @@ abstract class BCodeTypes extends BCodeIdiomatic {
if (sym.isVarargsMethod) ACC_VARARGS else 0,
if (sym.hasFlag(symtab.Flags.SYNCHRONIZED)) ACC_SYNCHRONIZED else 0
)
+ // TODO @lry should probably also check / add "deprectated"
+ // all call sites of "javaFlags" seem to check for deprecation rigth after.
+ // Exception: the call below in javaFieldFlags. However, the caller of javaFieldFlags then
+ // does the check.
}
/*
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
index 5b0fa6f7a8..15bc068533 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
@@ -43,9 +43,9 @@ abstract class BTypes[G <: Global](val __global_dont_use: G) {
case FLOAT => "F"
case LONG => "J"
case DOUBLE => "D"
- case c @ ClassBType(_, _) => "L" + c.internalName + ";"
- case ArrayBType(component) => "[" + component
- case MethodBType(args, res) => "(" + args.mkString + ")" + res
+ case ClassBType(internalName) => "L" + internalName + ";"
+ case ArrayBType(component) => "[" + component
+ case MethodBType(args, res) => "(" + args.mkString + ")" + res
}
/**
@@ -160,9 +160,9 @@ abstract class BTypes[G <: Global](val __global_dont_use: G) {
case FLOAT => asm.Type.FLOAT_TYPE
case LONG => asm.Type.LONG_TYPE
case DOUBLE => asm.Type.DOUBLE_TYPE
- case c @ ClassBType(_, _) => asm.Type.getObjectType(c.internalName) // (*)
- case a @ ArrayBType(_) => asm.Type.getObjectType(a.descriptor)
- case m @ MethodBType(_, _) => asm.Type.getMethodType(m.descriptor)
+ case ClassBType(internalName) => asm.Type.getObjectType(internalName) // see (*) above
+ case a: ArrayBType => asm.Type.getObjectType(a.descriptor)
+ case m: MethodBType => asm.Type.getMethodType(m.descriptor)
}
def asRefBType : RefBType = this.asInstanceOf[RefBType]
@@ -227,39 +227,254 @@ abstract class BTypes[G <: Global](val __global_dont_use: G) {
* This can be verified for example using javap or ASMifier.
*/
def classOrArrayType: String = this match {
- case c: ClassBType => c.internalName
- case a: ArrayBType => a.descriptor
+ case ClassBType(internalName) => internalName
+ case a: ArrayBType => a.descriptor
}
}
/**
+ * InnerClass and EnclosingMethod attributes (EnclosingMethod is displayed as OUTERCLASS in asm).
+ *
+ * In this summary, "class" means "class or interface".
+ *
+ * JLS: http://docs.oracle.com/javase/specs/jls/se8/html/index.html
+ * JVMS: http://docs.oracle.com/javase/specs/jvms/se8/html/index.html
+ *
+ * Terminology
+ * -----------
+ *
+ * - Nested class (JLS 8): class whose declaration occurs within the body of another class
+ *
+ * - Top-level class (JLS 8): non-nested class
+ *
+ * - Inner class (JLS 8.1.3): nested class that is not (explicitly or implicitly) static
+ *
+ * - Member class (JLS 8.5): class directly enclosed in the body of a class (and not, for
+ * example, defined in a method). Member classes cannot be anonymous. May be static.
+ *
+ * - Local class (JLS 14.3): nested, non-anonymous class that is not a member of a class
+ * - cannot be static (therefore they are "inner" classes)
+ * - can be defined in a method, a constructor or in an initializer block
+ *
+ * - Initializer block (JLS 8.6 / 8.7): block of statements in a java class
+ * - static initializer: executed before constructor body
+ * - instance initializer: exectued when class is initialized (instance creation, static
+ * field access, ...)
+ *
+ *
+ * InnerClass
+ * ----------
+ *
+ * The JVMS 4.7.6 requires an entry for every class mentioned in a CONSTANT_Class_info in the
+ * constant pool (CP) that is not a member of a package (JLS 7.1).
+ *
+ * The JLS 13.1, points 9. / 10. requires: a class must reference (in the CP)
+ * - its immediately enclosing class
+ * - all of its member classes
+ * - all local and anonymous classes that appear elsewhere (method, constructor, initializer
+ * block, field initializer)
+ *
+ * In a comment, the 4.7.6 spec says: this implies an entry in the InnerClass attribute for
+ * - All enclosing classes (except the outermost, which is top-level)
+ * - My comment: not sure how this is implied, below (*) a Java counter-example.
+ * In any case, the Java compiler seems to add all enclosing classes, even if they are not
+ * otherwise mentioned in the CP. So we should do the same.
+ * - All nested classes (including anonymous and local, but not transitively)
+ *
+ * Fields in the InnerClass entries:
+ * - inner class: the (nested) class C we are talking about
+ * - outer class: the class of which C is a member. Has to be null for non-members, i.e. for
+ * local and anonymous classes.
+ * - inner name: A string with the simple name of the inner class. Null for anonymous classes.
+ * - flags: access property flags, details in JVMS, table in 4.7.6.
+ *
+ *
+ * Note 1: when a nested class is present in the InnerClass attribute, all of its enclosing
+ * classes have to be present as well (by the rules above). Example:
+ *
+ * class Outer { class I1 { class I2 { } } }
+ * class User { Outer.I1.I2 foo() { } }
+ *
+ * The return type "Outer.I1.I2" puts "Outer$I1$I2" in the CP, therefore the class is added to the
+ * InnerClass attribute. For this entry, the "outer class" field will be "Outer$I1". This in turn
+ * adds "Outer$I1" to the CP, which requires adding that class to the InnerClass attribute.
+ * (For local / anonymous classes this would not be the case, since the "outer class" attribute
+ * would be empty. However, no class (other than the enclosing class) can refer to them, as they
+ * have no name.)
+ *
+ * In the current implementation of the Scala compiler, when adding a class to the InnerClass
+ * attribute, all of its enclosing classes will be added as well. Javac seems to do the same,
+ * see (*).
+ *
+ *
+ * Note 2: If a class name is mentioned only in a CONSTANT_Utf8_info, but not in a
+ * CONSTANT_Class_info, the JVMS does not require an entry in the InnerClass attribute. However,
+ * the Java compiler seems to add such classes anyway. For example, when using an annotation, the
+ * annotation class is stored as a CONSTANT_Utf8_info in the CP:
+ *
+ * @O.Ann void foo() { }
+ *
+ * adds "const #13 = Asciz LO$Ann;;" in the constant pool. The "RuntimeInvisibleAnnotations"
+ * attribute refers to that constant pool entry. Even though there is no other reference to
+ * `O.Ann`, the java compiler adds an entry for that class to the InnerClass attribute (which
+ * entails adding a CONSTANT_Class_info for the class).
+ *
+ *
+ *
+ * EnclosingMethod
+ * ---------------
+ *
+ * JVMS 4.7.7: the attribute must be present "if and only if it represents a local class
+ * or an anonymous class" (i.e. not for member classes).
+ *
+ * Fields:
+ * - class: the enclosing class
+ * - method: the enclosing method (or constructor). Null if the class is not enclosed by a
+ * method, i.e. for
+ * - local or anonymous classes defined in (static or non-static) initializer blocks
+ * - anonymous classes defined in initializer blocks or field initializers
+ *
+ * Note: the field is required for anonymous classes defined within local variable
+ * initializers (within a method), Java example below (**).
+ *
+ * Currently, the Scala compiler sets "method" to the class constructor for classes
+ * defined in initializer blocks or field initializers. This is probably OK, since the
+ * Scala compiler desugars these statements into to the primary constructor.
+ *
+ *
+ * (*)
+ * public class Test {
+ * void foo() {
+ * class Foo1 {
+ * // constructor statement block
+ * {
+ * class Foo2 {
+ * class Foo3 { }
+ * }
+ * }
+ * }
+ * }
+ * }
+ *
+ * The class file Test$1Foo1$1Foo2$Foo3 has no reference to the class Test$1Foo1, however it
+ * still contains an InnerClass attribute for Test$1Foo1.
+ * Maybe this is just because the Java compiler follows the JVMS comment ("InnerClasses
+ * information for each enclosing class").
+ *
+ *
+ * (**)
+ * void foo() {
+ * // anonymous class defined in local variable initializer expression.
+ * Runnable x = true ? (new Runnable() {
+ * public void run() { return; }
+ * }) : null;
+ * }
+ *
+ * The EnclosingMethod attribute of the anonymous class mentions "foo" in the "method" field.
+ *
+ *
+ * Java Compatibility
+ * ------------------
+ *
+ * In the InnerClass entry for classes in top-level modules, the "outer class" is emitted as the
+ * mirror class (or the existing companion class), i.e. C1 is nested in T (not T$).
+ * For classes nested in a nested object, the "outer class" is the module class: C2 is nested in T$N$
+ * object T {
+ * class C1
+ * object N { class C2 }
+ * }
+ *
+ * Reason: java compat. It's a "best effort" "solution". If you want to use "C1" from Java, you
+ * can write "T.C1", and the Java compiler will translate that to the classfile T$C1.
+ *
+ * If we would emit the "outer class" of C1 as "T$", then in Java you'd need to write "T$.C1"
+ * because the java compiler looks at the InnerClass attribute to find if an inner class exists.
+ * However, the Java compiler would then translate the '.' to '$' and you'd get the class name
+ * "T$$C1". This class file obviously does not exist.
+ *
+ * Directly using the encoded class name "T$C1" in Java does not work: since the classfile
+ * describes a nested class, the Java compiler hides it from the classpath and will report
+ * "cannot find symbol T$C1". This means that the class T.N.C2 cannot be referenced from a
+ * Java source file in any way.
+ *
+ *
+ * STATIC flag
+ * -----------
+ *
+ * Java: static nested classes have the "static" flag in the InnerClass attribute. This is not the
+ * case for local classes defined within a static method, even though such classes, as they are
+ * defined in a static context, don't take an "outer" instance.
+ * Non-static nested classes (inner classes, including local classes defined in a non-static
+ * method) take an "outer" instance on construction.
+ *
+ * Scala: Explicitouter adds an "outer" parameter to nested classes, except for classes defined
+ * in a static context, i.e. when all outer classes are module classes.
+ * package p
+ * object O1 {
+ * class C1 // static
+ * object O2 {
+ * def f = {
+ * class C2 { // static
+ * class C3 // non-static, needs outer
+ * }
+ * }
+ * }
+ * }
+ *
+ * Int the InnerClass attribute, the `static` flag is added for all classes defined in a static
+ * context, i.e. also for C2. This is different than in Java.
+ *
+ *
+ * Mirror Classes
+ * --------------
+ *
+ * TODO: innerclass attributes on mirror class, bean info class
+ */
+
+ /**
* Class or Interface type.
*
- * Classes are represented using their name as a slice of the `chrs` array. This representation is
- * efficient because the JVM class name is initially created using `classSymbol.javaBinaryName`.
- * This already adds the necessary string to the `chrs` array, so it makes sense to reuse the same
- * name table in the backend.
+ * The information for creating a ClassBType (superClass, interfaces, etc) is obtained
+ * - either from a ClassSymbol, for classes being compiled or referenced from source (see
+ * BCodeTypes)
+ * - or, during inlining, from ASM ClassNodes that are parsed from class files.
+ *
+ * The class name is represented as a slice of the `chrs` array. This representation is efficient
+ * because the JVM class name is obtained through `classSymbol.javaBinaryName`. This already adds
+ * the necessary string to the `chrs` array, so it makes sense to reuse the same name table in the
+ * backend.
+ *
+ * Not a case class because that would expose the constructor that takes (offset, length)
+ * parameters (I didn't find a way to make it private, also the factory in the companion).
+ *
+ * @param offset See below
+ * @param length The class name is represented as offset and length in the `chrs` array.
+ * The (public) constructors of ClassBType take a BTypeName, which are
+ * hash-consed. This ensures that two ClassBType instances for the same name
+ * have the same offset and length.
*
* Not a case class because that would expose the (Int, Int) constructor (didn't find a way to
* make it private, also the factory in the companion).
*/
class ClassBType private(val offset: Int, val length: Int) extends RefBType {
/**
- * Construct a ClassBType for a given (intenred) class name.
+ * Construct a ClassBType from the (intenred) internal name of a class.
*
- * @param n The class name as a slice of the `chrs` array, without the surrounding 'L' and ';'.
- * Note that `classSymbol.javaBinaryName` returns exactly such a name.
+ * @param internalName The internal name as a slice of the `chrs` array. The internal name does
+ * not have the surrounding 'L' and ';'. Note that
+ * `classSymbol.javaBinaryName` returns exactly such a name.
*/
- def this(n: BTypeName) = this(n.start, n.length)
+ def this(internalName: BTypeName) = this(internalName.start, internalName.length)
/**
- * Construct a ClassBType for a given java class name.
+ * Construct a ClassBType from the internal name of a class.
*
- * @param s A class name of the form "java/lang/String", without the surrounding 'L' and ';'.
+ * @param internalName The internal name of a class has the form "java/lang/String", without the
+ * surrounding 'L' and ';'.
*/
- def this(s: String) = this({
- assert(!(s.head == 'L' && s.last == ';'), s"Descriptor instead of internal name: $s")
- createNewName(s)
+ def this(internalName: String) = this({
+ assert(!(internalName.head == 'L' && internalName.last == ';'), s"Descriptor instead of internal name: $internalName")
+ createNewName(internalName)
})
/**
@@ -277,7 +492,7 @@ abstract class BTypes[G <: Global](val __global_dont_use: G) {
* Custom equals / hashCode are needed because this is not a case class.
*/
override def equals(o: Any): Boolean = (this eq o.asInstanceOf[Object]) || (o match {
- case ClassBType(`offset`, `length`) => true
+ case c: ClassBType => c.offset == this.offset && c.length == this.length
case _ => false
})
@@ -291,12 +506,15 @@ abstract class BTypes[G <: Global](val __global_dont_use: G) {
}
object ClassBType {
- def apply(n: BTypeName): ClassBType = new ClassBType(n)
- def apply(s: String): ClassBType = new ClassBType(s)
+ def apply(internalName: BTypeName): ClassBType = new ClassBType(internalName)
+ def apply(internalName: String): ClassBType = new ClassBType(internalName)
- def unapply(c: ClassBType): Option[(Int, Int)] =
+ /**
+ * Pattern matching on a ClassBType extracts the `internalName` of the class.
+ */
+ def unapply(c: ClassBType): Option[String] =
if (c == null) None
- else Some((c.offset, c.length))
+ else Some(c.internalName)
}
case class ArrayBType(componentType: BType) extends RefBType {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index b0fb3069c1..2392033760 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -381,6 +381,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
case "jvm-1.5" => asm.Opcodes.V1_5
case "jvm-1.6" => asm.Opcodes.V1_6
case "jvm-1.7" => asm.Opcodes.V1_7
+ case "jvm-1.8" => asm.Opcodes.V1_8
}
private val majorVersion: Int = (classfileVersion & 0xFF)
@@ -636,6 +637,9 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
innerSym.rawname + innerSym.moduleSuffix
// add inner classes which might not have been referenced yet
+ // TODO @lry according to the spec, all nested classes should be added, also local and
+ // anonymous. This seems to add only member classes - or not? it's exitingErasure, so maybe
+ // local / anonymous classes have been lifted by lambdalift. are they in the "decls" though?
exitingErasure {
for (sym <- List(csym, csym.linkedClassOfClass); m <- sym.info.decls.map(innerClassSymbolFor) if m.isClass)
innerClassBuffer += m
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
index a401de05e5..89866b7ce9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
@@ -165,7 +165,7 @@ abstract class GenBCode extends BCodeSyncAndTry {
// -------------- mirror class, if needed --------------
val mirrorC =
- if (isStaticModule(claszSymbol) && isTopLevelModule(claszSymbol)) {
+ if (isTopLevelModuleClass(claszSymbol)) {
if (claszSymbol.companionClass == NoSymbol) {
mirrorCodeGen.genMirrorClass(claszSymbol, cunit)
} else {
@@ -271,7 +271,7 @@ abstract class GenBCode extends BCodeSyncAndTry {
override def run() {
arrivalPos = 0 // just in case
- scalaPrimitives.init
+ scalaPrimitives.init()
initBCodeTypes()
// initBytecodeWriter invokes fullName, thus we have to run it before the typer-dependent thread is activated.
diff --git a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
index c73e7ce00e..d0b8fd70ed 100644
--- a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
@@ -29,7 +29,7 @@ trait AbsScalaSettings {
def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): ChoiceSetting
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]): IntSetting
def MultiStringSetting(name: String, helpArg: String, descr: String): MultiStringSetting
- def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: () => Unit)(helper: MultiChoiceSetting => String): MultiChoiceSetting
+ def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: Option[() => Unit])(helper: MultiChoiceSetting => String): MultiChoiceSetting
def OutputSetting(outputDirs: OutputDirs, default: String): OutputSetting
def PathSetting(name: String, descr: String, default: String): PathSetting
def PhasesSetting(name: String, descr: String, default: String): PhasesSetting
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
index 3f41ede3ad..f26192f88a 100644
--- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
@@ -211,7 +211,7 @@ class MutableSettings(val errorFn: String => Unit)
add(new ChoiceSetting(name, helpArg, descr, choices, default))
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]) = add(new IntSetting(name, descr, default, range, parser))
def MultiStringSetting(name: String, arg: String, descr: String) = add(new MultiStringSetting(name, arg, descr))
- def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: () => Unit = () => ())(
+ def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: Option[() => Unit] = None)(
helper: MultiChoiceSetting => String = _ => choices.mkString(f"$descr:%n", f"%n ", f"%n")
) =
add(new MultiChoiceSetting(name, helpArg, descr, choices, default, helper))
@@ -563,19 +563,23 @@ class MutableSettings(val errorFn: String => Unit)
arg: String,
descr: String,
override val choices: List[String],
- val default: () => Unit,
+ val default: Option[() => Unit],
helper: MultiChoiceSetting => String
) extends MultiStringSetting(name, s"_,$arg,-$arg", s"$descr: `_' for all, `$name:help' to list") {
private def badChoice(s: String, n: String) = errorFn(s"'$s' is not a valid choice for '$name'")
private def choosing = choices.nonEmpty
private def isChoice(s: String) = (s == "_") || (choices contains (s stripPrefix "-"))
- private var sawHelp = false
+
+ private var sawHelp = false
+ private var sawAll = false
+ private val adderAll = () => sawAll = true
+ private val noargs = () => errorFn(s"'$name' requires an option. See '$name:help'.")
override protected def tts(args: List[String], halting: Boolean) = {
val added = collection.mutable.ListBuffer.empty[String]
def tryArg(arg: String) = arg match {
- case "_" if choosing => default()
+ case "_" if choosing => addAll()
case "help" if choosing => sawHelp = true
case s if !choosing || isChoice(s) => added += s
case s => badChoice(s, name)
@@ -587,13 +591,19 @@ class MutableSettings(val errorFn: String => Unit)
case Nil => Nil
}
val rest = loop(args)
- if (rest.size == args.size) default() // if no arg consumed, trigger default action
- else value = added.toList // update all new settings at once
+ if (rest.size == args.size)
+ (default getOrElse noargs)() // if no arg consumed, trigger default action or error
+ else
+ value ++= added.toList // update all new settings at once
Some(rest)
}
def isHelping: Boolean = sawHelp
- def help: String = helper(this)
+ def help: String = helper(this)
+ def addAll(): Unit = (default getOrElse adderAll)()
+
+ // the semantics is: s is enabled, i.e., either s or (_ but not -s)
+ override def contains(s: String) = isChoice(s) && (value contains s) || (sawAll && !(value contains s"-$s"))
}
/** A setting that accumulates all strings supplied to it,
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 5c3eadbd60..8e69598614 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -207,7 +207,6 @@ trait ScalaSettings extends AbsScalaSettings
val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.").withDeprecationMessage(removalIn212)
val inferByName = BooleanSetting ("-Yinfer-by-name", "Allow inference of by-name types. This is a temporary option to ease transition. See SI-7899.").withDeprecationMessage(removalIn212)
- val Yinvalidate = StringSetting ("-Yinvalidate", "classpath-entry", "Invalidate classpath entry before run", "")
val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes")
val YdisableUnreachablePrevention = BooleanSetting("-Ydisable-unreachable-prevention", "Disable the prevention of unreachable blocks in code generation.")
val YnoLoadImplClass = BooleanSetting ("-Yno-load-impl-class", "Do not load $class.class files.")
diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
index 37dfafb01c..d42c0dd730 100644
--- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
@@ -39,7 +39,7 @@ trait StandardScalaSettings {
val optimise: BooleanSetting // depends on post hook which mutates other settings
val print = BooleanSetting ("-print", "Print program with Scala-specific features removed.")
val target = ChoiceSetting ("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.",
- List("jvm-1.5", "jvm-1.6", "jvm-1.7"), "jvm-1.6")
+ List("jvm-1.5", "jvm-1.6", "jvm-1.7", "jvm-1.8"), "jvm-1.6")
val unchecked = BooleanSetting ("-unchecked", "Enable additional warnings where generated code depends on assumptions.")
val uniqid = BooleanSetting ("-uniqid", "Uniquely tag all identifiers in debugging output.")
val usejavacp = BooleanSetting ("-usejavacp", "Utilize the java.class.path in classpath resolution.")
diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala
index 9989d1d188..bec068b56a 100644
--- a/src/compiler/scala/tools/nsc/settings/Warnings.scala
+++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala
@@ -116,7 +116,7 @@ trait Warnings {
helpArg = "warning",
descr = description,
choices = choices,
- default = () => xlint.value = true
+ default = Some(() => xlint.value = true)
) { s =>
def helpline(n: String) = lintWarnings.find(_.name == n).map(w => f" ${w.name}%-25s ${w.helpDescription}%n")
choices flatMap (helpline(_)) mkString (f"$description:%n", "", f"%n")
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 447fa66ae4..82c2a4d6ed 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -240,6 +240,12 @@ abstract class SymbolLoaders {
}
}
+ private def phaseBeforeRefchecks: Phase = {
+ var resPhase = phase
+ while (resPhase.refChecked) resPhase = resPhase.prev
+ resPhase
+ }
+
/**
* Load contents of a package
*/
@@ -248,19 +254,24 @@ abstract class SymbolLoaders {
protected def doComplete(root: Symbol) {
assert(root.isPackageClass, root)
- root.setInfo(new PackageClassInfoType(newScope, root))
-
- if (!root.isRoot) {
- for (classRep <- classpath.classes) {
- initializeFromClassPath(root, classRep)
- }
- }
- if (!root.isEmptyPackageClass) {
- for (pkg <- classpath.packages) {
- enterPackage(root, pkg.name, new PackageLoader(pkg))
+ // Time travel to a phase before refchecks avoids an initialization issue. `openPackageModule`
+ // creates a module symbol and invokes invokes `companionModule` while the `infos` field is
+ // still null. This calls `isModuleNotMethod`, which forces the `info` if run after refchecks.
+ enteringPhase(phaseBeforeRefchecks) {
+ root.setInfo(new PackageClassInfoType(newScope, root))
+
+ if (!root.isRoot) {
+ for (classRep <- classpath.classes) {
+ initializeFromClassPath(root, classRep)
+ }
}
+ if (!root.isEmptyPackageClass) {
+ for (pkg <- classpath.packages) {
+ enterPackage(root, pkg.name, new PackageLoader(pkg))
+ }
- openPackageModule(root)
+ openPackageModule(root)
+ }
}
}
}
@@ -290,7 +301,13 @@ abstract class SymbolLoaders {
protected def doComplete(root: Symbol) {
val start = if (Statistics.canEnable) Statistics.startTimer(classReadNanos) else null
- classfileParser.parse(classfile, root)
+
+ // Running the classfile parser after refchecks can lead to "illegal class file dependency"
+ // errors. More concretely, the classfile parser calls "sym.companionModule", which calls
+ // "isModuleNotMethod" on the companion. After refchecks, this method forces the info, which
+ // may run the classfile parser. This produces the error.
+ enteringPhase(phaseBeforeRefchecks)(classfileParser.parse(classfile, root))
+
if (root.associatedFile eq NoAbstractFile) {
root match {
// In fact, the ModuleSymbol forwards its setter to the module class
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index c3fbfae322..fa53ef48b5 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -76,8 +76,17 @@ abstract class Flatten extends InfoTransform {
for (sym <- decls) {
if (sym.isTerm && !sym.isStaticModule) {
decls1 enter sym
- if (sym.isModule)
+ if (sym.isModule) {
+ // Nested, non-static moduls are transformed to methods.
+ assert(sym.isMethod, s"Non-static $sym should have the lateMETHOD flag from RefChecks")
+ // Note that module classes are not entered into the 'decls' of the ClassInfoType
+ // of the outer class, only the module symbols are. So the current loop does
+ // not visit module classes. Therefore we set the LIFTED flag here for module
+ // classes.
+ // TODO: should we also set the LIFTED flag for static, nested module classes?
+ // currently they don't get the flag, even though they are lifted to the package
sym.moduleClass setFlag LIFTED
+ }
} else if (sym.isClass)
liftSymbol(sym)
}
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index b71d14a04f..38671ebaae 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -192,13 +192,15 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
def mkSlowPathDef(clazz: Symbol, lzyVal: Symbol, cond: Tree, syncBody: List[Tree],
stats: List[Tree], retVal: Tree): Tree = {
+ // Q: is there a reason to first set owner to `clazz` (by using clazz.newMethod), and then
+ // changing it to lzyVal.owner very soon after? Could we just do lzyVal.owner.newMethod?
val defSym = clazz.newMethod(nme.newLazyValSlowComputeName(lzyVal.name.toTermName), lzyVal.pos, STABLE | PRIVATE)
defSym setInfo MethodType(List(), lzyVal.tpe.resultType)
defSym.owner = lzyVal.owner
debuglog(s"crete slow compute path $defSym with owner ${defSym.owner} for lazy val $lzyVal")
if (bitmaps.contains(lzyVal))
bitmaps(lzyVal).map(_.owner = defSym)
- val rhs: Tree = (gen.mkSynchronizedCheck(clazz, cond, syncBody, stats)).changeOwner(currentOwner -> defSym)
+ val rhs: Tree = gen.mkSynchronizedCheck(clazz, cond, syncBody, stats).changeOwner(currentOwner -> defSym)
DefDef(defSym, addBitmapDefs(lzyVal, BLOCK(rhs, retVal)))
}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 2209aac00f..9b85f1b36a 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -69,7 +69,6 @@ abstract class UnCurry extends InfoTransform
private val byNameArgs = mutable.HashSet[Tree]()
private val noApply = mutable.HashSet[Tree]()
private val newMembers = mutable.Map[Symbol, mutable.Buffer[Tree]]()
- private val repeatedParams = mutable.Map[Symbol, List[ValDef]]()
/** Add a new synthetic member for `currentOwner` */
private def addNewMember(t: Tree): Unit =
@@ -428,7 +427,7 @@ abstract class UnCurry extends InfoTransform
treeCopy.ValDef(p, p.mods, p.name, p.tpt, EmptyTree)
})
- if (dd.symbol hasAnnotation VarargsClass) saveRepeatedParams(dd)
+ if (dd.symbol hasAnnotation VarargsClass) validateVarargs(dd)
withNeedLift(needLift = false) {
if (dd.symbol.isClassConstructor) {
@@ -699,19 +698,12 @@ abstract class UnCurry extends InfoTransform
}
}
-
- /* Analyzes repeated params if method is annotated as `varargs`.
- * If the repeated params exist, it saves them into the `repeatedParams` map,
- * which is used later.
- */
- private def saveRepeatedParams(dd: DefDef): Unit =
+ private def validateVarargs(dd: DefDef): Unit =
if (dd.symbol.isConstructor)
reporter.error(dd.symbol.pos, "A constructor cannot be annotated with a `varargs` annotation.")
- else treeInfo.repeatedParams(dd) match {
- case Nil =>
- reporter.error(dd.symbol.pos, "A method without repeated parameters cannot be annotated with the `varargs` annotation.")
- case reps =>
- repeatedParams(dd.symbol) = reps
+ else {
+ val hasRepeated = mexists(dd.symbol.paramss)(sym => definitions.isRepeatedParamType(sym.tpe))
+ if (!hasRepeated) reporter.error(dd.symbol.pos, "A method without repeated parameters cannot be annotated with the `varargs` annotation.")
}
/* Called during post transform, after the method argument lists have been flattened.
@@ -719,7 +711,7 @@ abstract class UnCurry extends InfoTransform
* varargs forwarder.
*/
private def addJavaVarargsForwarders(dd: DefDef, flatdd: DefDef): DefDef = {
- if (!dd.symbol.hasAnnotation(VarargsClass) || !repeatedParams.contains(dd.symbol))
+ if (!dd.symbol.hasAnnotation(VarargsClass) || !enteringUncurry(mexists(dd.symbol.paramss)(sym => definitions.isRepeatedParamType(sym.tpe))))
return flatdd
def toArrayType(tp: Type): Type = {
@@ -735,19 +727,18 @@ abstract class UnCurry extends InfoTransform
)
}
- val reps = repeatedParams(dd.symbol)
- val rpsymbols = reps.map(_.symbol).toSet
val theTyper = typer.atOwner(dd, currentClass)
- val flatparams = flatdd.vparamss.head
+ val flatparams = flatdd.symbol.paramss.head
+ val isRepeated = enteringUncurry(dd.symbol.info.paramss.flatten.map(sym => definitions.isRepeatedParamType(sym.tpe)))
// create the type
- val forwformals = flatparams map {
- case p if rpsymbols(p.symbol) => toArrayType(p.symbol.tpe)
- case p => p.symbol.tpe
+ val forwformals = map2(flatparams, isRepeated) {
+ case (p, true) => toArrayType(p.tpe)
+ case (p, false)=> p.tpe
}
val forwresult = dd.symbol.tpe_*.finalResultType
val forwformsyms = map2(forwformals, flatparams)((tp, oldparam) =>
- currentClass.newValueParameter(oldparam.name, oldparam.symbol.pos).setInfo(tp)
+ currentClass.newValueParameter(oldparam.name.toTermName, oldparam.pos).setInfo(tp)
)
def mono = MethodType(forwformsyms, forwresult)
val forwtype = dd.symbol.tpe match {
@@ -761,13 +752,13 @@ abstract class UnCurry extends InfoTransform
// create the tree
val forwtree = theTyper.typedPos(dd.pos) {
- val locals = map2(forwParams, flatparams) {
- case (_, fp) if !rpsymbols(fp.symbol) => null
- case (argsym, fp) =>
+ val locals = map3(forwParams, flatparams, isRepeated) {
+ case (_, fp, false) => null
+ case (argsym, fp, true) =>
Block(Nil,
gen.mkCast(
gen.mkWrapArray(Ident(argsym), elementType(ArrayClass, argsym.tpe)),
- seqType(elementType(SeqClass, fp.symbol.tpe))
+ seqType(elementType(SeqClass, fp.tpe))
)
)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 9c22688581..33d3432ae2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -576,7 +576,10 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
// also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc
val expanded1 = try onSuccess(duplicateAndKeepPositions(expanded)) finally popMacroContext()
if (!hasMacroExpansionAttachment(expanded1)) linkExpandeeAndExpanded(expandee, expanded1)
- if (settings.Ymacroexpand.value == settings.MacroExpand.Discard) expandee.setType(expanded1.tpe)
+ if (settings.Ymacroexpand.value == settings.MacroExpand.Discard) {
+ suppressMacroExpansion(expandee)
+ expandee.setType(expanded1.tpe)
+ }
else expanded1
case Fallback(fallback) => onFallback(fallback)
case Delayed(delayed) => onDelayed(delayed)
diff --git a/src/jline/LICENSE.txt b/src/jline/LICENSE.txt
deleted file mode 100644
index 1cdc44c211..0000000000
--- a/src/jline/LICENSE.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or
-without modification, are permitted provided that the following
-conditions are met:
-
-Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with
-the distribution.
-
-Neither the name of JLine nor the names of its contributors
-may be used to endorse or promote products derived from this
-software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/src/jline/README.md b/src/jline/README.md
deleted file mode 100644
index 829476145d..0000000000
--- a/src/jline/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-Description
------------
-
-JLine 2.x
-
-License
--------
-
-BSD
-
-Building
---------
-
-### Requirements
-
-* SBT
-* Java 5+
-
-This is a fork with scala specific modifications.
-The original repository was: git://github.com/jdillon/jline2.git
-
-You can now build with sbt:
-
- sbt update proguard
diff --git a/src/jline/build.sbt b/src/jline/build.sbt
deleted file mode 100644
index 873f7574f1..0000000000
--- a/src/jline/build.sbt
+++ /dev/null
@@ -1,49 +0,0 @@
-seq(ProguardPlugin.proguardSettings :_*)
-
-name := "jline"
-
-organization := "org.scala-lang"
-
-version := "2.11.0-SNAPSHOT"
-
-scalaVersion := "2.10.1"
-
-// Only need these because of weird testing jline issues.
-retrieveManaged := true
-
-parallelExecution in Test := false
-
-libraryDependencies ++= Seq(
- "org.fusesource.jansi" % "jansi" % "1.10",
- "com.novocode" % "junit-interface" % "0.9" % "test->default"
-)
-
-javacOptions ++= Seq("-source", "1.5", "-target", "1.5")
-
-proguardOptions ++= Seq(
- "-dontshrink",
- "-keep class *",
- "-keepdirectories"
-)
-
-proguardInJars := Nil
-
-makeInJarFilter ~= { prevFilter =>
- val jansiFilter = List(
- "!META-INF/MANIFEST.MF",
- "org/fusesource/hawtjni/runtime",
- "org/fusesource/hawtjni/runtime/Callback.class",
- "org/fusesource/hawtjni/runtime/Library.class",
- "!org/fusesource/hawtjni/**",
- "!META-INF/maven/org.fusesource.hawtjni",
- "!META-INF/maven/org.fusesource.jansi",
- "!META-INF/maven/org.fusesource.hawtjni/**",
- "!META-INF/maven/org.fusesource.jansi/**"
- ).mkString(",")
- // In sbt 0.9.8 the scala-library.jar line was not necessary,
- // but in 0.9.9 it started showing up here. Who knows.
- file =>
- if (file startsWith "jansi-") jansiFilter
- else if (file == "scala-library.jar") "!**"
- else prevFilter(file)
-}
diff --git a/src/jline/manual-test.sh b/src/jline/manual-test.sh
deleted file mode 100755
index 744e1756e8..0000000000
--- a/src/jline/manual-test.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-#
-# Apparently the jline bundled with sbt interferes with testing some
-# changes: for instance after changing the keybindings I kept seeing
-# failures until I realized what was happening and bypassed sbt, like this.
-CP=lib_managed/jars/com.novocode/junit-interface/junit-interface-0.9.jar:lib_managed/jars/junit/junit-dep/junit-dep-4.8.2.jar:lib_managed/jars/org.fusesource.jansi/jansi/jansi-1.10.jar:lib_managed/jars/org.hamcrest/hamcrest-core/hamcrest-core-1.1.jar:lib_managed/jars/org.scala-tools.testing/test-interface/test-interface-0.5.jar:target/scala-2.10/test-classes:target/scala-2.10/jline_2.10-2.11.0-SNAPSHOT.min.jar
-
-sbt proguard
-java -cp $CP org.junit.runner.JUnitCore scala.tools.jline.console.EditLineTest
diff --git a/src/jline/project/build.properties b/src/jline/project/build.properties
deleted file mode 100644
index 9b860e23c5..0000000000
--- a/src/jline/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=0.12.3
diff --git a/src/jline/project/plugins.sbt b/src/jline/project/plugins.sbt
deleted file mode 100644
index 9c13de92d8..0000000000
--- a/src/jline/project/plugins.sbt
+++ /dev/null
@@ -1,3 +0,0 @@
-resolvers += Resolver.url("sbt-plugin-releases-scalasbt", url("http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
-
-addSbtPlugin("org.scala-sbt" % "xsbt-proguard-plugin" % "0.1.3")
diff --git a/src/jline/src/main/java/scala/tools/jline/AnsiWindowsTerminal.java b/src/jline/src/main/java/scala/tools/jline/AnsiWindowsTerminal.java
deleted file mode 100644
index 94697137d3..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/AnsiWindowsTerminal.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2009 the original author(s).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * MODIFICATIONS: methods to deal with wrapping the output stream.
- */
-
-package scala.tools.jline;
-
-import org.fusesource.jansi.AnsiConsole;
-import org.fusesource.jansi.AnsiOutputStream;
-import org.fusesource.jansi.WindowsAnsiOutputStream;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-
-/**
- * ANSI-supported {@link WindowsTerminal}.
- *
- * @since 2.0
- */
-public class AnsiWindowsTerminal
- extends WindowsTerminal
-{
- private final boolean ansiSupported = detectAnsiSupport();
-
- @Override
- public OutputStream wrapOutIfNeeded(OutputStream out) {
- return wrapOutputStream(out);
- }
-
- /**
- * Returns an ansi output stream handler. We return whatever was
- * passed if we determine we cannot handle ansi based on Kernel32 calls.
- *
- * @return an @{link AltWindowAnsiOutputStream} instance or the passed
- * stream.
- */
- private static OutputStream wrapOutputStream(final OutputStream stream) {
- String os = System.getProperty("os.name");
- if( os.startsWith("Windows") ) {
- // On windows we know the console does not interpret ANSI codes..
- try {
- return new WindowsAnsiOutputStream(stream);
- } catch (Throwable ignore) {
- // this happens when JNA is not in the path.. or
- // this happens when the stdout is being redirected to a file.
- }
- // Use the ANSIOutputStream to strip out the ANSI escape sequences.
- return new AnsiOutputStream(stream);
- }
- return stream;
- }
-
- private static boolean detectAnsiSupport() {
- OutputStream out = AnsiConsole.wrapOutputStream(new ByteArrayOutputStream());
- try {
- out.close();
- }
- catch (Exception e) {
- // ignore;
- }
- return out instanceof WindowsAnsiOutputStream;
- }
-
- public AnsiWindowsTerminal() throws Exception {
- super();
- }
-
- @Override
- public boolean isAnsiSupported() {
- return ansiSupported;
- }
-
- @Override
- public boolean hasWeirdWrap() {
- return false;
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/NoInterruptUnixTerminal.java b/src/jline/src/main/java/scala/tools/jline/NoInterruptUnixTerminal.java
deleted file mode 100644
index ef7cf23c4a..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/NoInterruptUnixTerminal.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 the original author(s).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package scala.tools.jline;
-
-// Based on Apache Karaf impl
-
-/**
- * Non-interruptable (via CTRL-C) {@link UnixTerminal}.
- *
- * @since 2.0
- */
-public class NoInterruptUnixTerminal
- extends UnixTerminal
-{
- public NoInterruptUnixTerminal() throws Exception {
- super();
- }
-
- @Override
- public void init() throws Exception {
- super.init();
- getSettings().set("intr undef");
- }
-
- @Override
- public void restore() throws Exception {
- getSettings().set("intr ^C");
- super.restore();
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/Terminal.java b/src/jline/src/main/java/scala/tools/jline/Terminal.java
deleted file mode 100644
index 79611c244d..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/Terminal.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Representation of the input terminal for a platform.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public interface Terminal
-{
- void init() throws Exception;
-
- void restore() throws Exception;
-
- void reset() throws Exception;
-
- boolean isSupported();
-
- int getWidth();
-
- int getHeight();
-
- boolean isAnsiSupported();
-
- /**
- * When ANSI is not natively handled, the output will have to be wrapped.
- */
- OutputStream wrapOutIfNeeded(OutputStream out);
-
- /**
- * For terminals that don't wrap when character is written in last column,
- * only when the next character is written.
- * These are the ones that have 'am' and 'xn' termcap attributes (xterm and
- * rxvt flavors falls under that category)
- */
- boolean hasWeirdWrap();
-
- boolean isEchoEnabled();
-
- void setEchoEnabled(boolean enabled);
-
- int readCharacter(InputStream in) throws IOException;
-
- int readVirtualKey(InputStream in) throws IOException;
-
- InputStream getDefaultBindings();
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/TerminalFactory.java b/src/jline/src/main/java/scala/tools/jline/TerminalFactory.java
deleted file mode 100644
index 95b7c28bd5..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/TerminalFactory.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline;
-
-import scala.tools.jline.internal.Configuration;
-import scala.tools.jline.internal.Log;
-
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Creates terminal instances.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public class TerminalFactory
-{
- public static final String JLINE_TERMINAL = "jline.terminal";
-
- public static final String AUTO = "auto";
-
- public static final String UNIX = "unix";
-
- public static final String WIN = "win";
-
- public static final String WINDOWS = "windows";
-
- public static final String NONE = "none";
-
- public static final String OFF = "off";
-
- public static final String FALSE = "false";
-
- private static final InheritableThreadLocal<Terminal> holder = new InheritableThreadLocal<Terminal>();
-
- public static synchronized Terminal create() {
- if (Log.TRACE) {
- //noinspection ThrowableInstanceNeverThrown
- Log.trace(new Throwable("CREATE MARKER"));
- }
-
- String type = Configuration.getString(JLINE_TERMINAL);
- if (type == null) {
- type = AUTO;
- }
-
- Log.debug("Creating terminal; type=", type);
-
- Terminal t;
- try {
- String tmp = type.toLowerCase();
-
- if (tmp.equals(UNIX)) {
- t = getFlavor(Flavor.UNIX);
- }
- else if (tmp.equals(WIN) | tmp.equals(WINDOWS)) {
- t = getFlavor(Flavor.WINDOWS);
- }
- else if (tmp.equals(NONE) || tmp.equals(OFF) || tmp.equals(FALSE)) {
- t = new UnsupportedTerminal();
- }
- else {
- if (tmp.equals(AUTO)) {
- String os = Configuration.getOsName();
- Flavor flavor = Flavor.UNIX;
- if (os.contains(WINDOWS)) {
- flavor = Flavor.WINDOWS;
- }
- t = getFlavor(flavor);
- }
- else {
- try {
- t = (Terminal) Thread.currentThread().getContextClassLoader().loadClass(type).newInstance();
- }
- catch (Exception e) {
- throw new IllegalArgumentException(MessageFormat.format("Invalid terminal type: {0}", type), e);
- }
- }
- }
- }
- catch (Exception e) {
- Log.error("Failed to construct terminal; falling back to unsupported", e);
- t = new UnsupportedTerminal();
- }
-
- Log.debug("Created Terminal: ", t);
-
- try {
- t.init();
- }
- catch (Exception e) {
- Log.error("Terminal initialization failed; falling back to unsupported", e);
- return new UnsupportedTerminal();
- }
-
- return t;
- }
-
- public static synchronized void reset() {
- holder.remove();
- }
-
- public static synchronized void resetIf(final Terminal t) {
- if (holder.get() == t) {
- reset();
- }
- }
-
- public static enum Type
- {
- AUTO,
- WINDOWS,
- UNIX,
- NONE
- }
-
- public static synchronized void configure(final String type) {
- assert type != null;
- System.setProperty(JLINE_TERMINAL, type);
- }
-
- public static synchronized void configure(final Type type) {
- assert type != null;
- configure(type.name().toLowerCase());
- }
-
- //
- // Flavor Support
- //
-
- public static enum Flavor
- {
- WINDOWS,
- UNIX
- }
-
- private static final Map<Flavor, Class<? extends Terminal>> FLAVORS = new HashMap<Flavor, Class<? extends Terminal>>();
-
- static {
- registerFlavor(Flavor.WINDOWS, AnsiWindowsTerminal.class);
- registerFlavor(Flavor.UNIX, UnixTerminal.class);
- }
-
- public static synchronized Terminal get() {
- Terminal t = holder.get();
- if (t == null) {
- t = create();
- holder.set(t);
- }
- return t;
- }
-
- public static Terminal getFlavor(final Flavor flavor) throws Exception {
- Class<? extends Terminal> type = FLAVORS.get(flavor);
- if (type != null) {
- return type.newInstance();
- }
-
- throw new InternalError();
- }
-
- public static void registerFlavor(final Flavor flavor, final Class<? extends Terminal> type) {
- FLAVORS.put(flavor, type);
- }
-
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/TerminalSupport.java b/src/jline/src/main/java/scala/tools/jline/TerminalSupport.java
deleted file mode 100644
index 1ca12cb73f..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/TerminalSupport.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline;
-
-import scala.tools.jline.internal.Log;
-import scala.tools.jline.internal.Configuration;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Provides support for {@link Terminal} instances.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public abstract class TerminalSupport
- implements Terminal
-{
- public static String DEFAULT_KEYBINDINGS_PROPERTIES = "keybindings.properties";
-
- public static final String JLINE_SHUTDOWNHOOK = "jline.shutdownhook";
-
- public static final int DEFAULT_WIDTH = 80;
-
- public static final int DEFAULT_HEIGHT = 24;
-
- private Thread shutdownHook;
-
- private boolean shutdownHookEnabled;
-
- private boolean supported;
-
- private boolean echoEnabled;
-
- private boolean ansiSupported;
-
- protected TerminalSupport(final boolean supported) {
- this.supported = supported;
- this.shutdownHookEnabled = Configuration.getBoolean(JLINE_SHUTDOWNHOOK, false);
- }
-
- public void init() throws Exception {
- installShutdownHook(new RestoreHook());
- }
-
- public void restore() throws Exception {
- TerminalFactory.resetIf(this);
- removeShutdownHook();
- }
-
- public void reset() throws Exception {
- restore();
- init();
- }
-
- // Shutdown hooks causes classloader leakage in sbt,
- // so they are only installed if -Djline.shutdownhook is true.
- protected void installShutdownHook(final Thread hook) {
- if (!shutdownHookEnabled) {
- Log.debug("Not install shutdown hook " + hook + " because they are disabled.");
- return;
- }
-
- assert hook != null;
-
- if (shutdownHook != null) {
- throw new IllegalStateException("Shutdown hook already installed");
- }
-
- try {
- Runtime.getRuntime().addShutdownHook(hook);
- shutdownHook = hook;
- }
- catch (AbstractMethodError e) {
- // JDK 1.3+ only method. Bummer.
- Log.trace("Failed to register shutdown hook: ", e);
- }
- }
-
- protected void removeShutdownHook() {
- if (!shutdownHookEnabled)
- return;
-
- if (shutdownHook != null) {
- try {
- Runtime.getRuntime().removeShutdownHook(shutdownHook);
- }
- catch (AbstractMethodError e) {
- // JDK 1.3+ only method. Bummer.
- Log.trace("Failed to remove shutdown hook: ", e);
- }
- catch (IllegalStateException e) {
- // The VM is shutting down, not a big deal; ignore
- }
- shutdownHook = null;
- }
- }
-
- public final boolean isSupported() {
- return supported;
- }
-
- public synchronized boolean isAnsiSupported() {
- return ansiSupported;
- }
-
- protected synchronized void setAnsiSupported(final boolean supported) {
- this.ansiSupported = supported;
- Log.debug("Ansi supported: ", supported);
- }
-
- /**
- * Subclass to change behavior if needed.
- * @return the passed out
- */
- public OutputStream wrapOutIfNeeded(OutputStream out) {
- return out;
- }
-
- /**
- * Defaults to true which was the behaviour before this method was added.
- */
- public boolean hasWeirdWrap() {
- return true;
- }
-
- public int getWidth() {
- return DEFAULT_WIDTH;
- }
-
- public int getHeight() {
- return DEFAULT_HEIGHT;
- }
-
- public synchronized boolean isEchoEnabled() {
- return echoEnabled;
- }
-
- public synchronized void setEchoEnabled(final boolean enabled) {
- this.echoEnabled = enabled;
- Log.debug("Echo enabled: ", enabled);
- }
-
- public int readCharacter(final InputStream in) throws IOException {
- return in.read();
- }
-
- public int readVirtualKey(final InputStream in) throws IOException {
- return readCharacter(in);
- }
-
- public InputStream getDefaultBindings() {
- return TerminalSupport.class.getResourceAsStream(DEFAULT_KEYBINDINGS_PROPERTIES);
- }
-
- //
- // RestoreHook
- //
-
- protected class RestoreHook
- extends Thread
- {
- public void start() {
- try {
- restore();
- }
- catch (Exception e) {
- Log.trace("Failed to restore: ", e);
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/UnixTerminal.java b/src/jline/src/main/java/scala/tools/jline/UnixTerminal.java
deleted file mode 100644
index 94a1b98c0d..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/UnixTerminal.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline;
-
-import scala.tools.jline.console.Key;
-import scala.tools.jline.internal.Configuration;
-import scala.tools.jline.internal.Log;
-import scala.tools.jline.internal.ReplayPrefixOneCharInputStream;
-import scala.tools.jline.internal.TerminalLineSettings;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-import static scala.tools.jline.UnixTerminal.UnixKey.*;
-import static scala.tools.jline.console.Key.*;
-
-/**
- * Terminal that is used for unix platforms. Terminal initialization
- * is handled by issuing the <em>stty</em> command against the
- * <em>/dev/tty</em> file to disable character echoing and enable
- * character input. All known unix systems (including
- * Linux and Macintosh OS X) support the <em>stty</em>), so this
- * implementation should work for an reasonable POSIX system.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:dwkemp@gmail.com">Dale Kemp</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofré</a>
- * @since 2.0
- */
-public class UnixTerminal
- extends TerminalSupport
-{
- private final TerminalLineSettings settings = new TerminalLineSettings();
-
- private final ReplayPrefixOneCharInputStream replayStream;
-
- private final InputStreamReader replayReader;
-
- public UnixTerminal() throws Exception {
- super(true);
-
- this.replayStream = new ReplayPrefixOneCharInputStream(Configuration.getInputEncoding());
- this.replayReader = new InputStreamReader(replayStream, replayStream.getEncoding());
- }
-
- protected TerminalLineSettings getSettings() {
- return settings;
- }
-
- /**
- * Remove line-buffered input by invoking "stty -icanon min 1"
- * against the current terminal.
- */
- @Override
- public void init() throws Exception {
- super.init();
-
- setAnsiSupported(true);
-
- // set the console to be character-buffered instead of line-buffered
- settings.set("-icanon min 1");
-
- setEchoEnabled(false);
- }
-
- /**
- * Restore the original terminal configuration, which can be used when
- * shutting down the console reader. The ConsoleReader cannot be
- * used after calling this method.
- */
- @Override
- public void restore() throws Exception {
- settings.restore();
- super.restore();
- // print a newline after the terminal exits.
- // this should probably be a configurable.
- System.out.println();
- }
-
- /**
- * Returns the value of <tt>stty columns</tt> param.
- */
- @Override
- public int getWidth() {
- int w = settings.getProperty("columns");
- return w < 1 ? DEFAULT_WIDTH : w;
- }
-
- /**
- * Returns the value of <tt>stty rows>/tt> param.
- */
- @Override
- public int getHeight() {
- int h = settings.getProperty("rows");
- return h < 1 ? DEFAULT_HEIGHT : h;
- }
-
- @Override
- public synchronized void setEchoEnabled(final boolean enabled) {
- try {
- if (enabled) {
- settings.set("echo");
- }
- else {
- settings.set("-echo");
- }
- super.setEchoEnabled(enabled);
- }
- catch (Exception e) {
- Log.error("Failed to ", (enabled ? "enable" : "disable"), " echo: ", e);
- }
- }
-
- @Override
- public int readVirtualKey(final InputStream in) throws IOException {
- int c = readCharacter(in);
-
- if (Key.valueOf(c) == DELETE && settings.getProperty("erase") == DELETE.code) {
- c = BACKSPACE.code;
- }
-
- UnixKey key = UnixKey.valueOf(c);
-
- // in Unix terminals, arrow keys are represented by a sequence of 3 characters. E.g., the up arrow key yields 27, 91, 68
- if (key == ARROW_START) {
- // also the escape key is 27 thats why we read until we have something different than 27
- // this is a bugfix, because otherwise pressing escape and than an arrow key was an undefined state
- while (key == ARROW_START) {
- c = readCharacter(in);
- key = UnixKey.valueOf(c);
- }
-
- if (key == ARROW_PREFIX || key == O_PREFIX) {
- c = readCharacter(in);
- key = UnixKey.valueOf(c);
-
- if (key == ARROW_UP) {
- return CTRL_P.code;
- }
- else if (key == ARROW_DOWN) {
- return CTRL_N.code;
- }
- else if (key == ARROW_LEFT) {
- return CTRL_B.code;
- }
- else if (key == ARROW_RIGHT) {
- return CTRL_F.code;
- }
- else if (key == HOME_CODE) {
- return CTRL_A.code;
- }
- else if (key == END_CODE) {
- return CTRL_E.code;
- }
- else if (key == DEL_THIRD) {
- readCharacter(in); // read 4th & ignore
- return DELETE.code;
- }
- }
- else if (c == 'b') { // alt-b: go back a word
- return CTRL_O.code; // PREV_WORD
- }
- else if (c == 'f') { // alt-f: go forward a word
- return CTRL_T.code; // NEXT_WORD
- }
- else if (key == DEL) { // alt-backspace: delete previous word
- return CTRL_W.code; // DELETE_PREV_WORD
- }
- else if (c == 'd') { // alt-d: delete next word
- return CTRL_X.code; // DELETE_NEXT_WORD
- }
-
- }
-
- // handle unicode characters, thanks for a patch from amyi@inf.ed.ac.uk
- if (c > 128) {
- // handle unicode characters longer than 2 bytes,
- // thanks to Marc.Herbert@continuent.com
- replayStream.setInput(c, in);
- // replayReader = new InputStreamReader(replayStream, encoding);
- c = replayReader.read();
- }
-
- return c;
- }
-
- /**
- * Unix keys.
- */
- public static enum UnixKey
- {
- ARROW_START(27),
-
- ARROW_PREFIX(91),
-
- ARROW_LEFT(68),
-
- ARROW_RIGHT(67),
-
- ARROW_UP(65),
-
- ARROW_DOWN(66),
-
- O_PREFIX(79),
-
- HOME_CODE(72),
-
- END_CODE(70),
-
- DEL_THIRD(51),
-
- DEL_SECOND(126),
-
- DEL(127);
-
-
- public final short code;
-
- UnixKey(final int code) {
- this.code = (short) code;
- }
-
- private static final Map<Short, UnixKey> codes;
-
- static {
- Map<Short, UnixKey> map = new HashMap<Short, UnixKey>();
-
- for (UnixKey key : UnixKey.values()) {
- map.put(key.code, key);
- }
-
- codes = map;
- }
-
- public static UnixKey valueOf(final int code) {
- return codes.get((short) code);
- }
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/UnsupportedTerminal.java b/src/jline/src/main/java/scala/tools/jline/UnsupportedTerminal.java
deleted file mode 100644
index 04fe4f7f16..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/UnsupportedTerminal.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline;
-
-/**
- * An unsupported terminal.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public class UnsupportedTerminal
- extends TerminalSupport
-{
- public UnsupportedTerminal() {
- super(false);
- setAnsiSupported(false);
- setEchoEnabled(true);
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java b/src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java
deleted file mode 100644
index 4c70155f59..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-import scala.tools.jline.internal.Configuration;
-import org.fusesource.jansi.internal.WindowsSupport;
-
-import scala.tools.jline.internal.Log;
-import scala.tools.jline.internal.ReplayPrefixOneCharInputStream;
-
-import static scala.tools.jline.WindowsTerminal.ConsoleMode.*;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.*;
-import static scala.tools.jline.console.Key.*;
-
-/**
- * Terminal implementation for Microsoft Windows. Terminal initialization in
- * {@link #init} is accomplished by extracting the
- * <em>jline_<i>version</i>.dll</em>, saving it to the system temporary
- * directoy (determined by the setting of the <em>java.io.tmpdir</em> System
- * property), loading the library, and then calling the Win32 APIs <a
- * href="http://msdn.microsoft.com/library/default.asp?
- * url=/library/en-us/dllproc/base/setconsolemode.asp">SetConsoleMode</a> and
- * <a href="http://msdn.microsoft.com/library/default.asp?
- * url=/library/en-us/dllproc/base/getconsolemode.asp">GetConsoleMode</a> to
- * disable character echoing.
- * <p/>
- * <p>
- * By default, the {@link #readCharacter} method will attempt to test to see if
- * the specified {@link InputStream} is {@link System#in} or a wrapper around
- * {@link FileDescriptor#in}, and if so, will bypass the character reading to
- * directly invoke the readc() method in the JNI library. This is so the class
- * can read special keys (like arrow keys) which are otherwise inaccessible via
- * the {@link System#in} stream. Using JNI reading can be bypassed by setting
- * the <code>jline.WindowsTerminal.directConsole</code> system property
- * to <code>false</code>.
- * </p>
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public class WindowsTerminal
- extends TerminalSupport
-{
- public static final String JLINE_WINDOWS_TERMINAL_INPUT_ENCODING = "jline.WindowsTerminal.input.encoding";
-
- public static final String JLINE_WINDOWS_TERMINAL_OUTPUT_ENCODING = "jline.WindowsTerminal.output.encoding";
-
- public static final String JLINE_WINDOWS_TERMINAL_DIRECT_CONSOLE = "jline.WindowsTerminal.directConsole";
-
- public static final String WINDOWSBINDINGS_PROPERTIES = "windowsbindings.properties";
-
- public static final String ANSI = WindowsTerminal.class.getName() + ".ansi";
-
- private boolean directConsole;
-
- private int originalMode;
-
- private final ReplayPrefixOneCharInputStream replayStream;
-
- private final InputStreamReader replayReader;
-
- public WindowsTerminal() throws Exception {
- super(true);
-
- this.replayStream =
- new ReplayPrefixOneCharInputStream(Configuration.getString(JLINE_WINDOWS_TERMINAL_INPUT_ENCODING, Configuration.getFileEncoding()));
- this.replayReader = new InputStreamReader(replayStream, replayStream.getEncoding());
- }
-
- @Override
- public void init() throws Exception {
- super.init();
-
- setAnsiSupported(Boolean.getBoolean(ANSI));
-
- //
- // FIXME: Need a way to disable direct console and sysin detection muck
- //
-
- setDirectConsole(Boolean.getBoolean(JLINE_WINDOWS_TERMINAL_DIRECT_CONSOLE));
-
- this.originalMode = getConsoleMode();
- setConsoleMode(originalMode & ~ENABLE_ECHO_INPUT.code);
- setEchoEnabled(false);
- }
-
- /**
- * Restore the original terminal configuration, which can be used when
- * shutting down the console reader. The ConsoleReader cannot be
- * used after calling this method.
- */
- @Override
- public void restore() throws Exception {
- // restore the old console mode
- setConsoleMode(originalMode);
- super.restore();
- }
-
- @Override
- public int getWidth() {
- int w = getWindowsTerminalWidth();
- return w < 1 ? DEFAULT_WIDTH : w;
- }
-
- @Override
- public int getHeight() {
- int h = getWindowsTerminalHeight();
- return h < 1 ? DEFAULT_HEIGHT : h;
- }
-
- @Override
- public void setEchoEnabled(final boolean enabled) {
- // Must set these four modes at the same time to make it work fine.
- if (enabled) {
- setConsoleMode(getConsoleMode() |
- ENABLE_ECHO_INPUT.code |
- ENABLE_LINE_INPUT.code |
- ENABLE_PROCESSED_INPUT.code |
- ENABLE_WINDOW_INPUT.code);
- }
- else {
- setConsoleMode(getConsoleMode() &
- ~(ENABLE_LINE_INPUT.code |
- ENABLE_ECHO_INPUT.code |
- ENABLE_PROCESSED_INPUT.code |
- ENABLE_WINDOW_INPUT.code));
- }
- super.setEchoEnabled(enabled);
- }
-
- /**
- * Whether or not to allow the use of the JNI console interaction.
- */
- public void setDirectConsole(final boolean flag) {
- this.directConsole = flag;
- Log.debug("Direct console: ", flag);
- }
-
- /**
- * Whether or not to allow the use of the JNI console interaction.
- */
- public Boolean getDirectConsole() {
- return directConsole;
- }
-
-
- @Override
- public int readCharacter(final InputStream in) throws IOException {
- // if we can detect that we are directly wrapping the system
- // input, then bypass the input stream and read directly (which
- // allows us to access otherwise unreadable strokes, such as
- // the arrow keys)
-
- if (directConsole || isSystemIn(in)) {
- return readByte();
- }
- else {
- return super.readCharacter(in);
- }
- }
-
- private boolean isSystemIn(final InputStream in) throws IOException {
- assert in != null;
-
- if (in == System.in) {
- return true;
- }
- else if (in instanceof FileInputStream && ((FileInputStream) in).getFD() == FileDescriptor.in) {
- return true;
- }
-
- return false;
- }
-
- @Override
- public int readVirtualKey(final InputStream in) throws IOException {
- int indicator = readCharacter(in);
-
- // in Windows terminals, arrow keys are represented by
- // a sequence of 2 characters. E.g., the up arrow
- // key yields 224, 72
- if (indicator == SPECIAL_KEY_INDICATOR.code || indicator == NUMPAD_KEY_INDICATOR.code) {
- int c = readCharacter(in);
- WindowsKey key = WindowsKey.valueOf(c);
- if (key == null)
- return 0;
-
- switch (key) {
- case UP_ARROW_KEY:
- return CTRL_P.code; // translate UP -> CTRL-P
-
- case LEFT_ARROW_KEY:
- return CTRL_B.code; // translate LEFT -> CTRL-B
-
- case RIGHT_ARROW_KEY:
- return CTRL_F.code; // translate RIGHT -> CTRL-F
-
- case DOWN_ARROW_KEY:
- return CTRL_N.code; // translate DOWN -> CTRL-N
-
- case DELETE_KEY:
- return CTRL_QM.code; // translate DELETE -> CTRL-?
-
- case HOME_KEY:
- return CTRL_A.code;
-
- case END_KEY:
- return CTRL_E.code;
-
- case PAGE_UP_KEY:
- return CTRL_K.code;
-
- case PAGE_DOWN_KEY:
- return CTRL_L.code;
-
- case ESCAPE_KEY:
- return CTRL_OB.code; // translate ESCAPE -> CTRL-[
-
- case INSERT_KEY:
- return CTRL_C.code;
-
- default:
- return 0;
- }
- }
- else if (indicator > 128) {
- // handle unicode characters longer than 2 bytes,
- // thanks to Marc.Herbert@continuent.com
- replayStream.setInput(indicator, in);
- // replayReader = new InputStreamReader(replayStream, encoding);
- indicator = replayReader.read();
-
- }
-
- return indicator;
- }
-
- @Override
- public InputStream getDefaultBindings() {
- return WindowsTerminal.class.getResourceAsStream(WINDOWSBINDINGS_PROPERTIES);
- }
-
- //
- // Native Bits
- //
- private int getConsoleMode() {
- return WindowsSupport.getConsoleMode();
- }
-
- private void setConsoleMode(int mode) {
- WindowsSupport.setConsoleMode(mode);
- }
-
- private int readByte() {
- return WindowsSupport.readByte();
- }
-
- private int getWindowsTerminalWidth() {
- return WindowsSupport.getWindowsTerminalWidth();
- }
-
- private int getWindowsTerminalHeight() {
- return WindowsSupport.getWindowsTerminalHeight();
- }
-
- /**
- * Console mode
- * <p/>
- * Constants copied <tt>wincon.h</tt>.
- */
- public static enum ConsoleMode
- {
- /**
- * The ReadFile or ReadConsole function returns only when a carriage return
- * character is read. If this mode is disable, the functions return when one
- * or more characters are available.
- */
- ENABLE_LINE_INPUT(2),
-
- /**
- * Characters read by the ReadFile or ReadConsole function are written to
- * the active screen buffer as they are read. This mode can be used only if
- * the ENABLE_LINE_INPUT mode is also enabled.
- */
- ENABLE_ECHO_INPUT(4),
-
- /**
- * CTRL+C is processed by the system and is not placed in the input buffer.
- * If the input buffer is being read by ReadFile or ReadConsole, other
- * control keys are processed by the system and are not returned in the
- * ReadFile or ReadConsole buffer. If the ENABLE_LINE_INPUT mode is also
- * enabled, backspace, carriage return, and linefeed characters are handled
- * by the system.
- */
- ENABLE_PROCESSED_INPUT(1),
-
- /**
- * User interactions that change the size of the console screen buffer are
- * reported in the console's input buffee. Information about these events
- * can be read from the input buffer by applications using
- * theReadConsoleInput function, but not by those using ReadFile
- * orReadConsole.
- */
- ENABLE_WINDOW_INPUT(8),
-
- /**
- * If the mouse pointer is within the borders of the console window and the
- * window has the keyboard focus, mouse events generated by mouse movement
- * and button presses are placed in the input buffer. These events are
- * discarded by ReadFile or ReadConsole, even when this mode is enabled.
- */
- ENABLE_MOUSE_INPUT(16),
-
- /**
- * When enabled, text entered in a console window will be inserted at the
- * current cursor location and all text following that location will not be
- * overwritten. When disabled, all following text will be overwritten. An OR
- * operation must be performed with this flag and the ENABLE_EXTENDED_FLAGS
- * flag to enable this functionality.
- */
- ENABLE_PROCESSED_OUTPUT(1),
-
- /**
- * This flag enables the user to use the mouse to select and edit text. To
- * enable this option, use the OR to combine this flag with
- * ENABLE_EXTENDED_FLAGS.
- */
- ENABLE_WRAP_AT_EOL_OUTPUT(2),;
-
- public final int code;
-
- ConsoleMode(final int code) {
- this.code = code;
- }
- }
-
- /**
- * Windows keys.
- * <p/>
- * Constants copied <tt>wincon.h</tt>.
- */
- public static enum WindowsKey
- {
- /**
- * On windows terminals, this character indicates that a 'special' key has
- * been pressed. This means that a key such as an arrow key, or delete, or
- * home, etc. will be indicated by the next character.
- */
- SPECIAL_KEY_INDICATOR(224),
-
- /**
- * On windows terminals, this character indicates that a special key on the
- * number pad has been pressed.
- */
- NUMPAD_KEY_INDICATOR(0),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR,
- * this character indicates an left arrow key press.
- */
- LEFT_ARROW_KEY(75),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates an
- * right arrow key press.
- */
- RIGHT_ARROW_KEY(77),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates an up
- * arrow key press.
- */
- UP_ARROW_KEY(72),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates an
- * down arrow key press.
- */
- DOWN_ARROW_KEY(80),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates that
- * the delete key was pressed.
- */
- DELETE_KEY(83),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates that
- * the home key was pressed.
- */
- HOME_KEY(71),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates that
- * the end key was pressed.
- */
- END_KEY(79),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates that
- * the page up key was pressed.
- */
- PAGE_UP_KEY(73),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates that
- * the page down key was pressed.
- */
- PAGE_DOWN_KEY(81),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR
- * this character indicates that
- * the insert key was pressed.
- */
- INSERT_KEY(82),
-
- /**
- * When following the SPECIAL_KEY_INDICATOR or NUMPAD_KEY_INDICATOR,
- * this character indicates that the escape key was pressed.
- */
- ESCAPE_KEY(0),;
-
- public final int code;
-
- WindowsKey(final int code) {
- this.code = code;
- }
-
- private static final Map<Integer, WindowsKey> codes;
-
- static {
- Map<Integer, WindowsKey> map = new HashMap<Integer, WindowsKey>();
-
- for (WindowsKey key : WindowsKey.values()) {
- map.put(key.code, key);
- }
-
- codes = map;
- }
-
- public static WindowsKey valueOf(final int code) {
- return codes.get(code);
- }
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java b/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java
deleted file mode 100644
index a375b84a5c..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java
+++ /dev/null
@@ -1,2185 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console;
-
-import scala.tools.jline.Terminal;
-import scala.tools.jline.TerminalFactory;
-import scala.tools.jline.console.completer.CandidateListCompletionHandler;
-import scala.tools.jline.console.completer.Completer;
-import scala.tools.jline.console.completer.CompletionHandler;
-import scala.tools.jline.console.history.History;
-import scala.tools.jline.console.history.MemoryHistory;
-import scala.tools.jline.internal.Configuration;
-import scala.tools.jline.internal.Log;
-import org.fusesource.jansi.AnsiOutputStream;
-
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.awt.event.ActionListener;
-import java.io.*;
-import java.util.*;
-
-/**
- * A reader for console applications. It supports custom tab-completion,
- * saveable command history, and command line editing. On some platforms,
- * platform-specific commands will need to be issued before the reader will
- * function properly. See {@link jline.Terminal#init} for convenience
- * methods for issuing platform-specific setup commands.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- */
-public class ConsoleReader
-{
- public static final String JLINE_NOBELL = "jline.nobell";
-
- public static final String JLINE_EXPANDEVENTS = "jline.expandevents";
-
- public static final char BACKSPACE = '\b';
-
- public static final char RESET_LINE = '\r';
-
- public static final char KEYBOARD_BELL = '\07';
-
- public static final char NULL_MASK = 0;
-
- public static final int TAB_WIDTH = 4;
-
- private static final ResourceBundle
- resources = ResourceBundle.getBundle(CandidateListCompletionHandler.class.getName());
-
- private final Terminal terminal;
-
- private InputStream in;
-
- private final Writer out;
-
- private final CursorBuffer buf = new CursorBuffer();
-
- private String prompt;
-
- private boolean bellEnabled = true;
-
- private boolean expandEvents = false;
-
- private Character mask;
-
- private Character echoCharacter;
-
- private StringBuffer searchTerm = null;
-
- private String previousSearchTerm = "";
-
- private int searchIndex = -1;
-
- public ConsoleReader(final InputStream in, final OutputStream out, final InputStream bindings, final Terminal term) throws
- IOException
- {
- this.in = in;
- this.terminal = term != null ? term : TerminalFactory.get();
- this.out = new PrintWriter(getTerminal().wrapOutIfNeeded(out));
- this.keyBindings = loadKeyBindings(bindings);
-
- setBellEnabled(!Configuration.getBoolean(JLINE_NOBELL, false));
- setExpandEvents(Configuration.getBoolean(JLINE_EXPANDEVENTS, false));
- }
-
- /**
- * @deprecated use {@link #ConsoleReader(InputStream, OutputStream, InputStream, Terminal)}
- * to let the terminal wrap the output stream if needed.
- */
- public ConsoleReader(final InputStream in, final Writer out, final InputStream bindings, final Terminal term) throws
- IOException
- {
- this.in = in;
- this.out = out;
- this.terminal = term != null ? term : TerminalFactory.get();
- this.keyBindings = loadKeyBindings(bindings);
-
- setBellEnabled(!Configuration.getBoolean(JLINE_NOBELL, false));
- }
-
- /**
- * @deprecated use {@link #ConsoleReader(InputStream, OutputStream, InputStream, Terminal)}
- * to let the terminal wrap the output stream if needed.
- */
- public ConsoleReader(final InputStream in, final Writer out, final Terminal term) throws IOException {
- this(in, out, null, term);
- }
-
- /**
- * @deprecated use {@link #ConsoleReader(InputStream, OutputStream, InputStream, Terminal)}
- * to let the terminal wrap the output stream if needed.
- */
- public ConsoleReader(final InputStream in, final Writer out) throws IOException
- {
- this(in, out, null, null);
- }
-
- /**
- * Create a new reader using {@link FileDescriptor#in} for input and
- * {@link System#out} for output.
- * <p/>
- * {@link FileDescriptor#in} is used because it has a better chance of not being buffered.
- */
- public ConsoleReader() throws IOException {
- this(new FileInputStream(FileDescriptor.in), System.out, null, null );
- }
-
- // FIXME: Only used for tests
-
- void setInput(final InputStream in) {
- this.in = in;
- }
-
- public InputStream getInput() {
- return in;
- }
-
- public Writer getOutput() {
- return out;
- }
-
- public Terminal getTerminal() {
- return terminal;
- }
-
- public CursorBuffer getCursorBuffer() {
- return buf;
- }
-
- public void setBellEnabled(final boolean enabled) {
- this.bellEnabled = enabled;
- }
-
- public boolean isBellEnabled() {
- return bellEnabled;
- }
-
- public void setExpandEvents(final boolean expand) {
- this.expandEvents = expand;
- }
-
- public boolean getExpandEvents() {
- return expandEvents;
- }
-
- public void setPrompt(final String prompt) {
- this.prompt = prompt;
- }
-
- public String getPrompt() {
- return prompt;
- }
-
- /**
- * Set the echo character. For example, to have "*" entered when a password is typed:
- * <p/>
- * <pre>
- * myConsoleReader.setEchoCharacter(new Character('*'));
- * </pre>
- * <p/>
- * Setting the character to
- * <p/>
- * <pre>
- * null
- * </pre>
- * <p/>
- * will restore normal character echoing. Setting the character to
- * <p/>
- * <pre>
- * new Character(0)
- * </pre>
- * <p/>
- * will cause nothing to be echoed.
- *
- * @param c the character to echo to the console in place of the typed character.
- */
- public void setEchoCharacter(final Character c) {
- this.echoCharacter = c;
- }
-
- /**
- * Returns the echo character.
- */
- public Character getEchoCharacter() {
- return echoCharacter;
- }
-
- /**
- * Erase the current line.
- *
- * @return false if we failed (e.g., the buffer was empty)
- */
- protected final boolean resetLine() throws IOException {
- if (buf.cursor == 0) {
- return false;
- }
-
- backspaceAll();
-
- return true;
- }
-
- int getCursorPosition() {
- // FIXME: does not handle anything but a line with a prompt absolute position
- String prompt = getPrompt();
- return ((prompt == null) ? 0 : stripAnsi(lastLine(prompt)).length()) + buf.cursor;
- }
-
- /**
- * Returns the text after the last '\n'.
- * prompt is returned if no '\n' characters are present.
- * null is returned if prompt is null.
- */
- private String lastLine(String str) {
- if (str == null) return "";
- int last = str.lastIndexOf("\n");
-
- if (last >= 0) {
- return str.substring(last + 1, str.length());
- }
-
- return str;
- }
-
- private String stripAnsi(String str) {
- if (str == null) return "";
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- AnsiOutputStream aos = new AnsiOutputStream(baos);
- aos.write(str.getBytes());
- aos.flush();
- return baos.toString();
- } catch (IOException e) {
- return str;
- }
- }
-
- /**
- * Move the cursor position to the specified absolute index.
- */
- public final boolean setCursorPosition(final int position) throws IOException {
- return moveCursor(position - buf.cursor) != 0;
- }
-
- /**
- * Set the current buffer's content to the specified {@link String}. The
- * visual console will be modified to show the current buffer.
- *
- * @param buffer the new contents of the buffer.
- */
- private void setBuffer(final String buffer) throws IOException {
- // don't bother modifying it if it is unchanged
- if (buffer.equals(buf.buffer.toString())) {
- return;
- }
-
- // obtain the difference between the current buffer and the new one
- int sameIndex = 0;
-
- for (int i = 0, l1 = buffer.length(), l2 = buf.buffer.length(); (i < l1)
- && (i < l2); i++) {
- if (buffer.charAt(i) == buf.buffer.charAt(i)) {
- sameIndex++;
- }
- else {
- break;
- }
- }
-
- int diff = buf.cursor - sameIndex;
- if (diff < 0) { // we can't backspace here so try from the end of the buffer
- moveToEnd();
- diff = buf.buffer.length() - sameIndex;
- }
-
- backspace(diff); // go back for the differences
- killLine(); // clear to the end of the line
- buf.buffer.setLength(sameIndex); // the new length
- putString(buffer.substring(sameIndex)); // append the differences
- }
-
- private void setBuffer(final CharSequence buffer) throws IOException {
- setBuffer(String.valueOf(buffer));
- }
-
- /**
- * Output put the prompt + the current buffer
- */
- public final void drawLine() throws IOException {
- String prompt = getPrompt();
- if (prompt != null) {
- print(prompt);
- }
-
- print(buf.buffer.toString());
-
- if (buf.length() != buf.cursor) { // not at end of line
- back(buf.length() - buf.cursor - 1);
- }
- // force drawBuffer to check for weird wrap (after clear screen)
- drawBuffer();
- }
-
- /**
- * Clear the line and redraw it.
- */
- public final void redrawLine() throws IOException {
- print(RESET_LINE);
-// flush();
- drawLine();
- }
-
- /**
- * Clear the buffer and add its contents to the history.
- *
- * @return the former contents of the buffer.
- */
- final String finishBuffer() throws IOException { // FIXME: Package protected because used by tests
- String str = buf.buffer.toString();
-
- if (expandEvents) {
- str = expandEvents(str);
- }
-
- // we only add it to the history if the buffer is not empty
- // and if mask is null, since having a mask typically means
- // the string was a password. We clear the mask after this call
- if (str.length() > 0) {
- if (mask == null && isHistoryEnabled()) {
- history.add(str);
- }
- else {
- mask = null;
- }
- }
-
- history.moveToEnd();
-
- buf.buffer.setLength(0);
- buf.cursor = 0;
-
- return str;
- }
-
- /**
- * Expand event designator such as !!, !#, !3, etc...
- * See http://www.gnu.org/software/bash/manual/html_node/Event-Designators.html
- *
- * @param str
- * @return
- */
- protected String expandEvents(String str) throws IOException {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < str.length(); i++) {
- char c = str.charAt(i);
- switch (c) {
- case '!':
- if (i + 1 < str.length()) {
- c = str.charAt(++i);
- boolean neg = false;
- String rep = null;
- int i1, idx;
- switch (c) {
- case '!':
- if (history.size() == 0) {
- throw new IllegalArgumentException("!!: event not found");
- }
- rep = history.get(history.index() - 1).toString();
- break;
- case '#':
- sb.append(sb.toString());
- break;
- case '?':
- i1 = str.indexOf('?', i + 1);
- if (i1 < 0) {
- i1 = str.length();
- }
- String sc = str.substring(i + 1, i1);
- i = i1;
- idx = searchBackwards(sc);
- if (idx < 0) {
- throw new IllegalArgumentException("!?" + sc + ": event not found");
- } else {
- rep = history.get(idx).toString();
- }
- break;
- case ' ':
- case '\t':
- sb.append('!');
- sb.append(c);
- break;
- case '-':
- neg = true;
- i++;
- // fall through
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- i1 = i;
- for (; i < str.length(); i++) {
- c = str.charAt(i);
- if (c < '0' || c > '9') {
- break;
- }
- }
- idx = 0;
- try {
- idx = Integer.parseInt(str.substring(i1, i));
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException((neg ? "!-" : "!") + str.substring(i1, i) + ": event not found");
- }
- if (neg) {
- if (idx < history.size()) {
- rep = (history.get(history.index() - idx)).toString();
- } else {
- throw new IllegalArgumentException((neg ? "!-" : "!") + str.substring(i1, i) + ": event not found");
- }
- } else {
- if (idx >= history.index() - history.size() && idx < history.index()) {
- rep = (history.get(idx)).toString();
- } else {
- throw new IllegalArgumentException((neg ? "!-" : "!") + str.substring(i1, i) + ": event not found");
- }
- }
- break;
- default:
- String ss = str.substring(i);
- i = str.length();
- idx = searchBackwards(ss, history.index(), true);
- if (idx < 0) {
- throw new IllegalArgumentException("!" + ss + ": event not found");
- } else {
- rep = history.get(idx).toString();
- }
- break;
- }
- if (rep != null) {
- sb.append(rep);
- }
- } else {
- sb.append(c);
- }
- break;
- case '^':
- if (i == 0) {
- int i1 = str.indexOf('^', i + 1);
- int i2 = str.indexOf('^', i1 + 1);
- if (i2 < 0) {
- i2 = str.length();
- }
- if (i1 > 0 && i2 > 0) {
- String s1 = str.substring(i + 1, i1);
- String s2 = str.substring(i1 + 1, i2);
- String s = history.get(history.index() - 1).toString().replace(s1, s2);
- sb.append(s);
- i = i2 + 1;
- break;
- }
- }
- sb.append(c);
- break;
- default:
- sb.append(c);
- break;
- }
- }
- String result = sb.toString();
- if (!str.equals(result)) {
- print(result);
- println();
- flush();
- }
- return result;
-
- }
-
- /**
- * Write out the specified string to the buffer and the output stream.
- */
- public final void putString(final CharSequence str) throws IOException {
- buf.write(str);
- print(str);
- drawBuffer();
- }
-
- /**
- * Output the specified character, both to the buffer and the output stream.
- */
- private void putChar(final int c, final boolean print) throws IOException {
- buf.write((char) c);
-
- if (print) {
- if (mask == null) {
- // no masking
- print(c);
- }
- else if (mask == NULL_MASK) {
- // Don't print anything
- }
- else {
- print(mask);
- }
-
- drawBuffer();
- }
- }
-
- /**
- * Redraw the rest of the buffer from the cursor onwards. This is necessary
- * for inserting text into the buffer.
- *
- * @param clear the number of characters to clear after the end of the buffer
- */
- private void drawBuffer(final int clear) throws IOException {
- // debug ("drawBuffer: " + clear);
- if (buf.cursor == buf.length() && clear == 0) {
- } else {
- char[] chars = buf.buffer.substring(buf.cursor).toCharArray();
- if (mask != null) {
- Arrays.fill(chars, mask);
- }
- if (getTerminal().hasWeirdWrap()) {
- // need to determine if wrapping will occur:
- int width = getTerminal().getWidth();
- int pos = getCursorPosition();
- for (int i = 0; i < chars.length; i++) {
- print(chars[i]);
- if ((pos + i + 1) % width == 0) {
- print(32); // move cursor to next line by printing dummy space
- print(13); // CR / not newline.
- }
- }
- } else {
- print(chars);
- }
- clearAhead(clear, chars.length);
- if (getTerminal().isAnsiSupported()) {
- if (chars.length > 0) {
- back(chars.length);
- }
- } else {
- back(chars.length);
- }
- }
- if (getTerminal().hasWeirdWrap()) {
- int width = getTerminal().getWidth();
- // best guess on whether the cursor is in that weird location...
- // Need to do this without calling ansi cursor location methods
- // otherwise it breaks paste of wrapped lines in xterm.
- if (getCursorPosition() > 0 && (getCursorPosition() % width == 0)
- && buf.cursor == buf.length() && clear == 0) {
- // the following workaround is reverse-engineered from looking
- // at what bash sent to the terminal in the same situation
- print(32); // move cursor to next line by printing dummy space
- print(13); // CR / not newline.
- }
- }
- }
-
- /**
- * Redraw the rest of the buffer from the cursor onwards. This is necessary
- * for inserting text into the buffer.
- */
- private void drawBuffer() throws IOException {
- drawBuffer(0);
- }
-
- /**
- * Clear ahead the specified number of characters without moving the cursor.
- *
- * @param num the number of characters to clear
- * @param delta the difference between the internal cursor and the screen
- * cursor - if > 0, assume some stuff was printed and weird wrap has to be
- * checked
- */
- private void clearAhead(final int num, int delta) throws IOException {
- if (num == 0) {
- return;
- }
-
- if (getTerminal().isAnsiSupported()) {
- int width = getTerminal().getWidth();
- int screenCursorCol = getCursorPosition() + delta;
- // clear current line
- printAnsiSequence("K");
- // if cursor+num wraps, then we need to clear the line(s) below too
- int curCol = screenCursorCol % width;
- int endCol = (screenCursorCol + num - 1) % width;
- int lines = num / width;
- if (endCol < curCol) lines++;
- for (int i = 0; i < lines; i++) {
- printAnsiSequence("B");
- printAnsiSequence("2K");
- }
- for (int i = 0; i < lines; i++) {
- printAnsiSequence("A");
- }
- return;
- }
-
- // print blank extra characters
- print(' ', num);
-
- // we need to flush here so a "clever" console doesn't just ignore the redundancy
- // of a space followed by a backspace.
-// flush();
-
- // reset the visual cursor
- back(num);
-
-// flush();
- }
-
- /**
- * Move the visual cursor backwards without modifying the buffer cursor.
- */
- protected void back(final int num) throws IOException {
- if (num == 0) return;
- if (getTerminal().isAnsiSupported()) {
- int width = getTerminal().getWidth();
- int cursor = getCursorPosition();
- int realCursor = cursor + num;
- int realCol = realCursor % width;
- int newCol = cursor % width;
- int moveup = num / width;
- int delta = realCol - newCol;
- if (delta < 0) moveup++;
- if (moveup > 0) {
- printAnsiSequence(moveup + "A");
- }
- printAnsiSequence((1 + newCol) + "G");
- return;
- }
- print(BACKSPACE, num);
-// flush();
- }
-
- /**
- * Flush the console output stream. This is important for printout out single characters (like a backspace or
- * keyboard) that we want the console to handle immediately.
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- private int backspaceAll() throws IOException {
- return backspace(Integer.MAX_VALUE);
- }
-
- /**
- * Issue <em>num</em> backspaces.
- *
- * @return the number of characters backed up
- */
- private int backspace(final int num) throws IOException {
- if (buf.cursor == 0) {
- return 0;
- }
-
- int count = 0;
-
- int termwidth = getTerminal().getWidth();
- int lines = getCursorPosition() / termwidth;
- count = moveCursor(-1 * num) * -1;
- buf.buffer.delete(buf.cursor, buf.cursor + count);
- if (getCursorPosition() / termwidth != lines) {
- if (getTerminal().isAnsiSupported()) {
- // debug("doing backspace redraw: " + getCursorPosition() + " on " + termwidth + ": " + lines);
- printAnsiSequence("K");
- // if cursor+num wraps, then we need to clear the line(s) below too
- // last char printed is one pos less than cursor so we subtract
- // one
-/*
- // TODO: fixme (does not work - test with reverse search with wrapping line and CTRL-E)
- int endCol = (getCursorPosition() + num - 1) % termwidth;
- int curCol = getCursorPosition() % termwidth;
- if (endCol < curCol) lines++;
- for (int i = 1; i < lines; i++) {
- printAnsiSequence("B");
- printAnsiSequence("2K");
- }
- for (int i = 1; i < lines; i++) {
- printAnsiSequence("A");
- }
- return count;
-*/
- }
- }
- drawBuffer(count);
-
- return count;
- }
-
- /**
- * Issue a backspace.
- *
- * @return true if successful
- */
- public boolean backspace() throws IOException {
- return backspace(1) == 1;
- }
-
- protected boolean moveToEnd() throws IOException {
- return moveCursor(buf.length() - buf.cursor) > 0;
- }
-
- /**
- * Delete the character at the current position and redraw the remainder of the buffer.
- */
- private boolean deleteCurrentCharacter() throws IOException {
- if (buf.length() == 0 || buf.cursor == buf.length()) {
- return false;
- }
-
- buf.buffer.deleteCharAt(buf.cursor);
- drawBuffer(1);
- return true;
- }
-
- private boolean previousWord() throws IOException {
- while (isDelimiter(buf.charLeftOfCursor()) && (moveCursor(-1) != 0)) {
- // nothing
- }
-
- while (!isDelimiter(buf.charLeftOfCursor()) && (moveCursor(-1) != 0)) {
- // nothing
- }
-
- return true;
- }
-
- private boolean nextWord() throws IOException {
- while (isDelimiter(buf.charAtCursor()) && (moveCursor(1) != 0)) {
- // nothing
- }
-
- while (!isDelimiter(buf.charAtCursor()) && (moveCursor(1) != 0)) {
- // nothing
- }
-
- return true;
- }
-
- private boolean deletePreviousWord() throws IOException {
- while (isDelimiter(buf.charLeftOfCursor()) && backspace()) {
- // nothing
- }
-
- while (!isDelimiter(buf.charLeftOfCursor()) && backspace()) {
- // nothing
- }
-
- return true;
- }
-
- private boolean deleteNextWord() throws IOException {
- while (isDelimiter(buf.charAtCursor()) && deleteCurrentCharacter()) {
- // nothing
- }
-
- while (!isDelimiter(buf.charAtCursor()) && deleteCurrentCharacter()) {
- // nothing
- }
-
- return true;
- }
-
- /**
- * Move the cursor <i>where</i> characters.
- *
- * @param num If less than 0, move abs(<i>where</i>) to the left, otherwise move <i>where</i> to the right.
- * @return The number of spaces we moved
- */
- public int moveCursor(final int num) throws IOException {
- int where = num;
-
- if ((buf.cursor == 0) && (where <= 0)) {
- return 0;
- }
-
- if ((buf.cursor == buf.buffer.length()) && (where >= 0)) {
- return 0;
- }
-
- if ((buf.cursor + where) < 0) {
- where = -buf.cursor;
- }
- else if ((buf.cursor + where) > buf.buffer.length()) {
- where = buf.buffer.length() - buf.cursor;
- }
-
- moveInternal(where);
-
- return where;
- }
-
- /**
- * Move the cursor <i>where</i> characters, without checking the current buffer.
- *
- * @param where the number of characters to move to the right or left.
- */
- private void moveInternal(final int where) throws IOException {
- // debug ("move cursor " + where + " ("
- // + buf.cursor + " => " + (buf.cursor + where) + ")");
- buf.cursor += where;
-
- if (getTerminal().isAnsiSupported()) {
- if (where < 0) {
- back(Math.abs(where));
- } else {
- int width = getTerminal().getWidth();
- int cursor = getCursorPosition();
- int oldLine = (cursor - where) / width;
- int newLine = cursor / width;
- if (newLine > oldLine) {
- if (getTerminal().hasWeirdWrap()) {
- // scroll up if at bottom
- // note:
- // on rxvt cywgin getTerminal().getHeight() is incorrect
- // MacOs xterm does not seem to support scrolling
- if (getCurrentAnsiRow() == getTerminal().getHeight()) {
- printAnsiSequence((newLine - oldLine) + "S");
- }
- }
- printAnsiSequence((newLine - oldLine) + "B");
- }
- printAnsiSequence(1 +(cursor % width) + "G");
- }
-// flush();
- return;
- }
-
- char c;
-
- if (where < 0) {
- int len = 0;
- for (int i = buf.cursor; i < buf.cursor - where; i++) {
- if (buf.buffer.charAt(i) == '\t') {
- len += TAB_WIDTH;
- }
- else {
- len++;
- }
- }
-
- char chars[] = new char[len];
- Arrays.fill(chars, BACKSPACE);
- out.write(chars);
-
- return;
- }
- else if (buf.cursor == 0) {
- return;
- }
- else if (mask != null) {
- c = mask;
- }
- else {
- print(buf.buffer.substring(buf.cursor - where, buf.cursor).toCharArray());
- return;
- }
-
- // null character mask: don't output anything
- if (mask == NULL_MASK) {
- return;
- }
-
- print(c, Math.abs(where));
- }
-
- // FIXME: replace() is not used
-
- public final boolean replace(final int num, final String replacement) {
- buf.buffer.replace(buf.cursor - num, buf.cursor, replacement);
- try {
- moveCursor(-num);
- drawBuffer(Math.max(0, num - replacement.length()));
- moveCursor(replacement.length());
- }
- catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- return true;
- }
-
- //
- // Key reading
- //
-
- /**
- * Read a character from the console.
- *
- * @return the character, or -1 if an EOF is received.
- */
- public final int readVirtualKey() throws IOException {
- int c = getTerminal().readVirtualKey(in);
-
- Log.trace("Keystroke: ", c);
-
- // clear any echo characters
- clearEcho(c);
-
- return c;
- }
-
- /**
- * Clear the echoed characters for the specified character code.
- */
- private int clearEcho(final int c) throws IOException {
- // if the terminal is not echoing, then ignore
- if (!getTerminal().isEchoEnabled()) {
- return 0;
- }
-
- // otherwise, clear
- int num = countEchoCharacters((char) c);
- back(num);
- drawBuffer(num);
-
- return num;
- }
-
- private int countEchoCharacters(final char c) {
- // tabs as special: we need to determine the number of spaces
- // to cancel based on what out current cursor position is
- if (c == 9) {
- int tabStop = 8; // will this ever be different?
- int position = getCursorPosition();
-
- return tabStop - (position % tabStop);
- }
-
- return getPrintableCharacters(c).length();
- }
-
- /**
- * Return the number of characters that will be printed when the specified
- * character is echoed to the screen
- *
- * Adapted from cat by Torbjorn Granlund, as repeated in stty by David MacKenzie.
- */
- private StringBuilder getPrintableCharacters(final char ch) {
- StringBuilder sbuff = new StringBuilder();
-
- if (ch >= 32) {
- if (ch < 127) {
- sbuff.append(ch);
- }
- else if (ch == 127) {
- sbuff.append('^');
- sbuff.append('?');
- }
- else {
- sbuff.append('M');
- sbuff.append('-');
-
- if (ch >= (128 + 32)) {
- if (ch < (128 + 127)) {
- sbuff.append((char) (ch - 128));
- }
- else {
- sbuff.append('^');
- sbuff.append('?');
- }
- }
- else {
- sbuff.append('^');
- sbuff.append((char) (ch - 128 + 64));
- }
- }
- }
- else {
- sbuff.append('^');
- sbuff.append((char) (ch + 64));
- }
-
- return sbuff;
- }
-
- public final int readCharacter(final char... allowed) throws IOException {
- // if we restrict to a limited set and the current character is not in the set, then try again.
- char c;
-
- Arrays.sort(allowed); // always need to sort before binarySearch
-
- while (Arrays.binarySearch(allowed, c = (char) readVirtualKey()) < 0) {
- // nothing
- }
-
- return c;
- }
-
- //
- // Key Bindings
- //
-
- public static final String JLINE_COMPLETION_THRESHOLD = "jline.completion.threshold";
-
- public static final String JLINE_KEYBINDINGS = "jline.keybindings";
-
- public static final String JLINEBINDINGS_PROPERTIES = ".jlinebindings.properties";
-
- /**
- * The map for logical operations.
- */
- private final short[] keyBindings;
-
- private short[] loadKeyBindings(InputStream input) throws IOException {
- if (input == null) {
- try {
- File file = new File(Configuration.getUserHome(), JLINEBINDINGS_PROPERTIES);
-
- String path = Configuration.getString(JLINE_KEYBINDINGS);
- if (path != null) {
- file = new File(path);
- }
-
- if (file.isFile()) {
- Log.debug("Loading user bindings from: ", file);
- input = new FileInputStream(file);
- }
- }
- catch (Exception e) {
- Log.error("Failed to load user bindings", e);
- }
- }
-
- if (input == null) {
- Log.debug("Using default bindings");
- input = getTerminal().getDefaultBindings();
- }
-
- short[] keyBindings = new short[Character.MAX_VALUE * 2];
-
- Arrays.fill(keyBindings, Operation.UNKNOWN.code);
-
- // Loads the key bindings. Bindings file is in the format:
- //
- // keycode: operation name
-
- if (input != null) {
- input = new BufferedInputStream(input);
- Properties p = new Properties();
- p.load(input);
- input.close();
-
- for (Object key : p.keySet()) {
- String val = (String) key;
-
- try {
- short code = Short.parseShort(val);
- String name = p.getProperty(val);
- Operation op = Operation.valueOf(name);
- keyBindings[code] = op.code;
- }
- catch (NumberFormatException e) {
- Log.error("Failed to convert binding code: ", val, e);
- }
- }
-
- // hardwired arrow key bindings
- // keybindings[VK_UP] = PREV_HISTORY;
- // keybindings[VK_DOWN] = NEXT_HISTORY;
- // keybindings[VK_LEFT] = PREV_CHAR;
- // keybindings[VK_RIGHT] = NEXT_CHAR;
- }
-
- return keyBindings;
- }
-
- int getKeyForAction(final short logicalAction) {
- for (int i = 0; i < keyBindings.length; i++) {
- if (keyBindings[i] == logicalAction) {
- return i;
- }
- }
-
- return -1;
- }
-
- int getKeyForAction(final Operation op) {
- assert op != null;
- return getKeyForAction(op.code);
- }
-
- public void printBindings() {
- System.out.println("printBindings(): keyBindings.length = " + keyBindings.length);
- for (int i = 0; i < keyBindings.length; i++) {
- if (keyBindings[i] != Operation.UNKNOWN.code) {
- System.out.println("keyBindings[" + i + "] = " + keyBindings[i]);
- }
- }
- }
-
- /**
- * Reads the console input and returns an array of the form [raw, key binding].
- */
- private int[] readBinding() throws IOException {
- int c = readVirtualKey();
-
- if (c == -1) {
- return null;
- }
-
- // extract the appropriate key binding
- short code = keyBindings[c];
-
- Log.trace("Translated: ", c, " -> ", code);
-
- return new int[]{c, code};
- }
-
- //
- // Line Reading
- //
-
- /**
- * Read the next line and return the contents of the buffer.
- */
- public String readLine() throws IOException {
- return readLine((String) null);
- }
-
- /**
- * Read the next line with the specified character mask. If null, then
- * characters will be echoed. If 0, then no characters will be echoed.
- */
- public String readLine(final Character mask) throws IOException {
- return readLine(null, mask);
- }
-
- public String readLine(final String prompt) throws IOException {
- return readLine(prompt, null);
- }
-
- /**
- * Read a line from the <i>in</i> {@link InputStream}, and return the line
- * (without any trailing newlines).
- *
- * @param prompt The prompt to issue to the console, may be null.
- * @return A line that is read from the terminal, or null if there was null input (e.g., <i>CTRL-D</i>
- * was pressed).
- */
- public String readLine(String prompt, final Character mask) throws IOException {
- // prompt may be null
- // mask may be null
-
- // FIXME: This blows, each call to readLine will reset the console's state which doesn't seem very nice.
- this.mask = mask;
- if (prompt != null) {
- setPrompt(prompt);
- }
- else {
- prompt = getPrompt();
- }
-
- try {
- if (!getTerminal().isSupported()) {
- beforeReadLine(prompt, mask);
- }
-
- if (prompt != null && prompt.length() > 0) {
- out.write(prompt);
- out.flush();
- }
-
- // if the terminal is unsupported, just use plain-java reading
- if (!getTerminal().isSupported()) {
- return readLine(in);
- }
-
- String originalPrompt = this.prompt;
-
- final int NORMAL = 1;
- final int SEARCH = 2;
- int state = NORMAL;
-
- boolean success = true;
-
- while (true) {
- int[] next = readBinding();
-
- if (next == null) {
- return null;
- }
-
- int c = next[0];
- // int code = next[1];
- Operation code = Operation.valueOf(next[1]);
-
- if (c == -1) {
- return null;
- }
-
- // Search mode.
- //
- // Note that we have to do this first, because if there is a command
- // not linked to a search command, we leave the search mode and fall
- // through to the normal state.
- if (state == SEARCH) {
- int cursorDest = -1;
-
- switch (code) {
- // This doesn't work right now, it seems CTRL-G is not passed
- // down correctly. :(
- case ABORT:
- state = NORMAL;
- break;
-
- case SEARCH_PREV:
- if (searchTerm.length() == 0) {
- searchTerm.append(previousSearchTerm);
- }
-
- if (searchIndex == -1) {
- searchIndex = searchBackwards(searchTerm.toString());
- } else {
- searchIndex = searchBackwards(searchTerm.toString(), searchIndex);
- }
- break;
-
- case DELETE_PREV_CHAR:
- if (searchTerm.length() > 0) {
- searchTerm.deleteCharAt(searchTerm.length() - 1);
- searchIndex = searchBackwards(searchTerm.toString());
- }
- break;
-
- case UNKNOWN:
- searchTerm.appendCodePoint(c);
- searchIndex = searchBackwards(searchTerm.toString());
- break;
-
- default:
- // Set buffer and cursor position to the found string.
- if (searchIndex != -1) {
- history.moveTo(searchIndex);
- // set cursor position to the found string
- cursorDest = history.current().toString().indexOf(searchTerm.toString());
- }
- state = NORMAL;
- break;
- }
-
- // if we're still in search mode, print the search status
- if (state == SEARCH) {
- if (searchTerm.length() == 0) {
- printSearchStatus("", "");
- searchIndex = -1;
- } else {
- if (searchIndex == -1) {
- beep();
- } else {
- printSearchStatus(searchTerm.toString(), history.get(searchIndex).toString());
- }
- }
- }
- // otherwise, restore the line
- else {
- restoreLine(originalPrompt, cursorDest);
- }
- }
-
- if (state == NORMAL) {
- switch (code) {
- case EXIT: // ctrl-d
- if (buf.buffer.length() == 0) {
- return null;
- } else {
- success = deleteCurrentCharacter();
- }
- break;
-
- case COMPLETE: // tab
- success = complete();
- break;
-
- case MOVE_TO_BEG:
- success = setCursorPosition(0);
- break;
-
- case KILL_LINE: // CTRL-K
- success = killLine();
- break;
-
- case CLEAR_SCREEN: // CTRL-L
- success = clearScreen();
- break;
-
- case KILL_LINE_PREV: // CTRL-U
- success = resetLine();
- break;
-
- case NEWLINE: // enter
- moveToEnd();
- println(); // output newline
- flush();
- return finishBuffer();
-
- case DELETE_PREV_CHAR: // backspace
- success = backspace();
- break;
-
- case DELETE_NEXT_CHAR: // delete
- success = deleteCurrentCharacter();
- break;
-
- case MOVE_TO_END:
- success = moveToEnd();
- break;
-
- case PREV_CHAR:
- success = moveCursor(-1) != 0;
- break;
-
- case NEXT_CHAR:
- success = moveCursor(1) != 0;
- break;
-
- case NEXT_HISTORY:
- success = moveHistory(true);
- break;
-
- case PREV_HISTORY:
- success = moveHistory(false);
- break;
-
- case ABORT:
- case REDISPLAY:
- break;
-
- case PASTE:
- success = paste();
- break;
-
- case DELETE_PREV_WORD:
- success = deletePreviousWord();
- break;
-
- case DELETE_NEXT_WORD:
- success = deleteNextWord();
- break;
-
- case PREV_WORD:
- success = previousWord();
- break;
-
- case NEXT_WORD:
- success = nextWord();
- break;
-
- case START_OF_HISTORY:
- success = history.moveToFirst();
- if (success) {
- setBuffer(history.current());
- }
- break;
-
- case END_OF_HISTORY:
- success = history.moveToLast();
- if (success) {
- setBuffer(history.current());
- }
- break;
-
- case CLEAR_LINE:
- moveInternal(-(buf.cursor));
- killLine();
- break;
-
- case INSERT:
- buf.setOverTyping(!buf.isOverTyping());
- break;
-
- case SEARCH_PREV: // CTRL-R
- if (searchTerm != null) {
- previousSearchTerm = searchTerm.toString();
- }
- searchTerm = new StringBuffer(buf.buffer);
- state = SEARCH;
- if (searchTerm.length() > 0) {
- searchIndex = searchBackwards(searchTerm.toString());
- if (searchIndex == -1) {
- beep();
- }
- printSearchStatus(searchTerm.toString(),
- searchIndex > -1 ? history.get(searchIndex).toString() : "");
- } else {
- searchIndex = -1;
- printSearchStatus("", "");
- }
- break;
-
- case UNKNOWN:
- default:
- if (c != 0) { // ignore null chars
- ActionListener action = triggeredActions.get((char) c);
- if (action != null) {
- action.actionPerformed(null);
- }
- else {
- putChar(c, true);
- }
- }
- else {
- success = false;
- }
- }
-
- if (!success) {
- beep();
- }
-
- flush();
- }
- }
- }
- finally {
- if (!getTerminal().isSupported()) {
- afterReadLine();
- }
- }
- }
-
- /**
- * Read a line for unsupported terminals.
- */
- private String readLine(final InputStream in) throws IOException {
- StringBuilder buff = new StringBuilder();
-
- while (true) {
- int i = in.read();
-
- if (i == -1 || i == '\n' || i == '\r') {
- return buff.toString();
- }
-
- buff.append((char) i);
- }
-
- // return new BufferedReader (new InputStreamReader (in)).readLine ();
- }
-
- //
- // Completion
- //
-
- private final List<Completer> completers = new LinkedList<Completer>();
-
- private CompletionHandler completionHandler = new CandidateListCompletionHandler();
-
- /**
- * Add the specified {@link jline.console.completer.Completer} to the list of handlers for tab-completion.
- *
- * @param completer the {@link jline.console.completer.Completer} to add
- * @return true if it was successfully added
- */
- public boolean addCompleter(final Completer completer) {
- return completers.add(completer);
- }
-
- /**
- * Remove the specified {@link jline.console.completer.Completer} from the list of handlers for tab-completion.
- *
- * @param completer The {@link Completer} to remove
- * @return True if it was successfully removed
- */
- public boolean removeCompleter(final Completer completer) {
- return completers.remove(completer);
- }
-
- /**
- * Returns an unmodifiable list of all the completers.
- */
- public Collection<Completer> getCompleters() {
- return Collections.unmodifiableList(completers);
- }
-
- public void setCompletionHandler(final CompletionHandler handler) {
- assert handler != null;
- this.completionHandler = handler;
- }
-
- public CompletionHandler getCompletionHandler() {
- return this.completionHandler;
- }
-
- /**
- * Use the completers to modify the buffer with the appropriate completions.
- *
- * @return true if successful
- */
- protected boolean complete() throws IOException {
- // debug ("tab for (" + buf + ")");
- if (completers.size() == 0) {
- return false;
- }
-
- List<CharSequence> candidates = new LinkedList<CharSequence>();
- String bufstr = buf.buffer.toString();
- int cursor = buf.cursor;
-
- int position = -1;
-
- for (Completer comp : completers) {
- if ((position = comp.complete(bufstr, cursor, candidates)) != -1) {
- break;
- }
- }
-
- return candidates.size() != 0 && getCompletionHandler().complete(this, candidates, position);
- }
-
- /**
- * The number of tab-completion candidates above which a warning will be
- * prompted before showing all the candidates.
- */
- private int autoprintThreshold = Integer.getInteger(JLINE_COMPLETION_THRESHOLD, 100); // same default as bash
-
- /**
- * @param threshold the number of candidates to print without issuing a warning.
- */
- public void setAutoprintThreshold(final int threshold) {
- this.autoprintThreshold = threshold;
- }
-
- /**
- * @return the number of candidates to print without issuing a warning.
- */
- public int getAutoprintThreshold() {
- return autoprintThreshold;
- }
-
- private boolean paginationEnabled;
-
- /**
- * Whether to use pagination when the number of rows of candidates exceeds the height of the terminal.
- */
- public void setPaginationEnabled(final boolean enabled) {
- this.paginationEnabled = enabled;
- }
-
- /**
- * Whether to use pagination when the number of rows of candidates exceeds the height of the terminal.
- */
- public boolean isPaginationEnabled() {
- return paginationEnabled;
- }
-
- //
- // History
- //
-
- private History history = new MemoryHistory();
-
- public void setHistory(final History history) {
- this.history = history;
- }
-
- public History getHistory() {
- return history;
- }
-
- private boolean historyEnabled = true;
-
- /**
- * Whether or not to add new commands to the history buffer.
- */
- public void setHistoryEnabled(final boolean enabled) {
- this.historyEnabled = enabled;
- }
-
- /**
- * Whether or not to add new commands to the history buffer.
- */
- public boolean isHistoryEnabled() {
- return historyEnabled;
- }
-
- /**
- * Move up or down the history tree.
- */
- private boolean moveHistory(final boolean next) throws IOException {
- if (next && !history.next()) {
- return false;
- }
- else if (!next && !history.previous()) {
- return false;
- }
-
- setBuffer(history.current());
-
- return true;
- }
-
- //
- // Printing
- //
-
- public static final String CR = System.getProperty("line.separator");
-
- /**
- * Output the specified character to the output stream without manipulating the current buffer.
- */
- private void print(final int c) throws IOException {
- if (c == '\t') {
- char chars[] = new char[TAB_WIDTH];
- Arrays.fill(chars, ' ');
- out.write(chars);
- return;
- }
-
- out.write(c);
- }
-
- /**
- * Output the specified characters to the output stream without manipulating the current buffer.
- */
- private void print(final char... buff) throws IOException {
- int len = 0;
- for (char c : buff) {
- if (c == '\t') {
- len += TAB_WIDTH;
- }
- else {
- len++;
- }
- }
-
- char chars[];
- if (len == buff.length) {
- chars = buff;
- }
- else {
- chars = new char[len];
- int pos = 0;
- for (char c : buff) {
- if (c == '\t') {
- Arrays.fill(chars, pos, pos + TAB_WIDTH, ' ');
- pos += TAB_WIDTH;
- }
- else {
- chars[pos] = c;
- pos++;
- }
- }
- }
-
- out.write(chars);
- }
-
- private void print(final char c, final int num) throws IOException {
- if (num == 1) {
- print(c);
- }
- else {
- char[] chars = new char[num];
- Arrays.fill(chars, c);
- print(chars);
- }
- }
-
- /**
- * Output the specified string to the output stream (but not the buffer).
- */
- public final void print(final CharSequence s) throws IOException {
- assert s != null;
- print(s.toString().toCharArray());
- }
-
- public final void println(final CharSequence s) throws IOException {
- assert s != null;
- print(s.toString().toCharArray());
- println();
- }
-
- /**
- * Output a platform-dependent newline.
- */
- public final void println() throws IOException {
- print(CR);
-// flush();
- }
-
- //
- // Actions
- //
-
- /**
- * Issue a delete.
- *
- * @return true if successful
- */
- public final boolean delete() throws IOException {
- return delete(1) == 1;
- }
-
- // FIXME: delete(int) only used by above + the return is always 1 and num is ignored
-
- /**
- * Issue <em>num</em> deletes.
- *
- * @return the number of characters backed up
- */
- private int delete(final int num) throws IOException {
- // TODO: Try to use jansi for this
-
- /* Commented out because of DWA-2949:
- if (buf.cursor == 0) {
- return 0;
- }
- */
-
- buf.buffer.delete(buf.cursor, buf.cursor + 1);
- drawBuffer(1);
-
- return 1;
- }
-
- /**
- * Kill the buffer ahead of the current cursor position.
- *
- * @return true if successful
- */
- public boolean killLine() throws IOException {
- int cp = buf.cursor;
- int len = buf.buffer.length();
-
- if (cp >= len) {
- return false;
- }
-
- int num = buf.buffer.length() - cp;
- clearAhead(num, 0);
-
- for (int i = 0; i < num; i++) {
- buf.buffer.deleteCharAt(len - i - 1);
- }
-
- return true;
- }
-
- /**
- * Clear the screen by issuing the ANSI "clear screen" code.
- */
- public boolean clearScreen() throws IOException {
- if (!getTerminal().isAnsiSupported()) {
- return false;
- }
-
- // send the ANSI code to clear the screen
- printAnsiSequence("2J");
-
- // then send the ANSI code to go to position 1,1
- printAnsiSequence("1;1H");
-
- redrawLine();
-
- return true;
- }
-
- /**
- * Issue an audible keyboard bell, if {@link #isBellEnabled} return true.
- */
- public void beep() throws IOException {
- if (isBellEnabled()) {
- print(KEYBOARD_BELL);
- // need to flush so the console actually beeps
- flush();
- }
- }
-
- /**
- * Paste the contents of the clipboard into the console buffer
- *
- * @return true if clipboard contents pasted
- */
- public boolean paste() throws IOException {
- Clipboard clipboard;
- try { // May throw ugly exception on system without X
- clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- }
- catch (Exception e) {
- return false;
- }
-
- if (clipboard == null) {
- return false;
- }
-
- Transferable transferable = clipboard.getContents(null);
-
- if (transferable == null) {
- return false;
- }
-
- try {
- Object content = transferable.getTransferData(DataFlavor.plainTextFlavor);
-
- // This fix was suggested in bug #1060649 at
- // http://sourceforge.net/tracker/index.php?func=detail&aid=1060649&group_id=64033&atid=506056
- // to get around the deprecated DataFlavor.plainTextFlavor, but it
- // raises a UnsupportedFlavorException on Mac OS X
-
- if (content == null) {
- try {
- content = new DataFlavor().getReaderForText(transferable);
- }
- catch (Exception e) {
- // ignore
- }
- }
-
- if (content == null) {
- return false;
- }
-
- String value;
-
- if (content instanceof Reader) {
- // TODO: we might want instead connect to the input stream
- // so we can interpret individual lines
- value = "";
- String line;
-
- BufferedReader read = new BufferedReader((Reader) content);
- while ((line = read.readLine()) != null) {
- if (value.length() > 0) {
- value += "\n";
- }
-
- value += line;
- }
- }
- else {
- value = content.toString();
- }
-
- if (value == null) {
- return true;
- }
-
- putString(value);
-
- return true;
- }
- catch (UnsupportedFlavorException e) {
- Log.error("Paste failed: ", e);
-
- return false;
- }
- }
-
- //
- // Triggered Actions
- //
-
- private final Map<Character, ActionListener> triggeredActions = new HashMap<Character, ActionListener>();
-
- /**
- * Adding a triggered Action allows to give another curse of action if a character passed the pre-processing.
- * <p/>
- * Say you want to close the application if the user enter q.
- * addTriggerAction('q', new ActionListener(){ System.exit(0); }); would do the trick.
- */
- public void addTriggeredAction(final char c, final ActionListener listener) {
- triggeredActions.put(c, listener);
- }
-
- //
- // Formatted Output
- //
-
- /**
- * Output the specified {@link Collection} in proper columns.
- */
- public void printColumns(final Collection<? extends CharSequence> items) throws IOException {
- if (items == null || items.isEmpty()) {
- return;
- }
-
- int width = getTerminal().getWidth();
- int height = getTerminal().getHeight();
-
- int maxWidth = 0;
- for (CharSequence item : items) {
- maxWidth = Math.max(maxWidth, item.length());
- }
- Log.debug("Max width: ", maxWidth);
-
- int showLines;
- if (isPaginationEnabled()) {
- showLines = height - 1; // page limit
- }
- else {
- showLines = Integer.MAX_VALUE;
- }
-
- StringBuilder buff = new StringBuilder();
- for (CharSequence item : items) {
- if ((buff.length() + maxWidth) > width) {
- println(buff);
- buff.setLength(0);
-
- if (--showLines == 0) {
- // Overflow
- print(resources.getString("display-more"));
- flush();
- int c = readVirtualKey();
- if (c == '\r' || c == '\n') {
- // one step forward
- showLines = 1;
- }
- else if (c != 'q') {
- // page forward
- showLines = height - 1;
- }
-
- back(resources.getString("display-more").length());
- if (c == 'q') {
- // cancel
- break;
- }
- }
- }
-
- // NOTE: toString() is important here due to AnsiString being retarded
- buff.append(item.toString());
- for (int i = 0; i < (maxWidth + 3 - item.length()); i++) {
- buff.append(' ');
- }
- }
-
- if (buff.length() > 0) {
- println(buff);
- }
- }
-
- //
- // Non-supported Terminal Support
- //
-
- private Thread maskThread;
-
- private void beforeReadLine(final String prompt, final Character mask) {
- if (mask != null && maskThread == null) {
- final String fullPrompt = "\r" + prompt
- + " "
- + " "
- + " "
- + "\r" + prompt;
-
- maskThread = new Thread()
- {
- public void run() {
- while (!interrupted()) {
- try {
- Writer out = getOutput();
- out.write(fullPrompt);
- out.flush();
- sleep(3);
- }
- catch (IOException e) {
- return;
- }
- catch (InterruptedException e) {
- return;
- }
- }
- }
- };
-
- maskThread.setPriority(Thread.MAX_PRIORITY);
- maskThread.setDaemon(true);
- maskThread.start();
- }
- }
-
- private void afterReadLine() {
- if (maskThread != null && maskThread.isAlive()) {
- maskThread.interrupt();
- }
-
- maskThread = null;
- }
-
- /**
- * Erases the current line with the existing prompt, then redraws the line
- * with the provided prompt and buffer
- * @param prompt
- * the new prompt
- * @param buffer
- * the buffer to be drawn
- * @param cursorDest
- * where you want the cursor set when the line has been drawn.
- * -1 for end of line.
- * */
- public void resetPromptLine(String prompt, String buffer, int cursorDest) throws IOException {
- // move cursor to end of line
- moveToEnd();
-
- // backspace all text, including prompt
- buf.buffer.append(this.prompt);
- buf.cursor += this.prompt.length();
- this.prompt = "";
- backspaceAll();
-
- this.prompt = prompt;
- redrawLine();
- setBuffer(buffer);
-
- // move cursor to destination (-1 will move to end of line)
- if (cursorDest < 0) cursorDest = buffer.length();
- setCursorPosition(cursorDest);
-
- flush();
- }
-
- public void printSearchStatus(String searchTerm, String match) throws IOException {
- String prompt = "(reverse-i-search)`" + searchTerm + "': ";
- String buffer = match;
- int cursorDest = match.indexOf(searchTerm);
- resetPromptLine(prompt, buffer, cursorDest);
- }
-
- public void restoreLine(String originalPrompt, int cursorDest) throws IOException {
- // TODO move cursor to matched string
- String prompt = lastLine(originalPrompt);
- String buffer = buf.buffer.toString();
- resetPromptLine(prompt, buffer, cursorDest);
- }
-
- //
- // History search
- //
- /**
- * Search backward in history from a given position.
- *
- * @param searchTerm substring to search for.
- * @param startIndex the index from which on to search
- * @return index where this substring has been found, or -1 else.
- */
- public int searchBackwards(String searchTerm, int startIndex) {
- return searchBackwards(searchTerm, startIndex, false);
- }
-
- /**
- * Search backwards in history from the current position.
- *
- * @param searchTerm substring to search for.
- * @return index where the substring has been found, or -1 else.
- */
- public int searchBackwards(String searchTerm) {
- return searchBackwards(searchTerm, history.index());
- }
-
-
- public int searchBackwards(String searchTerm, int startIndex, boolean startsWith) {
- ListIterator<History.Entry> it = history.entries(startIndex);
- while (it.hasPrevious()) {
- History.Entry e = it.previous();
- if (startsWith) {
- if (e.value().toString().startsWith(searchTerm)) {
- return e.index();
- }
- } else {
- if (e.value().toString().contains(searchTerm)) {
- return e.index();
- }
- }
- }
- return -1;
- }
-
- //
- // Helpers
- //
-
- /**
- * Checks to see if the specified character is a delimiter. We consider a
- * character a delimiter if it is anything but a letter or digit.
- *
- * @param c The character to test
- * @return True if it is a delimiter
- */
- private boolean isDelimiter(final char c) {
- return !Character.isLetterOrDigit(c);
- }
-
- private void printAnsiSequence(String sequence) throws IOException {
- print(27);
- print('[');
- print(sequence);
- flush(); // helps with step debugging
- }
-
- // return column position, reported by the terminal
- private int getCurrentPosition() {
- // check for ByteArrayInputStream to disable for unit tests
- if (getTerminal().isAnsiSupported() && !(in instanceof ByteArrayInputStream)) {
- try {
- printAnsiSequence("6n");
- flush();
- StringBuffer b = new StringBuffer(8);
- // position is sent as <ESC>[{ROW};{COLUMN}R
- int r;
- while((r = in.read()) > -1 && r != 'R') {
- if (r != 27 && r != '[') {
- b.append((char) r);
- }
- }
- String[] pos = b.toString().split(";");
- return Integer.parseInt(pos[1]);
- } catch (Exception x) {
- // no luck
- }
- }
-
- return -1; // TODO: throw exception instead?
- }
-
- // return row position, reported by the terminal
- // needed to know whether to scroll up on cursor move in last col for weird
- // wrapping terminals - not tested for anything else
- private int getCurrentAnsiRow() {
- // check for ByteArrayInputStream to disable for unit tests
- if (getTerminal().isAnsiSupported() && !(in instanceof ByteArrayInputStream)) {
- try {
- printAnsiSequence("6n");
- flush();
- StringBuffer b = new StringBuffer(8);
- // position is sent as <ESC>[{ROW};{COLUMN}R
- int r;
- while((r = in.read()) > -1 && r != 'R') {
- if (r != 27 && r != '[') {
- b.append((char) r);
- }
- }
- String[] pos = b.toString().split(";");
- return Integer.parseInt(pos[0]);
- } catch (Exception x) {
- // no luck
- }
- }
-
- return -1; // TODO: throw exception instead?
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/CursorBuffer.java b/src/jline/src/main/java/scala/tools/jline/console/CursorBuffer.java
deleted file mode 100644
index 7993def002..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/CursorBuffer.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console;
-
-/**
- * A holder for a {@link StringBuilder} that also contains the current cursor position.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public class CursorBuffer
-{
- private boolean overTyping = false;
-
- public int cursor = 0;
-
- public final StringBuilder buffer = new StringBuilder();
-
- public boolean isOverTyping() {
- return overTyping;
- }
-
- public void setOverTyping(final boolean b) {
- overTyping = b;
- }
-
- public int length() {
- return buffer.length();
- }
-
- /**
- * Gets the character to the left of the cursor.
- */
- public char charLeftOfCursor() {
- if (cursor <= 0) {
- return 0;
- }
-
- return buffer.charAt(cursor - 1);
- }
-
- /**
- * Gets the character at the cursor.
- */
- public char charAtCursor() {
- if (cursor < 0 || cursor >= buffer.length()) {
- return 0;
- }
- return buffer.charAt(cursor);
- }
-
- /**
- * Write the specific character into the buffer, setting the cursor position
- * ahead one. The text may overwrite or insert based on the current setting
- * of {@link #isOverTyping}.
- *
- * @param c the character to insert
- */
- public void write(final char c) {
- buffer.insert(cursor++, c);
- if (isOverTyping() && cursor < buffer.length()) {
- buffer.deleteCharAt(cursor);
- }
- }
-
- /**
- * Insert the specified chars into the buffer, setting the cursor to the end of the insertion point.
- */
- public void write(final CharSequence str) {
- assert str != null;
-
- if (buffer.length() == 0) {
- buffer.append(str);
- }
- else {
- buffer.insert(cursor, str);
- }
-
- cursor += str.length();
-
- if (isOverTyping() && cursor < buffer.length()) {
- buffer.delete(cursor, (cursor + str.length()));
- }
- }
-
- public boolean clear() {
- if (buffer.length() == 0) {
- return false;
- }
-
- buffer.delete(0, buffer.length());
- cursor = 0;
- return true;
- }
-
- @Override
- public String toString() {
- return buffer.toString();
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/Key.java b/src/jline/src/main/java/scala/tools/jline/console/Key.java
deleted file mode 100644
index 2e713a7da2..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/Key.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Map from key name to key codes.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @see java.awt.event.KeyEvent
- * @since 2.0
- */
-public enum Key
-{
- CTRL_A(1),
-
- CTRL_B(2),
-
- CTRL_C(3),
-
- CTRL_D(4),
-
- CTRL_E(5),
-
- CTRL_F(6),
-
- CTRL_G(7),
-
- CTRL_K(11),
-
- CTRL_L(12),
-
- CTRL_N(14),
-
- CTRL_O(15),
-
- CTRL_P(16),
-
- CTRL_T(20),
-
- CTRL_W(23),
-
- CTRL_X(24),
-
- CTRL_OB(27),
-
- CTRL_QM(127),
-
- BACKSPACE('\b'),
-
- DELETE(127),;
-
- public final short code;
-
- Key(final int code) {
- this.code = (short) code;
- }
-
- private static final Map<Short, Key> codes;
-
- static {
- Map<Short, Key> map = new HashMap<Short, Key>();
-
- for (Key op : Key.values()) {
- map.put(op.code, op);
- }
-
- codes = map;
- }
-
- public static Key valueOf(final int code) {
- return codes.get((short) code);
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/Operation.java b/src/jline/src/main/java/scala/tools/jline/console/Operation.java
deleted file mode 100644
index 59ee878d45..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/Operation.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Map for console operation to virtual key bindings.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @see java.awt.event.KeyEvent
- * @since 2.0
- */
-public enum Operation
-{
- /**
- * Unknown operation.
- */
- UNKNOWN(-99),
-
- /**
- * Operation that moves to the beginning of the buffer.
- */
- MOVE_TO_BEG(-1),
-
- /**
- * Operation that moves to the end of the buffer.
- */
- MOVE_TO_END(-3),
-
- /**
- * Operation that moved to the previous character in the buffer.
- */
- PREV_CHAR(-4),
-
- /**
- * Operation that issues a newline.
- */
- NEWLINE(-6),
-
- /**
- * Operation that deletes the buffer from the current character to the end.
- */
- KILL_LINE(-7),
-
- /**
- * Operation that clears the screen.
- */
- CLEAR_SCREEN(-8),
-
- /**
- * Operation that sets the buffer to the next history item.
- */
- NEXT_HISTORY(-9),
-
- /**
- * Operation that sets the buffer to the previous history item.
- */
- PREV_HISTORY(-11),
-
- /**
- * Operation that redisplays the current buffer.
- */
- REDISPLAY(-13),
-
- /**
- * Operation that deletes the buffer from the cursor to the beginning.
- */
- KILL_LINE_PREV(-15),
-
- /**
- * Operation that deletes the previous word in the buffer.
- */
- DELETE_PREV_WORD(-16),
-
- /**
- * Operation that moves to the next character in the buffer.
- */
- NEXT_CHAR(-19),
-
- /**
- * Operation that moves to the previous character in the buffer.
- */
- REPEAT_PREV_CHAR(-20),
-
- /**
- * Operation that searches backwards in the command history.
- */
- SEARCH_PREV(-21),
-
- /**
- * Operation that repeats the character.
- */
- REPEAT_NEXT_CHAR(-24),
-
- /**
- * Operation that searches forward in the command history.
- */
- SEARCH_NEXT(-25),
-
- /**
- * Operation that moved to the previous whitespace.
- */
- PREV_SPACE_WORD(-27),
-
- /**
- * Operation that moved to the end of the current word.
- */
- TO_END_WORD(-29),
-
- /**
- * Operation that
- */
- REPEAT_SEARCH_PREV(-34),
-
- /**
- * Operation that
- */
- PASTE_PREV(-36),
-
- /**
- * Operation that
- */
- REPLACE_MODE(-37),
-
- /**
- * Operation that
- */
- SUBSTITUTE_LINE(-38),
-
- /**
- * Operation that
- */
- TO_PREV_CHAR(-39),
-
- /**
- * Operation that
- */
- NEXT_SPACE_WORD(-40),
-
- /**
- * Operation that
- */
- DELETE_PREV_CHAR(-41),
-
- /**
- * Operation that
- */
- ADD(-42),
-
- /**
- * Operation that
- */
- PREV_WORD(-43),
-
- /**
- * Operation that
- */
- CHANGE_META(-44),
-
- /**
- * Operation that
- */
- DELETE_META(-45),
-
- /**
- * Operation that
- */
- END_WORD(-46),
-
- /**
- * Operation that toggles insert/overtype
- */
- INSERT(-48),
-
- /**
- * Operation that
- */
- REPEAT_SEARCH_NEXT(-49),
-
- /**
- * Operation that
- */
- PASTE_NEXT(-50),
-
- /**
- * Operation that
- */
- REPLACE_CHAR(-51),
-
- /**
- * Operation that
- */
- SUBSTITUTE_CHAR(-52),
-
- /**
- * Operation that
- */
- TO_NEXT_CHAR(-53),
-
- /**
- * Operation that undoes the previous operation.
- */
- UNDO(-54),
-
- /**
- * Operation that moved to the next word.
- */
- NEXT_WORD(-55),
-
- /**
- * Operation that deletes the previous character.
- */
- DELETE_NEXT_CHAR(-56),
-
- /**
- * Operation that toggles between uppercase and lowercase.
- */
- CHANGE_CASE(-57),
-
- /**
- * Operation that performs completion operation on the current word.
- */
- COMPLETE(-58),
-
- /**
- * Operation that exits the command prompt.
- */
- EXIT(-59),
-
- /**
- * Operation that pastes the contents of the clipboard into the line
- */
- PASTE(-60),
-
- /**
- * Operation that moves the current History to the beginning.
- */
- START_OF_HISTORY(-61),
-
- /**
- * Operation that moves the current History to the end.
- */
- END_OF_HISTORY(-62),
-
- /**
- * Operation that clears whatever text is on the current line.
- */
- CLEAR_LINE(-63),
-
- /**
- * Cancel search
- */
- ABORT(-64),
-
- /**
- * Delete next word
- */
- DELETE_NEXT_WORD(-65),
-
- ;
-
- public final short code;
-
- Operation(final int code) {
- this.code = (short) code;
- }
-
- private static final Map<Short, Operation> codes;
-
- static {
- Map<Short, Operation> map = new HashMap<Short, Operation>();
-
- for (Operation op : Operation.values()) {
- map.put(op.code, op);
- }
-
- codes = map;
- }
-
- public static Operation valueOf(final int code) {
- return codes.get((short) code);
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/AggregateCompleter.java b/src/jline/src/main/java/scala/tools/jline/console/completer/AggregateCompleter.java
deleted file mode 100644
index 3170bd1c68..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/AggregateCompleter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package scala.tools.jline.console.completer;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Completer which contains multiple completers and aggregates them together.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public class AggregateCompleter
- implements Completer
-{
- private final List<Completer> completers = new ArrayList<Completer>();
-
- public AggregateCompleter() {
- // empty
- }
-
- public AggregateCompleter(final Collection<Completer> completers) {
- assert completers != null;
- this.completers.addAll(completers);
- }
-
- public AggregateCompleter(final Completer... completers) {
- this(Arrays.asList(completers));
- }
-
- public Collection<Completer> getCompleters() {
- return completers;
- }
-
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- // buffer could be null
- assert candidates != null;
-
- List<Completion> completions = new ArrayList<Completion>(completers.size());
-
- // Run each completer, saving its completion results
- int max = -1;
- for (Completer completer : completers) {
- Completion completion = new Completion(candidates);
- completion.complete(completer, buffer, cursor);
-
- // Compute the max cursor position
- max = Math.max(max, completion.cursor);
-
- completions.add(completion);
- }
-
- // Append candidates from completions which have the same cursor position as max
- for (Completion completion : completions) {
- if (completion.cursor == max) {
- candidates.addAll(completion.candidates);
- }
- }
-
- return max;
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + "{" +
- "completers=" + completers +
- '}';
- }
-
- private class Completion
- {
- public final List<CharSequence> candidates;
-
- public int cursor;
-
- public Completion(final List<CharSequence> candidates) {
- assert candidates != null;
- this.candidates = new LinkedList<CharSequence>(candidates);
- }
-
- public void complete(final Completer completer, final String buffer, final int cursor) {
- assert completer != null;
-
- this.cursor = completer.complete(buffer, cursor, candidates);
- }
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/ArgumentCompleter.java b/src/jline/src/main/java/scala/tools/jline/console/completer/ArgumentCompleter.java
deleted file mode 100644
index 6f60029a1d..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/ArgumentCompleter.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.completer;
-
-import scala.tools.jline.internal.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * A {@link Completer} implementation that invokes a child completer using the appropriate <i>separator</i> argument.
- * This can be used instead of the individual completers having to know about argument parsing semantics.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public class ArgumentCompleter
- implements Completer
-{
- private final ArgumentDelimiter delimiter;
-
- private final List<Completer> completers = new ArrayList<Completer>();
-
- private boolean strict = true;
-
- /**
- * Create a new completer with the specified argument delimiter.
- *
- * @param delimiter The delimiter for parsing arguments
- * @param completers The embedded completers
- */
- public ArgumentCompleter(final ArgumentDelimiter delimiter, final Collection<Completer> completers) {
- assert delimiter != null;
- this.delimiter = delimiter;
- assert completers != null;
- this.completers.addAll(completers);
- }
-
- /**
- * Create a new completer with the specified argument delimiter.
- *
- * @param delimiter The delimiter for parsing arguments
- * @param completers The embedded completers
- */
- public ArgumentCompleter(final ArgumentDelimiter delimiter, final Completer... completers) {
- this(delimiter, Arrays.asList(completers));
- }
-
- /**
- * Create a new completer with the default {@link WhitespaceArgumentDelimiter}.
- *
- * @param completers The embedded completers
- */
- public ArgumentCompleter(final Completer... completers) {
- this(new WhitespaceArgumentDelimiter(), completers);
- }
-
- /**
- * Create a new completer with the default {@link WhitespaceArgumentDelimiter}.
- *
- * @param completers The embedded completers
- */
- public ArgumentCompleter(final List<Completer> completers) {
- this(new WhitespaceArgumentDelimiter(), completers);
- }
-
- /**
- * If true, a completion at argument index N will only succeed
- * if all the completions from 0-(N-1) also succeed.
- */
- public void setStrict(final boolean strict) {
- this.strict = strict;
- }
-
- /**
- * Returns whether a completion at argument index N will success
- * if all the completions from arguments 0-(N-1) also succeed.
- *
- * @return True if strict.
- * @since 2.3
- */
- public boolean isStrict() {
- return this.strict;
- }
-
- /**
- * @since 2.3
- */
- public ArgumentDelimiter getDelimiter() {
- return delimiter;
- }
-
- /**
- * @since 2.3
- */
- public List<Completer> getCompleters() {
- return completers;
- }
-
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- // buffer can be null
- assert candidates != null;
-
- ArgumentDelimiter delim = getDelimiter();
- ArgumentList list = delim.delimit(buffer, cursor);
- int argpos = list.getArgumentPosition();
- int argIndex = list.getCursorArgumentIndex();
-
- if (argIndex < 0) {
- return -1;
- }
-
- List<Completer> completers = getCompleters();
- Completer completer;
-
- // if we are beyond the end of the completers, just use the last one
- if (argIndex >= completers.size()) {
- completer = completers.get(completers.size() - 1);
- }
- else {
- completer = completers.get(argIndex);
- }
-
- // ensure that all the previous completers are successful before allowing this completer to pass (only if strict).
- for (int i = 0; isStrict() && (i < argIndex); i++) {
- Completer sub = completers.get(i >= completers.size() ? (completers.size() - 1) : i);
- String[] args = list.getArguments();
- String arg = (args == null || i >= args.length) ? "" : args[i];
-
- List<CharSequence> subCandidates = new LinkedList<CharSequence>();
-
- if (sub.complete(arg, arg.length(), subCandidates) == -1) {
- return -1;
- }
-
- if (subCandidates.size() == 0) {
- return -1;
- }
- }
-
- int ret = completer.complete(list.getCursorArgument(), argpos, candidates);
-
- if (ret == -1) {
- return -1;
- }
-
- int pos = ret + list.getBufferPosition() - argpos;
-
- // Special case: when completing in the middle of a line, and the area under the cursor is a delimiter,
- // then trim any delimiters from the candidates, since we do not need to have an extra delimiter.
- //
- // E.g., if we have a completion for "foo", and we enter "f bar" into the buffer, and move to after the "f"
- // and hit TAB, we want "foo bar" instead of "foo bar".
-
- if ((cursor != buffer.length()) && delim.isDelimiter(buffer, cursor)) {
- for (int i = 0; i < candidates.size(); i++) {
- CharSequence val = candidates.get(i);
-
- while (val.length() > 0 && delim.isDelimiter(val, val.length() - 1)) {
- val = val.subSequence(0, val.length() - 1);
- }
-
- candidates.set(i, val);
- }
- }
-
- Log.trace("Completing ", buffer, " (pos=", cursor, ") with: ", candidates, ": offset=", pos);
-
- return pos;
- }
-
- /**
- * The {@link ArgumentCompleter.ArgumentDelimiter} allows custom breaking up of a {@link String} into individual
- * arguments in order to dispatch the arguments to the nested {@link Completer}.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
- public static interface ArgumentDelimiter
- {
- /**
- * Break the specified buffer into individual tokens that can be completed on their own.
- *
- * @param buffer The buffer to split
- * @param pos The current position of the cursor in the buffer
- * @return The tokens
- */
- ArgumentList delimit(CharSequence buffer, int pos);
-
- /**
- * Returns true if the specified character is a whitespace parameter.
- *
- * @param buffer The complete command buffer
- * @param pos The index of the character in the buffer
- * @return True if the character should be a delimiter
- */
- boolean isDelimiter(CharSequence buffer, int pos);
- }
-
- /**
- * Abstract implementation of a delimiter that uses the {@link #isDelimiter} method to determine if a particular
- * character should be used as a delimiter.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
- public abstract static class AbstractArgumentDelimiter
- implements ArgumentDelimiter
- {
- // TODO: handle argument quoting and escape characters
-
- private char[] quoteChars = {'\'', '"'};
-
- private char[] escapeChars = {'\\'};
-
- public void setQuoteChars(final char[] chars) {
- this.quoteChars = chars;
- }
-
- public char[] getQuoteChars() {
- return this.quoteChars;
- }
-
- public void setEscapeChars(final char[] chars) {
- this.escapeChars = chars;
- }
-
- public char[] getEscapeChars() {
- return this.escapeChars;
- }
-
- public ArgumentList delimit(final CharSequence buffer, final int cursor) {
- List<String> args = new LinkedList<String>();
- StringBuilder arg = new StringBuilder();
- int argpos = -1;
- int bindex = -1;
-
- for (int i = 0; (buffer != null) && (i <= buffer.length()); i++) {
- // once we reach the cursor, set the
- // position of the selected index
- if (i == cursor) {
- bindex = args.size();
- // the position in the current argument is just the
- // length of the current argument
- argpos = arg.length();
- }
-
- if ((i == buffer.length()) || isDelimiter(buffer, i)) {
- if (arg.length() > 0) {
- args.add(arg.toString());
- arg.setLength(0); // reset the arg
- }
- }
- else {
- arg.append(buffer.charAt(i));
- }
- }
-
- return new ArgumentList(args.toArray(new String[args.size()]), bindex, argpos, cursor);
- }
-
- /**
- * Returns true if the specified character is a whitespace parameter. Check to ensure that the character is not
- * escaped by any of {@link #getQuoteChars}, and is not escaped by ant of the {@link #getEscapeChars}, and
- * returns true from {@link #isDelimiterChar}.
- *
- * @param buffer The complete command buffer
- * @param pos The index of the character in the buffer
- * @return True if the character should be a delimiter
- */
- public boolean isDelimiter(final CharSequence buffer, final int pos) {
- return !isQuoted(buffer, pos) && !isEscaped(buffer, pos) && isDelimiterChar(buffer, pos);
- }
-
- public boolean isQuoted(final CharSequence buffer, final int pos) {
- return false;
- }
-
- public boolean isEscaped(final CharSequence buffer, final int pos) {
- if (pos <= 0) {
- return false;
- }
-
- for (int i = 0; (escapeChars != null) && (i < escapeChars.length);
- i++) {
- if (buffer.charAt(pos) == escapeChars[i]) {
- return !isEscaped(buffer, pos - 1); // escape escape
- }
- }
-
- return false;
- }
-
- /**
- * Returns true if the character at the specified position if a delimiter. This method will only be called if
- * the character is not enclosed in any of the {@link #getQuoteChars}, and is not escaped by ant of the
- * {@link #getEscapeChars}. To perform escaping manually, override {@link #isDelimiter} instead.
- */
- public abstract boolean isDelimiterChar(CharSequence buffer, int pos);
- }
-
- /**
- * {@link ArgumentCompleter.ArgumentDelimiter} implementation that counts all whitespace (as reported by
- * {@link Character#isWhitespace}) as being a delimiter.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
- public static class WhitespaceArgumentDelimiter
- extends AbstractArgumentDelimiter
- {
- /**
- * The character is a delimiter if it is whitespace, and the
- * preceding character is not an escape character.
- */
- @Override
- public boolean isDelimiterChar(final CharSequence buffer, final int pos) {
- return Character.isWhitespace(buffer.charAt(pos));
- }
- }
-
- /**
- * The result of a delimited buffer.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
- public static class ArgumentList
- {
- private String[] arguments;
-
- private int cursorArgumentIndex;
-
- private int argumentPosition;
-
- private int bufferPosition;
-
- /**
- * @param arguments The array of tokens
- * @param cursorArgumentIndex The token index of the cursor
- * @param argumentPosition The position of the cursor in the current token
- * @param bufferPosition The position of the cursor in the whole buffer
- */
- public ArgumentList(final String[] arguments, final int cursorArgumentIndex, final int argumentPosition, final int bufferPosition) {
- assert arguments != null;
-
- this.arguments = arguments;
- this.cursorArgumentIndex = cursorArgumentIndex;
- this.argumentPosition = argumentPosition;
- this.bufferPosition = bufferPosition;
- }
-
- public void setCursorArgumentIndex(final int i) {
- this.cursorArgumentIndex = i;
- }
-
- public int getCursorArgumentIndex() {
- return this.cursorArgumentIndex;
- }
-
- public String getCursorArgument() {
- if ((cursorArgumentIndex < 0) || (cursorArgumentIndex >= arguments.length)) {
- return null;
- }
-
- return arguments[cursorArgumentIndex];
- }
-
- public void setArgumentPosition(final int pos) {
- this.argumentPosition = pos;
- }
-
- public int getArgumentPosition() {
- return this.argumentPosition;
- }
-
- public void setArguments(final String[] arguments) {
- this.arguments = arguments;
- }
-
- public String[] getArguments() {
- return this.arguments;
- }
-
- public void setBufferPosition(final int pos) {
- this.bufferPosition = pos;
- }
-
- public int getBufferPosition() {
- return this.bufferPosition;
- }
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/CandidateListCompletionHandler.java b/src/jline/src/main/java/scala/tools/jline/console/completer/CandidateListCompletionHandler.java
deleted file mode 100644
index fa5bfd2777..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/CandidateListCompletionHandler.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.completer;
-
-import scala.tools.jline.console.ConsoleReader;
-import scala.tools.jline.console.CursorBuffer;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.ResourceBundle;
-import java.util.Set;
-
-/**
- * A {@link CompletionHandler} that deals with multiple distinct completions
- * by outputting the complete list of possibilities to the console. This
- * mimics the behavior of the
- * <a href="http://www.gnu.org/directory/readline.html">readline</a> library.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public class CandidateListCompletionHandler
- implements CompletionHandler
-{
- // TODO: handle quotes and escaped quotes && enable automatic escaping of whitespace
-
- public boolean complete(final ConsoleReader reader, final List<CharSequence> candidates, final int pos) throws
- IOException
- {
- CursorBuffer buf = reader.getCursorBuffer();
-
- // if there is only one completion, then fill in the buffer
- if (candidates.size() == 1) {
- CharSequence value = candidates.get(0);
-
- // fail if the only candidate is the same as the current buffer
- if (value.equals(buf.toString())) {
- return false;
- }
-
- setBuffer(reader, value, pos);
-
- return true;
- }
- else if (candidates.size() > 1) {
- String value = getUnambiguousCompletions(candidates);
- setBuffer(reader, value, pos);
- }
-
- printCandidates(reader, candidates);
-
- // redraw the current console buffer
- reader.drawLine();
-
- return true;
- }
-
- public static void setBuffer(final ConsoleReader reader, final CharSequence value, final int offset) throws
- IOException
- {
- while ((reader.getCursorBuffer().cursor > offset) && reader.backspace()) {
- // empty
- }
-
- reader.putString(value);
- reader.setCursorPosition(offset + value.length());
- }
-
- /**
- * Print out the candidates. If the size of the candidates is greater than the
- * {@link ConsoleReader#getAutoprintThreshold}, they prompt with a warning.
- *
- * @param candidates the list of candidates to print
- */
- public static void printCandidates(final ConsoleReader reader, Collection<CharSequence> candidates) throws
- IOException
- {
- Set<CharSequence> distinct = new HashSet<CharSequence>(candidates);
-
- if (distinct.size() > reader.getAutoprintThreshold()) {
- //noinspection StringConcatenation
- reader.print(Messages.DISPLAY_CANDIDATES.format(candidates.size()));
- reader.flush();
-
- int c;
-
- String noOpt = Messages.DISPLAY_CANDIDATES_NO.format();
- String yesOpt = Messages.DISPLAY_CANDIDATES_YES.format();
- char[] allowed = {yesOpt.charAt(0), noOpt.charAt(0)};
-
- while ((c = reader.readCharacter(allowed)) != -1) {
- String tmp = new String(new char[]{(char) c});
-
- if (noOpt.startsWith(tmp)) {
- reader.println();
- return;
- }
- else if (yesOpt.startsWith(tmp)) {
- break;
- }
- else {
- reader.beep();
- }
- }
- }
-
- // copy the values and make them distinct, without otherwise affecting the ordering. Only do it if the sizes differ.
- if (distinct.size() != candidates.size()) {
- Collection<CharSequence> copy = new ArrayList<CharSequence>();
-
- for (CharSequence next : candidates) {
- if (!copy.contains(next)) {
- copy.add(next);
- }
- }
-
- candidates = copy;
- }
-
- reader.println();
- reader.printColumns(candidates);
- }
-
- /**
- * Returns a root that matches all the {@link String} elements of the specified {@link List},
- * or null if there are no commonalities. For example, if the list contains
- * <i>foobar</i>, <i>foobaz</i>, <i>foobuz</i>, the method will return <i>foob</i>.
- */
- private String getUnambiguousCompletions(final List<CharSequence> candidates) {
- if (candidates == null || candidates.isEmpty()) {
- return null;
- }
-
- // convert to an array for speed
- String[] strings = candidates.toArray(new String[candidates.size()]);
-
- String first = strings[0];
- StringBuilder candidate = new StringBuilder();
-
- for (int i = 0; i < first.length(); i++) {
- if (startsWith(first.substring(0, i + 1), strings)) {
- candidate.append(first.charAt(i));
- }
- else {
- break;
- }
- }
-
- return candidate.toString();
- }
-
- /**
- * @return true is all the elements of <i>candidates</i> start with <i>starts</i>
- */
- private boolean startsWith(final String starts, final String[] candidates) {
- for (String candidate : candidates) {
- if (!candidate.startsWith(starts)) {
- return false;
- }
- }
-
- return true;
- }
-
- private static enum Messages
- {
- DISPLAY_CANDIDATES,
- DISPLAY_CANDIDATES_YES,
- DISPLAY_CANDIDATES_NO,;
-
- private static final
- ResourceBundle
- bundle =
- ResourceBundle.getBundle(CandidateListCompletionHandler.class.getName(), Locale.getDefault());
-
- public String format(final Object... args) {
- if (bundle == null)
- return "";
- else
- return String.format(bundle.getString(name()), args);
- }
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/Completer.java b/src/jline/src/main/java/scala/tools/jline/console/completer/Completer.java
deleted file mode 100644
index 52d33847f2..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/Completer.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.completer;
-
-import java.util.List;
-
-/**
- * A completer is the mechanism by which tab-completion candidates will be resolved.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public interface Completer
-{
- //
- // FIXME: Check if we can use CharSequece for buffer?
- //
-
- /**
- * Populates <i>candidates</i> with a list of possible completions for the <i>buffer</i>.
- *
- * The <i>candidates</i> list will not be sorted before being displayed to the user: thus, the
- * complete method should sort the {@link List} before returning.
- *
- * @param buffer The buffer
- * @param cursor The current position of the cursor in the <i>buffer</i>
- * @param candidates The {@link List} of candidates to populate
- * @return The index of the <i>buffer</i> for which the completion will be relative
- */
- int complete(String buffer, int cursor, List<CharSequence> candidates);
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/CompletionHandler.java b/src/jline/src/main/java/scala/tools/jline/console/completer/CompletionHandler.java
deleted file mode 100644
index 030dc84205..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/CompletionHandler.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.completer;
-
-import scala.tools.jline.console.ConsoleReader;
-
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Handler for dealing with candidates for tab-completion.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public interface CompletionHandler
-{
- boolean complete(ConsoleReader reader, List<CharSequence> candidates, int position) throws IOException;
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/EnumCompleter.java b/src/jline/src/main/java/scala/tools/jline/console/completer/EnumCompleter.java
deleted file mode 100644
index 5ad049b857..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/EnumCompleter.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2009 the original author(s).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package scala.tools.jline.console.completer;
-
-/**
- * {@link Completer} for {@link Enum} names.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public class EnumCompleter
- extends StringsCompleter
-{
- public EnumCompleter(Class<? extends Enum> source) {
- assert source != null;
-
- for (Enum<?> n : source.getEnumConstants()) {
- this.getStrings().add(n.name().toLowerCase());
- }
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/FileNameCompleter.java b/src/jline/src/main/java/scala/tools/jline/console/completer/FileNameCompleter.java
deleted file mode 100644
index 6556138769..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/FileNameCompleter.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.completer;
-
-import scala.tools.jline.internal.Configuration;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * A file name completer takes the buffer and issues a list of
- * potential completions.
- * <p/>
- * This completer tries to behave as similar as possible to
- * <i>bash</i>'s file name completion (using GNU readline)
- * with the following exceptions:
- * <p/>
- * <ul>
- * <li>Candidates that are directories will end with "/"</li>
- * <li>Wildcard regular expressions are not evaluated or replaced</li>
- * <li>The "~" character can be used to represent the user's home,
- * but it cannot complete to other users' homes, since java does
- * not provide any way of determining that easily</li>
- * </ul>
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public class FileNameCompleter
- implements Completer
-{
- // TODO: Handle files with spaces in them
-
- private static final boolean OS_IS_WINDOWS;
-
- static {
- String os = Configuration.getOsName();
- OS_IS_WINDOWS = os.contains("windows");
- }
-
- public int complete(String buffer, final int cursor, final List<CharSequence> candidates) {
- // buffer can be null
- assert candidates != null;
-
- if (buffer == null) {
- buffer = "";
- }
-
- if (OS_IS_WINDOWS) {
- buffer = buffer.replace('/', '\\');
- }
-
- String translated = buffer;
-
- File homeDir = getUserHome();
-
- // Special character: ~ maps to the user's home directory
- if (translated.startsWith("~" + separator())) {
- translated = homeDir.getPath() + translated.substring(1);
- }
- else if (translated.startsWith("~")) {
- translated = homeDir.getParentFile().getAbsolutePath();
- }
- else if (!(translated.startsWith(separator()))) {
- String cwd = getUserDir().getAbsolutePath();
- translated = cwd + separator() + translated;
- }
-
- File file = new File(translated);
- final File dir;
-
- if (translated.endsWith(separator())) {
- dir = file;
- }
- else {
- dir = file.getParentFile();
- }
-
- File[] entries = dir == null ? new File[0] : dir.listFiles();
-
- return matchFiles(buffer, translated, entries, candidates);
- }
-
- protected String separator() {
- return File.separator;
- }
-
- protected File getUserHome() {
- return Configuration.getUserHome();
- }
-
- protected File getUserDir() {
- return new File(".");
- }
-
- protected int matchFiles(final String buffer, final String translated, final File[] files, final List<CharSequence> candidates) {
- if (files == null) {
- return -1;
- }
-
- int matches = 0;
-
- // first pass: just count the matches
- for (File file : files) {
- if (file.getAbsolutePath().startsWith(translated)) {
- matches++;
- }
- }
- for (File file : files) {
- if (file.getAbsolutePath().startsWith(translated)) {
- CharSequence name = file.getName() + (matches == 1 && file.isDirectory() ? separator() : " ");
- candidates.add(render(file, name).toString());
- }
- }
-
- final int index = buffer.lastIndexOf(separator());
-
- return index + separator().length();
- }
-
- protected CharSequence render(final File file, final CharSequence name) {
- assert file != null;
- assert name != null;
-
- return name;
- }
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/NullCompleter.java b/src/jline/src/main/java/scala/tools/jline/console/completer/NullCompleter.java
deleted file mode 100644
index 93cf563bcd..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/NullCompleter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package scala.tools.jline.console.completer;
-
-import java.util.List;
-
-/**
- * Null completer.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public final class NullCompleter
- implements Completer
-{
- public static final NullCompleter INSTANCE = new NullCompleter();
-
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- return -1;
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/StringsCompleter.java b/src/jline/src/main/java/scala/tools/jline/console/completer/StringsCompleter.java
deleted file mode 100644
index 2abfdd0340..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/StringsCompleter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package scala.tools.jline.console.completer;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * Completer for a set of strings.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public class StringsCompleter
- implements Completer
-{
- private final SortedSet<String> strings = new TreeSet<String>();
-
- public StringsCompleter() {
- // empty
- }
-
- public StringsCompleter(final Collection<String> strings) {
- assert strings != null;
- getStrings().addAll(strings);
- }
-
- public StringsCompleter(final String... strings) {
- this(Arrays.asList(strings));
- }
-
- public Collection<String> getStrings() {
- return strings;
- }
-
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- // buffer could be null
- assert candidates != null;
-
- if (buffer == null) {
- candidates.addAll(strings);
- }
- else {
- for (String match : strings.tailSet(buffer)) {
- if (!match.startsWith(buffer)) {
- break;
- }
-
- candidates.add(match);
- }
- }
-
- if (candidates.size() == 1) {
- candidates.set(0, candidates.get(0) + " ");
- }
-
- return candidates.isEmpty() ? -1 : 0;
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/completer/package-info.java b/src/jline/src/main/java/scala/tools/jline/console/completer/package-info.java
deleted file mode 100644
index 8150710cfc..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/completer/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Console completer support.
- *
- * @since 2.3
- */
-package scala.tools.jline.console.completer; \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/history/FileHistory.java b/src/jline/src/main/java/scala/tools/jline/console/history/FileHistory.java
deleted file mode 100644
index 5eccba3ce5..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/history/FileHistory.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.history;
-
-import scala.tools.jline.internal.Log;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.Flushable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.util.ListIterator;
-
-/**
- * {@link History} using a file for persistent backing.
- * <p/>
- * Implementers should install shutdown hook to call {@link FileHistory#flush}
- * to save history to disk.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public class FileHistory
- extends MemoryHistory
- implements PersistentHistory, Flushable
-{
- private final File file;
-
- public FileHistory(final File file) throws IOException {
- assert file != null;
- this.file = file;
- load(file);
- }
-
- public File getFile() {
- return file;
- }
-
- public void load(final File file) throws IOException {
- assert file != null;
- if (file.exists()) {
- Log.trace("Loading history from: ", file);
- load(new FileReader(file));
- }
- }
-
- public void load(final InputStream input) throws IOException {
- assert input != null;
- load(new InputStreamReader(input));
- }
-
- public void load(final Reader reader) throws IOException {
- assert reader != null;
- BufferedReader input = new BufferedReader(reader);
-
- String item;
- while ((item = input.readLine()) != null) {
- add(item);
- }
- }
-
- public void flush() throws IOException {
- Log.trace("Flushing history");
-
- if (!file.exists()) {
- File dir = file.getParentFile();
- if (!dir.exists() && !dir.mkdirs()) {
- Log.warn("Failed to create directory: ", dir);
- }
- if (!file.createNewFile()) {
- Log.warn("Failed to create file: ", file);
- }
- }
-
- PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
- try {
- for (Entry entry : this) {
- out.println(entry.value());
- }
- }
- finally {
- out.close();
- }
- }
-
- public void purge() throws IOException {
- Log.trace("Purging history");
-
- clear();
-
- if (!file.delete()) {
- Log.warn("Failed to delete history file: ", file);
- }
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/history/History.java b/src/jline/src/main/java/scala/tools/jline/console/history/History.java
deleted file mode 100644
index d8602f2150..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/history/History.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.history;
-
-import java.util.Iterator;
-import java.util.ListIterator;
-
-/**
- * Console history.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public interface History
- extends Iterable<History.Entry>
-{
- int size();
-
- boolean isEmpty();
-
- int index();
-
- void clear();
-
- CharSequence get(int index);
-
- void add(CharSequence line);
-
- void replace(CharSequence item);
-
- //
- // Entries
- //
-
- interface Entry
- {
- int index();
-
- CharSequence value();
- }
-
- ListIterator<Entry> entries(int index);
-
- ListIterator<Entry> entries();
-
- Iterator<Entry> iterator();
-
- //
- // Navigation
- //
-
- CharSequence current();
-
- boolean previous();
-
- boolean next();
-
- boolean moveToFirst();
-
- boolean moveToLast();
-
- boolean moveTo(int index);
-
- void moveToEnd();
-}
diff --git a/src/jline/src/main/java/scala/tools/jline/console/history/MemoryHistory.java b/src/jline/src/main/java/scala/tools/jline/console/history/MemoryHistory.java
deleted file mode 100644
index 3af936428a..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/history/MemoryHistory.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.history;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-/**
- * Non-persistent {@link History}.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public class MemoryHistory
- implements History
-{
- public static final int DEFAULT_MAX_SIZE = 500;
-
- private final LinkedList<CharSequence> items = new LinkedList<CharSequence>();
-
- private int maxSize = DEFAULT_MAX_SIZE;
-
- private boolean ignoreDuplicates = true;
-
- private boolean autoTrim = false;
-
- // NOTE: These are all ideas from looking at the Bash man page:
-
- // TODO: Add ignore space? (lines starting with a space are ignored)
-
- // TODO: Add ignore patterns?
-
- // TODO: Add history timestamp?
-
- // TODO: Add erase dups?
-
- private int offset = 0;
-
- private int index = 0;
-
- public void setMaxSize(final int maxSize) {
- this.maxSize = maxSize;
- maybeResize();
- }
-
- public int getMaxSize() {
- return maxSize;
- }
-
- public boolean isIgnoreDuplicates() {
- return ignoreDuplicates;
- }
-
- public void setIgnoreDuplicates(final boolean flag) {
- this.ignoreDuplicates = flag;
- }
-
- public boolean isAutoTrim() {
- return autoTrim;
- }
-
- public void setAutoTrim(final boolean flag) {
- this.autoTrim = flag;
- }
-
- public int size() {
- return items.size();
- }
-
- public boolean isEmpty() {
- return items.isEmpty();
- }
-
- public int index() {
- return offset + index;
- }
-
- public void clear() {
- items.clear();
- offset = 0;
- index = 0;
- }
-
- public CharSequence get(final int index) {
- return items.get(index - offset);
- }
-
- public void add(CharSequence item) {
- assert item != null;
-
- if (isAutoTrim()) {
- item = String.valueOf(item).trim();
- }
-
- if (isIgnoreDuplicates()) {
- if (!items.isEmpty() && item.equals(items.getLast())) {
- return;
- }
- }
-
- items.add(item);
-
- maybeResize();
- }
-
- public void replace(final CharSequence item) {
- items.removeLast();
- add(item);
- }
-
- private void maybeResize() {
- while (size() > getMaxSize()) {
- items.removeFirst();
- offset++;
- }
-
- index = size();
- }
-
- public ListIterator<Entry> entries(final int index) {
- return new EntriesIterator(index - offset);
- }
-
- public ListIterator<Entry> entries() {
- return entries(offset);
- }
-
- public Iterator<Entry> iterator() {
- return entries();
- }
-
- private static class EntryImpl
- implements Entry
- {
- private final int index;
-
- private final CharSequence value;
-
- public EntryImpl(int index, CharSequence value) {
- this.index = index;
- this.value = value;
- }
-
- public int index() {
- return index;
- }
-
- public CharSequence value() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.format("%d: %s", index, value);
- }
- }
-
- private class EntriesIterator
- implements ListIterator<Entry>
- {
- private final ListIterator<CharSequence> source;
-
- private EntriesIterator(final int index) {
- source = items.listIterator(index);
- }
-
- public Entry next() {
- if (!source.hasNext()) {
- throw new NoSuchElementException();
- }
- return new EntryImpl(offset + source.nextIndex(), source.next());
- }
-
- public Entry previous() {
- if (!source.hasPrevious()) {
- throw new NoSuchElementException();
- }
- return new EntryImpl(offset + source.previousIndex(), source.previous());
- }
-
- public int nextIndex() {
- return offset + source.nextIndex();
- }
-
- public int previousIndex() {
- return offset + source.previousIndex();
- }
-
- public boolean hasNext() {
- return source.hasNext();
- }
-
- public boolean hasPrevious() {
- return source.hasPrevious();
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public void set(final Entry entry) {
- throw new UnsupportedOperationException();
- }
-
- public void add(final Entry entry) {
- throw new UnsupportedOperationException();
- }
- }
-
- //
- // Navigation
- //
-
- /**
- * This moves the history to the last entry. This entry is one position
- * before the moveToEnd() position.
- *
- * @return Returns false if there were no history entries or the history
- * index was already at the last entry.
- */
- public boolean moveToLast() {
- int lastEntry = size() - 1;
- if (lastEntry >= 0 && lastEntry != index) {
- index = size() - 1;
- return true;
- }
-
- return false;
- }
-
- /**
- * Move to the specified index in the history
- * @param index
- * @return
- */
- public boolean moveTo(int index) {
- index -= offset;
- if (index >= 0 && index < size() ) {
- this.index = index;
- return true;
- }
- return false;
- }
-
- /**
- * Moves the history index to the first entry.
- *
- * @return Return false if there are no entries in the history or if the
- * history is already at the beginning.
- */
- public boolean moveToFirst() {
- if (size() > 0 && index != 0) {
- index = 0;
- return true;
- }
-
- return false;
- }
-
- /**
- * Move to the end of the history buffer. This will be a blank entry, after
- * all of the other entries.
- */
- public void moveToEnd() {
- index = size();
- }
-
- /**
- * Return the content of the current buffer.
- */
- public CharSequence current() {
- if (index >= size()) {
- return "";
- }
-
- return items.get(index);
- }
-
- /**
- * Move the pointer to the previous element in the buffer.
- *
- * @return true if we successfully went to the previous element
- */
- public boolean previous() {
- if (index <= 0) {
- return false;
- }
-
- index--;
-
- return true;
- }
-
- /**
- * Move the pointer to the next element in the buffer.
- *
- * @return true if we successfully went to the next element
- */
- public boolean next() {
- if (index >= size()) {
- return false;
- }
-
- index++;
-
- return true;
- }
-
-
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/history/PersistentHistory.java b/src/jline/src/main/java/scala/tools/jline/console/history/PersistentHistory.java
deleted file mode 100644
index 916532e7fc..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/history/PersistentHistory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.console.history;
-
-import java.io.IOException;
-
-/**
- * Persistent {@link History}.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.3
- */
-public interface PersistentHistory
- extends History
-{
- /**
- * Flush all items to persistent storage.
- *
- * @throws IOException Flush failed
- */
- void flush() throws IOException;
-
- /**
- * Purge persistent storage and {@link #clear}.
- *
- * @throws IOException Purge failed
- */
- void purge() throws IOException;
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/history/package-info.java b/src/jline/src/main/java/scala/tools/jline/console/history/package-info.java
deleted file mode 100644
index 4635752898..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/history/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2009 the original author(s).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Console history support.
- *
- * @since 2.0
- */
-package scala.tools.jline.console.history; \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/console/package-info.java b/src/jline/src/main/java/scala/tools/jline/console/package-info.java
deleted file mode 100644
index 9f284e9c05..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/console/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2009 the original author(s).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Console support.
- *
- * @since 2.0
- */
-package scala.tools.jline.console; \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/internal/Configuration.java b/src/jline/src/main/java/scala/tools/jline/internal/Configuration.java
deleted file mode 100644
index 5350d6c19e..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/internal/Configuration.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package scala.tools.jline.internal;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-/**
- * Provides access to configuration values.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.4
- */
-public final class Configuration
-{
- public static final String JLINE_RC = ".jline.rc";
-
- private static final Properties userprops;
-
- static {
- Properties props = new Properties();
-
- File file = new File(getUserHome(), JLINE_RC);
- if (file.exists() && file.canRead()) {
- try {
- InputStream input = new BufferedInputStream(new FileInputStream(file));
- try {
- props.load(input);
- Log.debug("Loaded user configuration: ", file);
- }
- finally {
- input.close();
- }
- }
- catch (IOException e) {
- Log.warn("Unable to read user configuration: ", file, e);
- }
- }
- else {
- Log.trace("User configuration file missing or unreadable: ", file);
- }
-
- userprops = props;
- }
-
- private static boolean isEmpty(final String value) {
- return value == null || value.trim().length() == 0;
- }
-
- public static String getString(final String name, final String defaultValue) {
- assert name != null;
-
- String value;
-
- // Check sysprops first, it always wins
- value = System.getProperty(name);
-
- if (isEmpty(value)) {
- // Next try userprops
- value = userprops.getProperty(name);
-
- if (isEmpty(value)) {
- // else use the default
- value = defaultValue;
- }
- }
-
- return value;
- }
-
- public static String getString(final String name) {
- return getString(name, null);
- }
-
- public static Boolean getBoolean(final String name, final Boolean defaultValue) {
- String value = getString(name);
- if (isEmpty(value)) {
- return defaultValue;
- }
- return Boolean.valueOf(value);
- }
-
- public static Boolean getBoolean(final String name) {
- return getBoolean(name, null);
- }
-
- //
- // System property helpers
- //
-
- public static File getUserHome() {
- return new File(System.getProperty("user.home"));
- }
-
- public static String getOsName() {
- return System.getProperty("os.name").toLowerCase();
- }
-
- public static String getFileEncoding() {
- return System.getProperty("file.encoding");
- }
-
- public static String getInputEncoding() {
- return System.getProperty("input.encoding", "UTF-8");
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/internal/Log.java b/src/jline/src/main/java/scala/tools/jline/internal/Log.java
deleted file mode 100644
index b226a10532..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/internal/Log.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package scala.tools.jline.internal;
-
-import java.io.PrintStream;
-
-/**
- * Internal logger.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public final class Log
-{
- ///CLOVER:OFF
-
- public static enum Level
- {
- TRACE,
- DEBUG,
- INFO,
- WARN,
- ERROR
- }
-
- @SuppressWarnings({"StringConcatenation"})
- public static final boolean DEBUG = Boolean.getBoolean(Log.class.getName() + ".debug");
-
- @SuppressWarnings({"StringConcatenation"})
- public static final boolean TRACE = Boolean.getBoolean(Log.class.getName() + ".trace");
-
- private static PrintStream output = System.err;
-
- public static PrintStream getOutput() {
- return output;
- }
-
- public static void setOutput(final PrintStream out) {
- assert out != null;
- output = out;
- }
-
- private static void print(final Object message) {
- if (message instanceof Throwable) {
- ((Throwable) message).printStackTrace();
- }
- else if (message.getClass().isArray()) {
- Object[] array = (Object[]) message;
-
- for (int i = 0; i < array.length; i++) {
- output.print(array[i]);
- if (i + 1 < array.length) {
- output.print(",");
- }
- }
- }
- else {
- output.print(message);
- }
- }
-
- private static void log(final Level level, final Object[] messages) {
- //noinspection SynchronizeOnNonFinalField
- synchronized (output) {
- output.format("[%s] ", level);
-
- for (Object message : messages) {
- print(message);
- }
-
- output.println();
- output.flush();
- }
- }
-
- public static void trace(final Object... messages) {
- if (TRACE) {
- log(Level.TRACE, messages);
- }
- }
-
- public static void debug(final Object... messages) {
- if (TRACE || DEBUG) {
- log(Level.DEBUG, messages);
- }
- }
-
- public static void warn(final Object... messages) {
- log(Level.WARN, messages);
- }
-
- public static void error(final Object... messages) {
- log(Level.ERROR, messages);
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/internal/ReplayPrefixOneCharInputStream.java b/src/jline/src/main/java/scala/tools/jline/internal/ReplayPrefixOneCharInputStream.java
deleted file mode 100644
index 2adabdd2ab..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/internal/ReplayPrefixOneCharInputStream.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package scala.tools.jline.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.MessageFormat;
-
-/**
- * This is awkward and inefficient, but probably the minimal way to add UTF-8 support to JLine
- *
- * @author <a href="mailto:Marc.Herbert@continuent.com">Marc Herbert</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @since 2.0
- */
-public final class ReplayPrefixOneCharInputStream
- extends InputStream
-{
- private byte firstByte;
-
- private int byteLength;
-
- private InputStream wrappedStream;
-
- private int byteRead;
-
- private final String encoding;
-
- public ReplayPrefixOneCharInputStream(final String encoding) {
- assert encoding != null;
- this.encoding = encoding;
- }
-
- public String getEncoding() {
- return encoding;
- }
-
- public void setInput(final int recorded, final InputStream wrapped) throws IOException {
- this.byteRead = 0;
- this.firstByte = (byte) recorded;
- this.wrappedStream = wrapped;
-
- byteLength = 1;
- if (encoding.equalsIgnoreCase("UTF-8")) {
- setInputUTF8(recorded, wrapped);
- }
- else if (encoding.equalsIgnoreCase("UTF-16")) {
- byteLength = 2;
- }
- else if (encoding.equalsIgnoreCase("UTF-32")) {
- byteLength = 4;
- }
- }
-
-
- public void setInputUTF8(final int recorded, final InputStream wrapped) throws IOException {
- // 110yyyyy 10zzzzzz
- if ((firstByte & (byte) 0xE0) == (byte) 0xC0) {
- this.byteLength = 2;
- }
- // 1110xxxx 10yyyyyy 10zzzzzz
- else if ((firstByte & (byte) 0xF0) == (byte) 0xE0) {
- this.byteLength = 3;
- }
- // 11110www 10xxxxxx 10yyyyyy 10zzzzzz
- else if ((firstByte & (byte) 0xF8) == (byte) 0xF0) {
- this.byteLength = 4;
- }
- else {
- throw new IOException(MessageFormat.format("Invalid UTF-8 first byte: {0}", firstByte));
- }
- }
-
- public int read() throws IOException {
- if (available() == 0) {
- return -1;
- }
-
- byteRead++;
-
- if (byteRead == 1) {
- return firstByte;
- }
-
- return wrappedStream.read();
- }
-
- /**
- * InputStreamReader is greedy and will try to read bytes in advance. We
- * do NOT want this to happen since we use a temporary/"losing bytes"
- * InputStreamReader above, that's why we hide the real
- * wrappedStream.available() here.
- */
- public int available() {
- return byteLength - byteRead;
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/internal/TerminalLineSettings.java b/src/jline/src/main/java/scala/tools/jline/internal/TerminalLineSettings.java
deleted file mode 100644
index 151862c14d..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/internal/TerminalLineSettings.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-
-package scala.tools.jline.internal;
-
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.MessageFormat;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Provides access to terminal line settings via <tt>stty</tt>.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- * @author <a href="mailto:dwkemp@gmail.com">Dale Kemp</a>
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- * @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofré</a>
- * @since 2.0
- */
-public final class TerminalLineSettings
-{
- public static final String JLINE_STTY = "jline.stty";
-
- public static final String DEFAULT_STTY = "stty";
-
- public static final String JLINE_SH = "jline.sh";
-
- public static final String DEFAULT_SH = "sh";
-
- private static String sttyCommand = Configuration.getString(JLINE_STTY, DEFAULT_STTY);
-
- private static String shCommand = Configuration.getString(JLINE_SH, DEFAULT_SH);
-
- private String config;
-
- private long configLastFetched;
-
- public TerminalLineSettings() throws IOException, InterruptedException {
- config = get("-a");
- configLastFetched = System.currentTimeMillis();
-
- Log.debug("Config: ", config);
-
- // sanity check
- if (config.length() == 0) {
- throw new IOException(MessageFormat.format("Unrecognized stty code: {0}", config));
- }
- }
-
- public String getConfig() {
- return config;
- }
-
- public void restore() throws IOException, InterruptedException {
- set("sane");
- }
-
- public String get(final String args) throws IOException, InterruptedException {
- return stty(args);
- }
-
- public void set(final String args) throws IOException, InterruptedException {
- stty(args);
- }
-
- /**
- * <p>
- * Get the value of a stty property, including the management of a cache.
- * </p>
- *
- * @param name the stty property.
- * @return the stty property value.
- */
- public int getProperty(String name) {
- assert name != null;
- try {
- // tty properties are cached so we don't have to worry too much about getting term widht/height
- if (config == null || System.currentTimeMillis() - configLastFetched > 1000 ) {
- config = get("-a");
- configLastFetched = System.currentTimeMillis();
- }
- return this.getProperty(name, config);
- } catch (Exception e) {
- Log.warn("Failed to query stty ", name, e);
- return -1;
- }
- }
-
- /**
- * <p>
- * Parses a stty output (provided by stty -a) and return the value of a given property.
- * </p>
- *
- * @param name property name.
- * @param stty string resulting of stty -a execution.
- * @return value of the given property.
- */
- protected int getProperty(String name, String stty) {
- // try the first kind of regex
- Pattern pattern = Pattern.compile(name + "\\s+=\\s+([^;]*)[;\\n\\r]");
- Matcher matcher = pattern.matcher(stty);
- if (!matcher.find()) {
- // try a second kind of regex
- pattern = Pattern.compile(name + "\\s+([^;]*)[;\\n\\r]");
- matcher = pattern.matcher(stty);
- if (!matcher.find()) {
- // try a second try of regex
- pattern = Pattern.compile("(\\S*)\\s+" + name);
- matcher = pattern.matcher(stty);
- if (!matcher.find()) {
- return -1;
- }
- }
- }
- return parseControlChar(matcher.group(1));
- }
-
- private int parseControlChar(String str) {
- // under
- if ("<undef>".equals(str)) {
- return -1;
- }
- // octal
- if (str.charAt(0) == '0') {
- return Integer.parseInt(str, 8);
- }
- // decimal
- if (str.charAt(0) >= '1' && str.charAt(0) <= '9') {
- return Integer.parseInt(str, 10);
- }
- // control char
- if (str.charAt(0) == '^') {
- if (str.charAt(1) == '?') {
- return 127;
- } else {
- return str.charAt(1) - 64;
- }
- } else if (str.charAt(0) == 'M' && str.charAt(1) == '-') {
- if (str.charAt(2) == '^') {
- if (str.charAt(3) == '?') {
- return 127 + 128;
- } else {
- return str.charAt(3) - 64 + 128;
- }
- } else {
- return str.charAt(2) + 128;
- }
- } else {
- return str.charAt(0);
- }
- }
-
- private static String stty(final String args) throws IOException, InterruptedException {
- assert args != null;
- return exec(String.format("%s %s < /dev/tty", sttyCommand, args));
- }
-
- private static String exec(final String cmd) throws IOException, InterruptedException {
- assert cmd != null;
- return exec(shCommand, "-c", cmd);
- }
-
- private static String exec(final String... cmd) throws IOException, InterruptedException {
- assert cmd != null;
-
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
-
- Log.trace("Running: ", cmd);
-
- Process p = Runtime.getRuntime().exec(cmd);
-
- InputStream in = null;
- InputStream err = null;
- OutputStream out = null;
- try {
- int c;
- in = p.getInputStream();
- while ((c = in.read()) != -1) {
- bout.write(c);
- }
- err = p.getErrorStream();
- while ((c = err.read()) != -1) {
- bout.write(c);
- }
- out = p.getOutputStream();
- p.waitFor();
- }
- finally {
- close(in, out, err);
- }
-
- String result = bout.toString();
-
- Log.trace("Result: ", result);
-
- return result;
- }
-
- private static void close(final Closeable... closeables) {
- for (Closeable c : closeables) {
- try {
- c.close();
- }
- catch (Exception e) {
- // Ignore
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/internal/package-info.java b/src/jline/src/main/java/scala/tools/jline/internal/package-info.java
deleted file mode 100644
index d27444cfdf..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/internal/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2009 the original author(s).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Internal support.
- *
- * @since 2.0
- */
-package scala.tools.jline.internal; \ No newline at end of file
diff --git a/src/jline/src/main/java/scala/tools/jline/package-info.java b/src/jline/src/main/java/scala/tools/jline/package-info.java
deleted file mode 100644
index fde16f98de..0000000000
--- a/src/jline/src/main/java/scala/tools/jline/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2009 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * JLine 2.
- *
- * @since 2.0
- */
-package scala.tools.jline; \ No newline at end of file
diff --git a/src/jline/src/main/resources/scala/tools/jline/console/completer/CandidateListCompletionHandler.properties b/src/jline/src/main/resources/scala/tools/jline/console/completer/CandidateListCompletionHandler.properties
deleted file mode 100644
index fd097efb8a..0000000000
--- a/src/jline/src/main/resources/scala/tools/jline/console/completer/CandidateListCompletionHandler.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-DISPLAY_CANDIDATES=Display all %d possibilities? (y or n)
-DISPLAY_CANDIDATES_YES=y
-DISPLAY_CANDIDATES_NO=n
-DISPLAY_MORE=--More--
diff --git a/src/jline/src/main/resources/scala/tools/jline/keybindings.properties b/src/jline/src/main/resources/scala/tools/jline/keybindings.properties
deleted file mode 100644
index ad932d2a80..0000000000
--- a/src/jline/src/main/resources/scala/tools/jline/keybindings.properties
+++ /dev/null
@@ -1,71 +0,0 @@
-# Keybinding mapping for JLine. The format is:
-# [key code]=[logical operation]
-
-# CTRL-A: move to the beginning of the line
-1=MOVE_TO_BEG
-
-# CTRL-B: move to the previous character
-2=PREV_CHAR
-
-# CTRL-D: close out the input stream
-4=EXIT
-
-# CTRL-E: move the cursor to the end of the line
-5=MOVE_TO_END
-
-# CTRL-F: move to the next character
-6=NEXT_CHAR
-
-# CTRL-G: abort
-7=ABORT
-
-# BACKSPACE, CTRL-H: delete the previous character
-# 8 is the ASCII code for backspace and therefor
-# deleting the previous character
-8=DELETE_PREV_CHAR
-
-# TAB, CTRL-I: signal that console completion should be attempted
-9=COMPLETE
-
-# CTRL-J, CTRL-M: newline
-10=NEWLINE
-
-# CTRL-K: erase the current line
-11=KILL_LINE
-
-# CTRL-L: clear screen
-12=CLEAR_SCREEN
-
-# ENTER: newline
-13=NEWLINE
-
-# CTRL-N: scroll to the next element in the history buffer
-14=NEXT_HISTORY
-
-# CTRL-O: move to the previous word
-15=PREV_WORD
-
-# CTRL-P: scroll to the previous element in the history buffer
-16=PREV_HISTORY
-
-# CTRL-R: search history
-18=SEARCH_PREV
-
-# CTRL-T: move to next word
-20=NEXT_WORD
-
-# CTRL-U: delete all the characters before the cursor position
-21=KILL_LINE_PREV
-
-# CTRL-V: paste the contents of the clipboard (useful for Windows terminal)
-22=PASTE
-
-# CTRL-W: delete the word directly before the cursor
-23=DELETE_PREV_WORD
-
-# CTRL-X: delete the word directly after the cursor
-24=DELETE_NEXT_WORD
-
-# DELETE, CTRL-?: delete the next character
-# 127 is the ASCII code for delete
-127=DELETE_NEXT_CHAR
diff --git a/src/jline/src/main/resources/scala/tools/jline/windowsbindings.properties b/src/jline/src/main/resources/scala/tools/jline/windowsbindings.properties
deleted file mode 100644
index 340b5aa5b9..0000000000
--- a/src/jline/src/main/resources/scala/tools/jline/windowsbindings.properties
+++ /dev/null
@@ -1,71 +0,0 @@
-# Keybinding mapping for JLine. The format is:
-# [key code]=[logical operation]
-
-# CTRL-A: move to the beginning of the line
-1=MOVE_TO_BEG
-
-# CTRL-B: move to the previous character
-2=PREV_CHAR
-
-# CTRL-C: toggle overtype mode (frankly, I wasn't sure where to bind this)
-3=INSERT
-
-# CTRL-D: close out the input stream
-4=EXIT
-
-# CTRL-E: move the cursor to the end of the line
-5=MOVE_TO_END
-
-# CTRL-F: move to the next character
-6=NEXT_CHAR
-
-# CTRL-G: move to the previous word
-7=ABORT
-
-# CTRL-H: delete the previous character
-8=DELETE_PREV_CHAR
-
-# TAB, CTRL-I: signal that console completion should be attempted
-9=COMPLETE
-
-# CTRL-J, CTRL-M: newline
-10=NEWLINE
-
-# CTRL-K: erase the current line
-11=KILL_LINE
-
-# CTRL-L: clear screen
-12=CLEAR_SCREEN
-
-# ENTER: newline
-13=NEWLINE
-
-# CTRL-N: scroll to the next element in the history buffer
-14=NEXT_HISTORY
-
-# CTRL-O: move to the previous word
-15=PREV_WORD
-
-# CTRL-P: scroll to the previous element in the history buffer
-16=PREV_HISTORY
-
-# CTRL-R: search backwards in history
-18=SEARCH_PREV
-
-# CTRL-S: Move to the end of the history
-19=END_OF_HISTORY
-
-# CTRL-U: delete all the characters before the cursor position
-21=KILL_LINE_PREV
-
-# CTRL-V: paste the contents of the clipboard (useful for Windows terminal)
-22=PASTE
-
-# CTRL-W: delete the word directly before the cursor
-23=DELETE_PREV_WORD
-
-# CTRL-[: escape - clear the current line.
-27=CLEAR_LINE
-
-# CTRL-?: delete the previous character
-127=DELETE_NEXT_CHAR
diff --git a/src/jline/src/test/java/scala/tools/jline/TerminalFactoryTest.java b/src/jline/src/test/java/scala/tools/jline/TerminalFactoryTest.java
deleted file mode 100644
index c0c070bdfd..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/TerminalFactoryTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package scala.tools.jline;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Tests for the {@link TerminalFactory}.
- */
-public class TerminalFactoryTest
-{
- @Before
- public void setUp() throws Exception {
- TerminalFactory.reset();
- }
-
- @Test
- public void testConfigureNone() {
- TerminalFactory.configure(TerminalFactory.NONE);
- Terminal t = TerminalFactory.get();
- assertNotNull(t);
- assertEquals(UnsupportedTerminal.class.getName(), t.getClass().getName());
- }
-
- @Test
- public void testConfigureUnsupportedTerminal() {
- TerminalFactory.configure(UnsupportedTerminal.class.getName());
- Terminal t = TerminalFactory.get();
- assertNotNull(t);
- assertEquals(UnsupportedTerminal.class.getName(), t.getClass().getName());
- }
-} \ No newline at end of file
diff --git a/src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTest.java b/src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTest.java
deleted file mode 100644
index 0e6cba15a0..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTest.java
+++ /dev/null
@@ -1,261 +0,0 @@
-package scala.tools.jline.console;
-
-import scala.tools.jline.TerminalFactory;
-import scala.tools.jline.WindowsTerminal;
-import scala.tools.jline.console.history.History;
-import scala.tools.jline.console.history.MemoryHistory;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.io.Writer;
-
-import static scala.tools.jline.WindowsTerminal.WindowsKey.DELETE_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.END_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.ESCAPE_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.HOME_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.INSERT_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.LEFT_ARROW_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.NUMPAD_KEY_INDICATOR;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.PAGE_DOWN_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.PAGE_UP_KEY;
-import static scala.tools.jline.WindowsTerminal.WindowsKey.SPECIAL_KEY_INDICATOR;
-import static scala.tools.jline.console.Operation.DELETE_NEXT_CHAR;
-import static scala.tools.jline.console.Operation.DELETE_PREV_CHAR;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Tests for the {@link ConsoleReader}.
- */
-public class ConsoleReaderTest
-{
- @Before
- public void setUp() throws Exception {
- System.setProperty(WindowsTerminal.JLINE_WINDOWS_TERMINAL_DIRECT_CONSOLE, "false");
- }
-
- private void assertWindowsKeyBehavior(String expected, char[] input) throws Exception {
- StringBuilder buffer = new StringBuilder();
- buffer.append(input);
- ConsoleReader reader = createConsole(buffer.toString().getBytes());
- assertNotNull(reader);
- String line = reader.readLine();
- assertEquals(expected, line);
- }
-
- private ConsoleReader createConsole(byte[] bytes) throws Exception {
- InputStream in = new ByteArrayInputStream(bytes);
- Writer writer = new StringWriter();
- ConsoleReader reader = new ConsoleReader(in, writer);
- reader.setHistory(createSeededHistory());
- return reader;
- }
-
- private History createSeededHistory() {
- History history = new MemoryHistory();
- history.add("dir");
- history.add("cd c:\\");
- history.add("mkdir monkey");
- return history;
- }
-
- @Test
- public void testDeleteAndBackspaceKeymappings() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- ConsoleReader consoleReader = new ConsoleReader();
- assertNotNull(consoleReader);
- assertEquals(127, consoleReader.getKeyForAction(DELETE_NEXT_CHAR));
- assertEquals(8, consoleReader.getKeyForAction(DELETE_PREV_CHAR));
- }
-
- @Test
- public void testReadline() throws Exception {
- ConsoleReader consoleReader = createConsole("Sample String\r\n".getBytes());
- assertNotNull(consoleReader);
- String line = consoleReader.readLine();
- assertEquals("Sample String", line);
- }
-
- @Test
- public void testDeleteOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- 'S', 's',
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) LEFT_ARROW_KEY.code,
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) DELETE_KEY.code, '\r', 'n'
- };
- assertWindowsKeyBehavior("S", characters);
- }
-
- @Test
- public void testNumpadDeleteOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- 'S', 's',
- (char) NUMPAD_KEY_INDICATOR.code,
- (char) LEFT_ARROW_KEY.code,
- (char) NUMPAD_KEY_INDICATOR.code,
- (char) DELETE_KEY.code, '\r', 'n'
- };
- assertWindowsKeyBehavior("S", characters);
- }
-
- @Test
- public void testHomeKeyOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- 'S', 's',
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) HOME_KEY.code, 'x', '\r', '\n'
- };
- assertWindowsKeyBehavior("xSs", characters);
-
- }
-
- @Test
- public void testEndKeyOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- 'S', 's',
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) HOME_KEY.code, 'x',
- (char) SPECIAL_KEY_INDICATOR.code, (char) END_KEY.code,
- 'j', '\r', '\n'
- };
- assertWindowsKeyBehavior("xSsj", characters);
- }
-
- @Test
- public void testPageUpOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) PAGE_UP_KEY.code, '\r', '\n'
- };
- assertWindowsKeyBehavior("dir", characters);
- }
-
- @Test
- public void testPageDownOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) PAGE_DOWN_KEY.code, '\r', '\n'
- };
- assertWindowsKeyBehavior("mkdir monkey", characters);
- }
-
- @Test
- public void testEscapeOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- 's', 's', 's',
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) ESCAPE_KEY.code, '\r', '\n'
- };
- assertWindowsKeyBehavior("", characters);
- }
-
- @Test
- public void testInsertOnWindowsTerminal() throws Exception {
- // test only works on Windows
- if (!(TerminalFactory.get() instanceof WindowsTerminal)) {
- return;
- }
-
- char[] characters = new char[]{
- 'o', 'p', 's',
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) HOME_KEY.code,
- (char) SPECIAL_KEY_INDICATOR.code,
- (char) INSERT_KEY.code, 'o', 'o', 'p', 's', '\r', '\n'
- };
- assertWindowsKeyBehavior("oops", characters);
- }
-
- @Test
- public void testExpansion() throws Exception {
- ConsoleReader reader = new ConsoleReader();
- MemoryHistory history = new MemoryHistory();
- history.setMaxSize(3);
- history.add("foo");
- history.add("dir");
- history.add("cd c:\\");
- history.add("mkdir monkey");
- reader.setHistory(history);
-
- assertEquals("echo a!", reader.expandEvents("echo a!"));
- assertEquals("mkdir monkey ; echo a!", reader.expandEvents("!! ; echo a!"));
- assertEquals("echo ! a", reader.expandEvents("echo ! a"));
- assertEquals("echo !\ta", reader.expandEvents("echo !\ta"));
-
- assertEquals("mkdir barey", reader.expandEvents("^monk^bar^"));
- assertEquals("mkdir barey", reader.expandEvents("^monk^bar"));
- assertEquals("a^monk^bar", reader.expandEvents("a^monk^bar"));
-
- assertEquals("mkdir monkey", reader.expandEvents("!!"));
- assertEquals("echo echo a", reader.expandEvents("echo !#a"));
-
- assertEquals("mkdir monkey", reader.expandEvents("!mk"));
- try {
- reader.expandEvents("!mz");
- } catch (IllegalArgumentException e) {
- assertEquals("!mz: event not found", e.getMessage());
- }
-
- assertEquals("mkdir monkey", reader.expandEvents("!?mo"));
- assertEquals("mkdir monkey", reader.expandEvents("!?mo?"));
-
- assertEquals("mkdir monkey", reader.expandEvents("!-1"));
- assertEquals("cd c:\\", reader.expandEvents("!-2"));
- assertEquals("cd c:\\", reader.expandEvents("!2"));
- assertEquals("mkdir monkey", reader.expandEvents("!3"));
- try {
- reader.expandEvents("!20");
- } catch (IllegalArgumentException e) {
- assertEquals("!20: event not found", e.getMessage());
- }
- try {
- reader.expandEvents("!-20");
- } catch (IllegalArgumentException e) {
- assertEquals("!-20: event not found", e.getMessage());
- }
- }
-}
diff --git a/src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTestSupport.java b/src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTestSupport.java
deleted file mode 100644
index c19099f0b2..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/ConsoleReaderTestSupport.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-package scala.tools.jline.console;
-
-import scala.tools.jline.UnixTerminal;
-import org.junit.Before;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-
-import static scala.tools.jline.UnixTerminal.UnixKey.ARROW_DOWN;
-import static scala.tools.jline.UnixTerminal.UnixKey.ARROW_LEFT;
-import static scala.tools.jline.UnixTerminal.UnixKey.ARROW_PREFIX;
-import static scala.tools.jline.UnixTerminal.UnixKey.ARROW_RIGHT;
-import static scala.tools.jline.UnixTerminal.UnixKey.ARROW_START;
-import static scala.tools.jline.UnixTerminal.UnixKey.ARROW_UP;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-/**
- * Provides support for console reader tests.
- */
-public abstract class ConsoleReaderTestSupport
-{
- protected ConsoleReader console;
-
- @Before
- public void setUp() throws Exception {
- console = new ConsoleReader(null, new PrintWriter(new OutputStreamWriter(new ByteArrayOutputStream())), new UnixTerminal());
- }
-
- protected void assertBuffer(final String expected, final Buffer buffer) throws IOException {
- assertBuffer(expected, buffer, true);
- }
-
- protected void assertBuffer(final String expected, final Buffer buffer, final boolean clear) throws IOException {
- // clear current buffer, if any
- if (clear) {
- console.finishBuffer();
- console.getHistory().clear();
- }
-
- console.setInput(new ByteArrayInputStream(buffer.getBytes()));
-
- // run it through the reader
- while (console.readLine((String) null) != null) {
- // ignore
- }
-
- assertEquals(expected, console.getCursorBuffer().toString());
- }
-
- private int getKeyForAction(final Operation key) {
- return getKeyForAction(key.code);
- }
-
- private int getKeyForAction(final short logicalAction) {
- int action = console.getKeyForAction(logicalAction);
-
- if (action == -1) {
- console.printBindings();
- fail("Keystroke for logical action " + logicalAction + " was not bound in the console");
- }
-
- return action;
- }
-
- protected class Buffer
- {
- private final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- public Buffer() {
- // nothing
- }
-
- public Buffer(final String str) {
- append(str);
- }
-
- public byte[] getBytes() {
- return out.toByteArray();
- }
-
- public Buffer op(final short operation) {
- return append(getKeyForAction(operation));
- }
-
- public Buffer op(final Operation op) {
- return op(op.code);
- }
-
- public Buffer ctrlA() {
- return append(getKeyForAction(Operation.MOVE_TO_BEG));
- }
-
- public Buffer ctrlU() {
- return append(getKeyForAction(Operation.KILL_LINE_PREV));
- }
-
- public Buffer tab() {
- return append(getKeyForAction(Operation.COMPLETE));
- }
-
- public Buffer back() {
- return append(getKeyForAction(Operation.DELETE_PREV_CHAR));
- }
-
- public Buffer left() {
- return append(ARROW_START.code).append(ARROW_PREFIX.code).append(ARROW_LEFT.code);
- }
-
- public Buffer right() {
- return append(ARROW_START.code).append(ARROW_PREFIX.code).append(ARROW_RIGHT.code);
- }
-
- public Buffer up() {
- return append(ARROW_START.code).append(ARROW_PREFIX.code).append(ARROW_UP.code);
- }
-
- public Buffer down() {
- return append(ARROW_START.code).append(ARROW_PREFIX.code).append(ARROW_DOWN.code);
- }
-
- public Buffer append(final String str) {
- for (byte b : str.getBytes()) {
- append(b);
- }
- return this;
- }
-
- public Buffer append(final int i) {
- out.write((byte) i);
- return this;
- }
- }
-}
diff --git a/src/jline/src/test/java/scala/tools/jline/console/EditLineTest.java b/src/jline/src/test/java/scala/tools/jline/console/EditLineTest.java
deleted file mode 100644
index 6f5d46121e..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/EditLineTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-package scala.tools.jline.console;
-
-import org.junit.Test;
-
-import static scala.tools.jline.console.Operation.*;
-
-/**
- * Tests various features of editing lines.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
-public class EditLineTest
- extends ConsoleReaderTestSupport
-{
- @Test
- public void testDeletePreviousWord() throws Exception {
- Buffer b = new Buffer("This is a test");
-
- assertBuffer("This is a ", b = b.op(DELETE_PREV_WORD));
- assertBuffer("This is ", b = b.op(DELETE_PREV_WORD));
- assertBuffer("This ", b = b.op(DELETE_PREV_WORD));
- assertBuffer("", b = b.op(DELETE_PREV_WORD));
- assertBuffer("", b = b.op(DELETE_PREV_WORD));
- assertBuffer("", b.op(DELETE_PREV_WORD));
- }
-
- @Test
- public void testDeleteNextWord() throws Exception {
- Buffer b = new Buffer("This is a test ");
-
- assertBuffer(" is a test ", b = b.op(MOVE_TO_BEG).op(DELETE_NEXT_WORD));
- assertBuffer(" a test ", b = b.op(DELETE_NEXT_WORD));
- assertBuffer(" test ", b = b.op(DELETE_NEXT_WORD));
- assertBuffer(" ", b = b.op(DELETE_NEXT_WORD));
- assertBuffer("", b = b.op(DELETE_NEXT_WORD));
- assertBuffer("", b.op(DELETE_NEXT_WORD));
- }
-
- @Test
- public void testMoveToEnd() throws Exception {
- Buffer b = new Buffer("This is a test");
-
- assertBuffer("This is a XtestX",
- new Buffer("This is a test").op(PREV_WORD)
- .append('X')
- .op(MOVE_TO_END)
- .append('X'));
-
- assertBuffer("This is Xa testX",
- new Buffer("This is a test").op(PREV_WORD)
- .op(PREV_WORD)
- .append('X')
- .op(MOVE_TO_END)
- .append('X'));
-
- assertBuffer("This Xis a testX",
- new Buffer("This is a test").op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .append('X')
- .op(MOVE_TO_END)
- .append('X'));
- }
-
- @Test
- public void testPreviousWord() throws Exception {
- assertBuffer("This is a Xtest",
- new Buffer("This is a test").op(PREV_WORD)
- .append('X'));
- assertBuffer("This is Xa test",
- new Buffer("This is a test").op(PREV_WORD)
- .op(PREV_WORD)
- .append('X'));
- assertBuffer("This Xis a test",
- new Buffer("This is a test").op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .append('X'));
- assertBuffer("XThis is a test",
- new Buffer("This is a test").op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .append('X'));
- assertBuffer("XThis is a test",
- new Buffer("This is a test").op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .append('X'));
- assertBuffer("XThis is a test",
- new Buffer("This is a test").op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .op(PREV_WORD)
- .append('X'));
- }
-
- @Test
- public void testNextWord() throws Exception {
- assertBuffer("ThisX is a test",
- new Buffer("This is a test").op(MOVE_TO_BEG)
- .op(NEXT_WORD)
- .append('X'));
- assertBuffer("This isX a test",
- new Buffer("This is a test").op(MOVE_TO_BEG)
- .op(NEXT_WORD)
- .op(NEXT_WORD)
- .append('X'));
- assertBuffer("This is aX test",
- new Buffer("This is a test").op(MOVE_TO_BEG)
- .op(NEXT_WORD)
- .op(NEXT_WORD)
- .op(NEXT_WORD)
- .append('X'));
- assertBuffer("This is a testX ",
- new Buffer("This is a test ").op(MOVE_TO_BEG)
- .op(NEXT_WORD)
- .op(NEXT_WORD)
- .op(NEXT_WORD)
- .op(NEXT_WORD)
- .append('X'));
- }
-
- @Test
- public void testLineStart() throws Exception {
- assertBuffer("XThis is a test",
- new Buffer("This is a test").ctrlA().append('X'));
- assertBuffer("TXhis is a test",
- new Buffer("This is a test").ctrlA().right().append('X'));
- }
-
- @Test
- public void testClearLine() throws Exception {
- assertBuffer("", new Buffer("This is a test").ctrlU());
- assertBuffer("t", new Buffer("This is a test").left().ctrlU());
- assertBuffer("st", new Buffer("This is a test").left().left().ctrlU());
- }
-
- @Test
- public void testRight() throws Exception {
- Buffer b = new Buffer("This is a test");
- b = b.left().right().back();
- assertBuffer("This is a tes", b);
- b = b.left().left().left().right().left().back();
- assertBuffer("This is ates", b);
- b.append('X');
- assertBuffer("This is aXtes", b);
- }
-
- @Test
- public void testLeft() throws Exception {
- Buffer b = new Buffer("This is a test");
- b = b.left().left().left();
- assertBuffer("This is a est", b = b.back());
- assertBuffer("This is aest", b = b.back());
- assertBuffer("This is est", b = b.back());
- assertBuffer("This isest", b = b.back());
- assertBuffer("This iest", b = b.back());
- assertBuffer("This est", b = b.back());
- assertBuffer("Thisest", b = b.back());
- assertBuffer("Thiest", b = b.back());
- assertBuffer("Thest", b = b.back());
- assertBuffer("Test", b = b.back());
- assertBuffer("est", b = b.back());
- assertBuffer("est", b = b.back());
- assertBuffer("est", b = b.back());
- assertBuffer("est", b = b.back());
- assertBuffer("est", b.back());
- }
-
- @Test
- public void testBackspace() throws Exception {
- Buffer b = new Buffer("This is a test");
- assertBuffer("This is a tes", b = b.back());
- assertBuffer("This is a te", b = b.back());
- assertBuffer("This is a t", b = b.back());
- assertBuffer("This is a ", b = b.back());
- assertBuffer("This is a", b = b.back());
- assertBuffer("This is ", b = b.back());
- assertBuffer("This is", b = b.back());
- assertBuffer("This i", b = b.back());
- assertBuffer("This ", b = b.back());
- assertBuffer("This", b = b.back());
- assertBuffer("Thi", b = b.back());
- assertBuffer("Th", b = b.back());
- assertBuffer("T", b = b.back());
- assertBuffer("", b = b.back());
- assertBuffer("", b = b.back());
- assertBuffer("", b = b.back());
- assertBuffer("", b = b.back());
- assertBuffer("", b.back());
- }
-
- @Test
- public void testBuffer() throws Exception {
- assertBuffer("This is a test", new Buffer("This is a test"));
- }
-}
diff --git a/src/jline/src/test/java/scala/tools/jline/console/completer/ArgumentCompleterTest.java b/src/jline/src/test/java/scala/tools/jline/console/completer/ArgumentCompleterTest.java
deleted file mode 100644
index 9e2a2ab031..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/completer/ArgumentCompleterTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2010 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package scala.tools.jline.console.completer;
-
-import scala.tools.jline.console.ConsoleReaderTestSupport;
-import scala.tools.jline.console.completer.ArgumentCompleter;
-import scala.tools.jline.console.completer.StringsCompleter;
-import org.junit.Test;
-
-/**
- * Tests for {@link jline.console.completer.ArgumentCompleter}.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
-public class ArgumentCompleterTest
- extends ConsoleReaderTestSupport
-{
- @Test
- public void test1() throws Exception {
- console.addCompleter(new ArgumentCompleter(new StringsCompleter("foo", "bar", "baz")));
-
- assertBuffer("foo foo ", new Buffer("foo f").tab());
- assertBuffer("foo ba", new Buffer("foo b").tab());
- assertBuffer("foo ba", new Buffer("foo ba").tab());
- assertBuffer("foo baz ", new Buffer("foo baz").tab());
-
- // test completion in the mid range
- assertBuffer("foo baz", new Buffer("f baz").left().left().left().left().tab());
- assertBuffer("ba foo", new Buffer("b foo").left().left().left().left().tab());
- assertBuffer("foo ba baz", new Buffer("foo b baz").left().left().left().left().tab());
- assertBuffer("foo foo baz", new Buffer("foo f baz").left().left().left().left().tab());
- }
-} \ No newline at end of file
diff --git a/src/jline/src/test/java/scala/tools/jline/console/completer/NullCompleterTest.java b/src/jline/src/test/java/scala/tools/jline/console/completer/NullCompleterTest.java
deleted file mode 100644
index 70a4c3b554..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/completer/NullCompleterTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2010 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package scala.tools.jline.console.completer;
-
-import scala.tools.jline.console.ConsoleReaderTestSupport;
-import scala.tools.jline.console.completer.NullCompleter;
-import org.junit.Test;
-
-/**
- * Tests for {@link NullCompleter}.
- *
- * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
- */
-public class NullCompleterTest
- extends ConsoleReaderTestSupport
-{
- @Test
- public void test1() throws Exception {
- console.addCompleter(NullCompleter.INSTANCE);
-
- assertBuffer("f", new Buffer("f").tab());
- assertBuffer("ba", new Buffer("ba").tab());
- assertBuffer("baz", new Buffer("baz").tab());
- }
-} \ No newline at end of file
diff --git a/src/jline/src/test/java/scala/tools/jline/console/completer/StringsCompleterTest.java b/src/jline/src/test/java/scala/tools/jline/console/completer/StringsCompleterTest.java
deleted file mode 100644
index 518b88d031..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/completer/StringsCompleterTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package scala.tools.jline.console.completer;
-
-import scala.tools.jline.console.ConsoleReaderTestSupport;
-import scala.tools.jline.console.completer.StringsCompleter;
-import org.junit.Test;
-
-/**
- * Tests for {@link jline.console.completer.StringsCompleter}.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
-public class StringsCompleterTest
- extends ConsoleReaderTestSupport
-{
- @Test
- public void test1() throws Exception {
- console.addCompleter(new StringsCompleter("foo", "bar", "baz"));
-
- assertBuffer("foo ", new Buffer("f").tab());
- // single tab completes to unambiguous "ba"
- assertBuffer("ba", new Buffer("b").tab());
- assertBuffer("ba", new Buffer("ba").tab());
- assertBuffer("baz ", new Buffer("baz").tab());
- }
-} \ No newline at end of file
diff --git a/src/jline/src/test/java/scala/tools/jline/console/history/HistoryTest.java b/src/jline/src/test/java/scala/tools/jline/console/history/HistoryTest.java
deleted file mode 100644
index 0a987b2b26..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/history/HistoryTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-package scala.tools.jline.console.history;
-
-import scala.tools.jline.console.ConsoleReaderTestSupport;
-import org.junit.Test;
-
-import static scala.tools.jline.console.Operation.MOVE_TO_BEG;
-import static scala.tools.jline.console.Operation.NEWLINE;
-import static scala.tools.jline.console.Operation.NEXT_HISTORY;
-import static scala.tools.jline.console.Operation.PREV_HISTORY;
-import static scala.tools.jline.console.Operation.PREV_CHAR;
-
-/**
- * Tests command history.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
-public class HistoryTest
- extends ConsoleReaderTestSupport
-{
- @Test
- public void testSingleHistory() throws Exception {
- Buffer b = new Buffer().
- append("test line 1").op(NEWLINE).
- append("test line 2").op(NEWLINE).
- append("test line 3").op(NEWLINE).
- append("test line 4").op(NEWLINE).
- append("test line 5").op(NEWLINE).
- append("");
-
- assertBuffer("", b);
-
- assertBuffer("test line 5", b = b.op(PREV_HISTORY));
- assertBuffer("test line 5", b = b.op(PREV_CHAR));
- assertBuffer("test line 4", b = b.op(PREV_HISTORY));
- assertBuffer("test line 5", b = b.op(NEXT_HISTORY));
- assertBuffer("test line 4", b = b.op(PREV_HISTORY));
- assertBuffer("test line 3", b = b.op(PREV_HISTORY));
- assertBuffer("test line 2", b = b.op(PREV_HISTORY));
- assertBuffer("test line 1", b = b.op(PREV_HISTORY));
-
- // beginning of history
- assertBuffer("test line 1", b = b.op(PREV_HISTORY));
- assertBuffer("test line 1", b = b.op(PREV_HISTORY));
- assertBuffer("test line 1", b = b.op(PREV_HISTORY));
- assertBuffer("test line 1", b = b.op(PREV_HISTORY));
-
- assertBuffer("test line 2", b = b.op(NEXT_HISTORY));
- assertBuffer("test line 3", b = b.op(NEXT_HISTORY));
- assertBuffer("test line 4", b = b.op(NEXT_HISTORY));
- assertBuffer("test line 5", b = b.op(NEXT_HISTORY));
-
- // end of history
- assertBuffer("", b = b.op(NEXT_HISTORY));
- assertBuffer("", b = b.op(NEXT_HISTORY));
- assertBuffer("", b = b.op(NEXT_HISTORY));
-
- assertBuffer("test line 5", b = b.op(PREV_HISTORY));
- assertBuffer("test line 4", b = b.op(PREV_HISTORY));
- b = b.op(MOVE_TO_BEG).append("XXX").op(NEWLINE);
- assertBuffer("XXXtest line 4", b = b.op(PREV_HISTORY));
- assertBuffer("test line 5", b = b.op(PREV_HISTORY));
- assertBuffer("test line 4", b = b.op(PREV_HISTORY));
- assertBuffer("test line 5", b = b.op(NEXT_HISTORY));
- assertBuffer("XXXtest line 4", b = b.op(NEXT_HISTORY));
- assertBuffer("", b = b.op(NEXT_HISTORY));
-
- assertBuffer("XXXtest line 4", b = b.op(PREV_HISTORY));
- assertBuffer("XXXtest line 4", b = b.op(NEWLINE).op(PREV_HISTORY));
- assertBuffer("XXXtest line 4", b = b.op(NEWLINE).op(PREV_HISTORY));
- assertBuffer("XXXtest line 4", b = b.op(NEWLINE).op(PREV_HISTORY));
- assertBuffer("XXXtest line 4", b = b.op(NEWLINE).op(PREV_HISTORY));
- }
-}
diff --git a/src/jline/src/test/java/scala/tools/jline/console/history/MemoryHistoryTest.java b/src/jline/src/test/java/scala/tools/jline/console/history/MemoryHistoryTest.java
deleted file mode 100644
index 91b81548c8..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/console/history/MemoryHistoryTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package scala.tools.jline.console.history;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import static junit.framework.Assert.*;
-
-/**
- * Tests for {@link MemoryHistory}.
- *
- * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
- */
-public class MemoryHistoryTest
-{
- private MemoryHistory history;
-
- @Before
- public void setUp() {
- history = new MemoryHistory();
- }
-
- @After
- public void tearDown() {
- history = null;
- }
-
- @Test
- public void testAdd() {
- assertEquals(0, history.size());
-
- history.add("test");
-
- assertEquals(1, history.size());
- assertEquals("test", history.get(0));
- assertEquals(1, history.index());
- }
-
- private void assertHistoryContains(final int offset, final String... items) {
- assertEquals(items.length, history.size());
- int i=0;
- for (History.Entry entry : history) {
- assertEquals(offset + i, entry.index());
- assertEquals(items[i++], entry.value());
- }
- }
-
- @Test
- public void testOffset() {
- history.setMaxSize(5);
-
- assertEquals(0, history.size());
- assertEquals(0, history.index());
-
- history.add("a");
- history.add("b");
- history.add("c");
- history.add("d");
- history.add("e");
-
- assertEquals(5, history.size());
- assertEquals(5, history.index());
- assertHistoryContains(0, "a", "b", "c", "d", "e");
-
- history.add("f");
-
- assertEquals(5, history.size());
- assertEquals(6, history.index());
-
- assertHistoryContains(1, "b", "c", "d", "e", "f");
- assertEquals("f", history.get(5));
- }
-
- @Test
- public void testReplace() {
- assertEquals(0, history.size());
-
- history.add("a");
- history.add("b");
- history.replace("c");
-
- assertHistoryContains(0, "a", "c");
- }
-} \ No newline at end of file
diff --git a/src/jline/src/test/java/scala/tools/jline/example/Example.java b/src/jline/src/test/java/scala/tools/jline/example/Example.java
deleted file mode 100644
index a89a09c5c9..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/example/Example.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2002-2006, Marc Prud'hommeaux. All rights reserved.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- */
-package scala.tools.jline.example;
-
-import scala.tools.jline.console.completer.*;
-import scala.tools.jline.console.ConsoleReader;
-
-import java.io.*;
-import java.util.*;
-
-public class Example
-{
- public static void usage() {
- System.out.println("Usage: java " + Example.class.getName()
- + " [none/simple/files/dictionary [trigger mask]]");
- System.out.println(" none - no completors");
- System.out.println(" simple - a simple completor that comples "
- + "\"foo\", \"bar\", and \"baz\"");
- System.out
- .println(" files - a completor that comples " + "file names");
- System.out.println(" classes - a completor that comples "
- + "java class names");
- System.out
- .println(" trigger - a special word which causes it to assume "
- + "the next line is a password");
- System.out.println(" mask - is the character to print in place of "
- + "the actual password character");
- System.out.println(" color - colored prompt and feedback");
- System.out.println("\n E.g - java Example simple su '*'\n"
- + "will use the simple compleator with 'su' triggering\n"
- + "the use of '*' as a password mask.");
- }
-
- public static void main(String[] args) throws IOException {
- Character mask = null;
- String trigger = null;
- boolean color = false;
-
- ConsoleReader reader = new ConsoleReader();
-
- reader.setBellEnabled(false);
- reader.setPrompt("prompt> ");
-
- if ((args == null) || (args.length == 0)) {
- usage();
-
- return;
- }
-
- List<Completer> completors = new LinkedList<Completer>();
-
- if (args.length > 0) {
- if (args[0].equals("none")) {
- }
- else if (args[0].equals("files")) {
- completors.add(new FileNameCompleter());
- }
- else if (args[0].equals("simple")) {
- completors.add(new StringsCompleter("foo", "bar", "baz"));
- }
- else if (args[0].equals("color")) {
- color = true;
- reader.setPrompt("\u001B[1mfoo\u001B[0m@bar\u001B[32m@baz\u001B[0m> ");
- }
- else {
- usage();
-
- return;
- }
- }
-
- if (args.length == 3) {
- mask = args[2].charAt(0);
- trigger = args[1];
- }
-
- for (Completer c : completors) {
- reader.addCompleter(c);
- }
-
- String line;
- PrintWriter out = new PrintWriter(
- reader.getTerminal().wrapOutIfNeeded(System.out));
-
- while ((line = reader.readLine()) != null) {
- if (color){
- out.println("\u001B[33m======>\u001B[0m\"" + line + "\"");
- } else {
- out.println("======>\"" + line + "\"");
- }
- out.flush();
-
- // If we input the special word then we will mask
- // the next line.
- if ((trigger != null) && (line.compareTo(trigger) == 0)) {
- line = reader.readLine("password> ", mask);
- }
- if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit")) {
- break;
- }
- }
- }
-}
diff --git a/src/jline/src/test/java/scala/tools/jline/internal/TerminalLineSettingsTest.java b/src/jline/src/test/java/scala/tools/jline/internal/TerminalLineSettingsTest.java
deleted file mode 100644
index 3af10887f1..0000000000
--- a/src/jline/src/test/java/scala/tools/jline/internal/TerminalLineSettingsTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package scala.tools.jline.internal;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests for the {@link TerminalLineSettings}.
- *
- * @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofré</a>
- */
-public class TerminalLineSettingsTest
-{
- private TerminalLineSettings settings;
-
- private final String linuxSttySample = "speed 38400 baud; rows 85; columns 244; line = 0;\n" +
- "intr = ^C; quit = ^\\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;\n" +
- "-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts\n" +
- "-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8\n" +
- "opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n" +
- "isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke";
-
- private final String solarisSttySample = "speed 38400 baud; \n" +
- "rows = 85; columns = 244; ypixels = 0; xpixels = 0;\n" +
- "csdata ?\n" +
- "eucw 1:0:0:0, scrw 1:0:0:0\n" +
- "intr = ^c; quit = ^\\; erase = ^?; kill = ^u;\n" +
- "eof = ^d; eol = -^?; eol2 = -^?; swtch = <undef>;\n" +
- "start = ^q; stop = ^s; susp = ^z; dsusp = ^y;\n" +
- "rprnt = ^r; flush = ^o; werase = ^w; lnext = ^v;\n" +
- "-parenb -parodd cs8 -cstopb -hupcl cread -clocal -loblk -crtscts -crtsxoff -parext \n" +
- "-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -iuclc \n" +
- "ixon ixany -ixoff imaxbel \n" +
- "isig icanon -xcase echo echoe echok -echonl -noflsh \n" +
- "-tostop echoctl -echoprt echoke -defecho -flusho -pendin iexten \n" +
- "opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3";
-
- private final String aixSttySample = "speed 38400 baud; 85 rows; 244 columns;\n" +
- "eucw 1:1:0:0, scrw 1:1:0:0:\n" +
- "intr = ^C; quit = ^\\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>\n" +
- "eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; dsusp = ^Y; reprint = ^R\n" +
- "discard = ^O; werase = ^W; lnext = ^V\n" +
- "-parenb -parodd cs8 -cstopb -hupcl cread -clocal -parext \n" +
- "-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -iuclc \n" +
- "ixon ixany -ixoff imaxbel \n" +
- "isig icanon -xcase echo echoe echok -echonl -noflsh \n" +
- "-tostop echoctl -echoprt echoke -flusho -pending iexten \n" +
- "opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3";
-
- private final String macOsSttySample = "speed 9600 baud; 47 rows; 155 columns;\n" +
- "lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl\n" +
- "-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo\n" +
- "-extproc\n" +
- "iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8\n" +
- "-ignbrk brkint -inpck -ignpar -parmrk\n" +
- "oflags: opost onlcr -oxtabs -onocr -onlret\n" +
- "cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow\n" +
- "-dtrflow -mdmbuf\n" +
- "cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;\n" +
- "eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;\n" +
- "min = 1; quit = ^\\; reprint = ^R; start = ^Q; status = ^T;\n" +
- "stop = ^S; susp = ^Z; time = 0; werase = ^W;";
-
- private final String netBsdSttySample = "speed 38400 baud; 85 rows; 244 columns;\n" +
- "lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl\n" +
- " -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo\n" +
- " -extproc\n" +
- "iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk\n" +
- " brkint -inpck -ignpar -parmrk\n" +
- "oflags: opost onlcr -ocrnl oxtabs onocr onlret\n" +
- "cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -mdmbuf\n" +
- " -cdtrcts\n" +
- "cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;\n" +
- " eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;\n" +
- " min = 1; quit = ^\\; reprint = ^R; start = ^Q; status = ^T;\n" +
- " stop = ^S; susp = ^Z; time = 0; werase = ^W;";
-
- private final String freeBsdSttySample = "speed 9600 baud; 32 rows; 199 columns;\n" +
- "lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl\n" +
- " -echoprt -altwerase -noflsh -tostop -flusho -pendin -nokerninfo\n" +
- " -extproc\n" +
- "iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk\n" +
- " brkint -inpck -ignpar -parmrk\n" +
- "oflags: opost onlcr -ocrnl tab0 -onocr -onlret\n" +
- "cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow\n" +
- " -dtrflow -mdmbuf\n" +
- "cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;\n" +
- " eol2 = <undef>; erase = ^?; erase2 = ^H; intr = ^C; kill = ^U;\n" +
- " lnext = ^V; min = 1; quit = ^\\; reprint = ^R; start = ^Q;\n" +
- " status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W;";
-
- @Before
- public void setUp() throws Exception {
- settings = new TerminalLineSettings();
- }
-
- @Test
- public void testGetConfig() {
- String config = settings.getConfig();
- System.out.println(config);
- }
-
- @Test
- public void testLinuxSttyParsing() {
- assertEquals(0x7f, settings.getProperty("erase", linuxSttySample));
- assertEquals(244, settings.getProperty("columns", linuxSttySample));
- assertEquals(85, settings.getProperty("rows", linuxSttySample));
- }
-
- @Test
- public void testSolarisSttyParsing() {
- assertEquals(0x7f, settings.getProperty("erase", solarisSttySample));
- assertEquals(244, settings.getProperty("columns", solarisSttySample));
- assertEquals(85, settings.getProperty("rows", solarisSttySample));
- }
-
- @Test
- public void testAixSttyParsing() {
- assertEquals(0x7f, settings.getProperty("erase", aixSttySample));
- assertEquals(244, settings.getProperty("columns", aixSttySample));
- assertEquals(85, settings.getProperty("rows", aixSttySample));
- }
-
- @Test
- public void testMacOsSttyParsing() {
- assertEquals(0x7f, settings.getProperty("erase", macOsSttySample));
- assertEquals(155, settings.getProperty("columns", macOsSttySample));
- assertEquals(47, settings.getProperty("rows", macOsSttySample));
- }
-
- @Test
- public void testNetBsdSttyParsing() {
- assertEquals(0x7f, settings.getProperty("erase", netBsdSttySample));
- assertEquals(244, settings.getProperty("columns", netBsdSttySample));
- assertEquals(85, settings.getProperty("rows", netBsdSttySample));
- }
-
- @Test
- public void testFreeBsdSttyParsing() {
- assertEquals(0x7f, settings.getProperty("erase", freeBsdSttySample));
- assertEquals(199, settings.getProperty("columns", freeBsdSttySample));
- assertEquals(32, settings.getProperty("rows", freeBsdSttySample));
- }
-
-} \ No newline at end of file
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index 0b08182102..2d2601c6fb 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -104,7 +104,7 @@ case class StringContext(parts: String*) {
* ''Note:'' Even when using the raw interpolator, Scala will preprocess unicode escapes.
* For example:
* {{{
- * scala> raw"\u005cu0025"
+ * scala> raw"\u005cu0023"
* res0: String = #
* }}}
*
@@ -112,8 +112,6 @@ case class StringContext(parts: String*) {
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
* the number of arguments `arg` by exactly 1.
- * @throws A `StringContext.InvalidEscapeException` if a `parts` string contains a backslash (`\`) character
- * that does not start a valid escape sequence.
*/
def raw(args: Any*): String = standardInterpolator(identity, args)
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 26ccd09803..720dfeed59 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -364,15 +364,16 @@ extends scala.collection.AbstractSeq[Int]
override def equals(other: Any) = other match {
case x: Range =>
// Note: this must succeed for overfull ranges (length > Int.MaxValue)
- (x canEqual this) && (
- isEmpty || // all empty sequences are equal
- (start == x.start && { // Otherwise, must have same start
- val l0 = last
- (l0 == x.last && ( // And same end
- start == l0 || step == x.step // And either the same step, or not take any steps
- ))
- })
- )
+ (x canEqual this) && {
+ if (isEmpty) x.isEmpty // empty sequences are equal
+ else // this is non-empty...
+ x.nonEmpty && start == x.start && { // ...so other must contain something and have same start
+ val l0 = last
+ (l0 == x.last && ( // And same end
+ start == l0 || step == x.step // And either the same step, or not take any steps
+ ))
+ }
+ }
case _ =>
super.equals(other)
}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index dddd3c0e61..42cf600c85 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -260,6 +260,9 @@ trait Symbols { self: Universe =>
* with an object definition (module class in scala compiler parlance).
* If yes, `isType` is also guaranteed to be true.
*
+ * Note to compiler developers: During the "mixin" phase, trait implementation class symbols
+ * receive the `lateMODULE` flag, hence `isImplClass && isModuleClass` becomes true.
+ *
* @group Tests
*/
def isModuleClass: Boolean = false
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 2ce54d2259..b6cce4524b 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -55,23 +55,29 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def newFreeTypeSymbol(name: TypeName, flags: Long = 0L, origin: String): FreeTypeSymbol =
new FreeTypeSymbol(name, origin) initFlags flags
- /** The original owner of a class. Used by the backend to generate
- * EnclosingMethod attributes.
+ /**
+ * This map stores the original owner the the first time the owner of a symbol is re-assigned.
+ * The original owner of a symbol is needed in some places in the backend. Ideally, owners should
+ * be versioned like the type history.
*/
- val originalOwner = perRunCaches.newMap[Symbol, Symbol]()
+ private val originalOwnerMap = perRunCaches.newMap[Symbol, Symbol]()
// TODO - don't allow the owner to be changed without checking invariants, at least
// when under some flag. Define per-phase invariants for owner/owned relationships,
// e.g. after flatten all classes are owned by package classes, there are lots and
// lots of these to be declared (or more realistically, discovered.)
- protected def saveOriginalOwner(sym: Symbol) {
- if (originalOwner contains sym) ()
- else originalOwner(sym) = sym.rawowner
+ protected def saveOriginalOwner(sym: Symbol): Unit = {
+ // some synthetic symbols have NoSymbol as owner initially
+ if (sym.owner != NoSymbol) {
+ if (originalOwnerMap contains sym) ()
+ else originalOwnerMap(sym) = sym.rawowner
+ }
}
+
protected def originalEnclosingMethod(sym: Symbol): Symbol = {
if (sym.isMethod || sym == NoSymbol) sym
else {
- val owner = originalOwner.getOrElse(sym, sym.rawowner)
+ val owner = sym.originalOwner
if (sym.isLocalDummy) owner.enclClass.primaryConstructor
else originalEnclosingMethod(owner)
}
@@ -757,8 +763,22 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* So "isModuleNotMethod" exists not for its achievement in
* brevity, but to encapsulate the relevant condition.
*/
- def isModuleNotMethod = isModule && !isMethod
- def isStaticModule = isModuleNotMethod && isStatic
+ def isModuleNotMethod = {
+ if (isModule) {
+ if (phase.refChecked) this.info // force completion to make sure lateMETHOD is there.
+ !isMethod
+ } else false
+ }
+
+ // After RefChecks, the `isStatic` check is mostly redundant: all non-static modules should
+ // be methods (and vice versa). There's a corner case on the vice-versa with mixed-in module
+ // symbols:
+ // trait T { object A }
+ // object O extends T
+ // The module symbol A is cloned into T$impl (addInterfaces), and then cloned into O (mixin).
+ // Since the original A is not static, it's turned into a method. The clone in O however is
+ // static (owned by a module), but it's also a method.
+ def isStaticModule = isModuleNotMethod && isStatic
final def isInitializedToDefault = !isType && hasAllFlags(DEFAULTINIT | ACCESSOR)
final def isThisSym = isTerm && owner.thisSym == this
@@ -909,10 +929,31 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
final def isModuleVar = hasFlag(MODULEVAR)
- /** Is this symbol static (i.e. with no outer instance)?
- * Q: When exactly is a sym marked as STATIC?
- * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep.
- * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6
+ /**
+ * Is this symbol static (i.e. with no outer instance)?
+ * Q: When exactly is a sym marked as STATIC?
+ * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or
+ * any number of levels deep.
+ * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6
+ *
+ * TODO: should this only be invoked on class / module symbols? because there's also `isStaticMember`.
+ *
+ * Note: the result of `isStatic` changes over time.
+ * - Lambdalift local definitions to the class level, the `owner` field is modified.
+ * object T { def foo { object O } }
+ * After lambdalift, the OModule.isStatic is true.
+ *
+ * - After flatten, nested classes are moved to the package level. Invoking `owner` on a
+ * class returns a package class, for which `isStaticOwner` is true. For example,
+ * class C { object O }
+ * OModuleClass.isStatic is true after flatten. Using phase travel to get before flatten,
+ * method `owner` returns the class C.
+ *
+ * Why not make a stable version of `isStatic`? Maybe some parts of the compiler depend on the
+ * current implementation. For example
+ * trait T { def foo = 1 }
+ * The method `foo` in the implementation class T$impl will be `isStatic`, because trait
+ * impl classes get the `lateMODULE` flag (T$impl.isStaticOwner is true).
*/
def isStatic = (this hasFlag STATIC) || owner.isStaticOwner
@@ -1099,13 +1140,28 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ owner attribute --------------------------------------------------------------
- /** In general when seeking the owner of a symbol, one should call `owner`.
- * The other possibilities include:
- * - call `safeOwner` if it is expected that the target may be NoSymbol
- * - call `assertOwner` if it is an unrecoverable error if the target is NoSymbol
+ /**
+ * The owner of a symbol. Changes over time to adapt to the structure of the trees:
+ * - Up to lambdalift, the owner is the lexically enclosing definition. For definitions
+ * in a local block, the owner is also the next enclosing definition.
+ * - After lambdalift, all local method and class definitions (those not owned by a class
+ * or package class) change their owner to the enclosing class. This is done through
+ * a destructive "sym.owner = sym.owner.enclClass". The old owner is saved by
+ * saveOriginalOwner.
+ * - After flatten, all classes are owned by a PackageClass. This is done through a
+ * phase check (if after flatten) in the (overridden) method "def owner" in
+ * ModuleSymbol / ClassSymbol. The `rawowner` field is not modified.
+ * - Owners are also changed in other situations, for example when moving trees into a new
+ * lexical context, e.g. in the named/default arguments tranformation, or when translating
+ * extension method definitions.
+ *
+ * In general when seeking the owner of a symbol, one should call `owner`.
+ * The other possibilities include:
+ * - call `safeOwner` if it is expected that the target may be NoSymbol
+ * - call `assertOwner` if it is an unrecoverable error if the target is NoSymbol
*
- * `owner` behaves like `safeOwner`, but logs NoSymbol.owner calls under -Xdev.
- * `assertOwner` aborts compilation immediately if called on NoSymbol.
+ * `owner` behaves like `safeOwner`, but logs NoSymbol.owner calls under -Xdev.
+ * `assertOwner` aborts compilation immediately if called on NoSymbol.
*/
def owner: Symbol = {
if (Statistics.hotEnabled) Statistics.incCounter(ownerCount)
@@ -1114,6 +1170,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def safeOwner: Symbol = if (this eq NoSymbol) NoSymbol else owner
final def assertOwner: Symbol = if (this eq NoSymbol) abort("no-symbol does not have an owner") else owner
+ /**
+ * The initial owner of this symbol.
+ */
+ def originalOwner: Symbol = originalOwnerMap.getOrElse(this, rawowner)
+
// TODO - don't allow the owner to be changed without checking invariants, at least
// when under some flag. Define per-phase invariants for owner/owned relationships,
// e.g. after flatten all classes are owned by package classes, there are lots and
@@ -1127,7 +1188,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
def ownerChain: List[Symbol] = this :: owner.ownerChain
- def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain
// Non-classes skip self and return rest of owner chain; overridden in ClassSymbol.
def enclClassChain: List[Symbol] = owner.enclClassChain
@@ -2811,6 +2871,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def owner = {
if (Statistics.hotEnabled) Statistics.incCounter(ownerCount)
+ // a module symbol may have the lateMETHOD flag after refchecks, see isModuleNotMethod
if (!isMethod && needsFlatClasses) rawowner.owner
else rawowner
}
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index b7d7d4df88..c521277f69 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -509,13 +509,6 @@ abstract class TreeInfo {
case _ => false
}
- /** The parameter ValDefs of a method definition that have vararg types of the form T*
- */
- def repeatedParams(tree: Tree): List[ValDef] = tree match {
- case DefDef(_, _, _, vparamss, _, _) => vparamss.flatten filter (vd => isRepeatedParamType(vd.tpt))
- case _ => Nil
- }
-
/** Is tpt a by-name parameter type of the form => T? */
def isByNameParamType(tpt: Tree) = tpt match {
case TypeTree() => definitions.isByNameParamType(tpt.tpe)
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index b808666360..8d4c3f752f 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -254,12 +254,13 @@ abstract class UnPickler {
// (4) Call the mirror's "missing" hook.
adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse {
// (5) Create a stub symbol to defer hard failure a little longer.
- val fullName = s"${owner.fullName}.$name"
+ val advice = moduleAdvice(s"${owner.fullName}.$name")
val missingMessage =
- s"""|bad symbolic reference to $fullName encountered in class file '$filename'.
- |Cannot access ${name.longString} in ${owner.kindString} ${owner.fullName}. The current classpath may be
- |missing a definition for $fullName, or $filename may have been compiled against a version that's
- |incompatible with the one found on the current classpath.${moduleAdvice(fullName)}""".stripMargin
+ s"""|missing or invalid dependency detected while loading class file '$filename'.
+ |Could not access ${name.longString} in ${owner.kindString} ${owner.fullName},
+ |because it (or its dependencies) are missing. Check your build definition for
+ |missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
+ |A full rebuild may help if '$filename' was compiled against an incompatible version of ${owner.fullName}.$advice""".stripMargin
owner.newStubSymbol(name, missingMessage)
}
}
diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
index 7ba68b8733..50ea8d9868 100644
--- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
+++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
@@ -65,10 +65,15 @@ private[reflect] trait SymbolLoaders { self: SymbolTable =>
class LazyPackageType extends LazyType with FlagAgnosticCompleter {
override def complete(sym: Symbol) {
assert(sym.isPackageClass)
- sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym)
+ // Time travel to a phase before refchecks avoids an initialization issue. `openPackageModule`
+ // creates a module symbol and invokes invokes `companionModule` while the `infos` field is
+ // still null. This calls `isModuleNotMethod`, which forces the `info` if run after refchecks.
+ slowButSafeEnteringPhaseNotLaterThan(picklerPhase) {
+ sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym)
// override def safeToString = pkgClass.toString
- openPackageModule(sym)
- markAllCompleted(sym)
+ openPackageModule(sym)
+ markAllCompleted(sym)
+ }
}
}
diff --git a/test/files/jvm/varargs.check b/test/files/jvm/varargs.check
index 8379befe93..986f98896a 100644
--- a/test/files/jvm/varargs.check
+++ b/test/files/jvm/varargs.check
@@ -1,3 +1,4 @@
7
10
-19 \ No newline at end of file
+19
+a
diff --git a/test/files/jvm/varargs/JavaClass.java b/test/files/jvm/varargs/JavaClass.java
index 9851e1b78b..6928ee5adc 100644
--- a/test/files/jvm/varargs/JavaClass.java
+++ b/test/files/jvm/varargs/JavaClass.java
@@ -11,5 +11,6 @@ public class JavaClass {
va.vi(1, 2, 3, 4);
varargz(5, 1.0, 2.0, 3.0);
va.vt(16, "", "", "");
+ System.out.println(va.vt1(16, "a", "b", "c"));
}
} \ No newline at end of file
diff --git a/test/files/jvm/varargs/VaClass.scala b/test/files/jvm/varargs/VaClass.scala
index 6343f9c6f6..e94e8a625a 100644
--- a/test/files/jvm/varargs/VaClass.scala
+++ b/test/files/jvm/varargs/VaClass.scala
@@ -9,5 +9,5 @@ class VaClass {
@varargs def vs(a: Int, b: String*) = println(a + b.length)
@varargs def vi(a: Int, b: Int*) = println(a + b.sum)
@varargs def vt[T](a: Int, b: T*) = println(a + b.length)
-
+ @varargs def vt1[T](a: Int, b: T*): T = b.head
}
diff --git a/test/files/neg/t5148.check b/test/files/neg/t5148.check
index 8a667f4b88..0de4fe2d4c 100644
--- a/test/files/neg/t5148.check
+++ b/test/files/neg/t5148.check
@@ -1,5 +1,6 @@
-error: bad symbolic reference to scala.tools.nsc.interpreter.IMain.Request encountered in class file 'Imports.class'.
-Cannot access type Request in class scala.tools.nsc.interpreter.IMain. The current classpath may be
-missing a definition for scala.tools.nsc.interpreter.IMain.Request, or Imports.class may have been compiled against a version that's
-incompatible with the one found on the current classpath.
+error: missing or invalid dependency detected while loading class file 'Imports.class'.
+Could not access type Request in class scala.tools.nsc.interpreter.IMain,
+because it (or its dependencies) are missing. Check your build definition for
+missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
+A full rebuild may help if 'Imports.class' was compiled against an incompatible version of scala.tools.nsc.interpreter.IMain.
one error found
diff --git a/test/files/neg/t8736-c.check b/test/files/neg/t8736-c.check
new file mode 100644
index 0000000000..06b2228543
--- /dev/null
+++ b/test/files/neg/t8736-c.check
@@ -0,0 +1,11 @@
+t8736-c.scala:4: warning: higher-kinded type should be enabled
+by making the implicit value scala.language.higherKinds visible.
+This can be achieved by adding the import clause 'import scala.language.higherKinds'
+or by setting the compiler option -language:higherKinds.
+See the Scala docs for value scala.language.higherKinds for a discussion
+why the feature should be explicitly enabled.
+ def hk[M[_]] = ???
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/t8736-c.flags b/test/files/neg/t8736-c.flags
new file mode 100644
index 0000000000..fde5313c96
--- /dev/null
+++ b/test/files/neg/t8736-c.flags
@@ -0,0 +1 @@
+-feature -language:-higherKinds,_ -Xfatal-warnings
diff --git a/test/files/neg/t8736-c.scala b/test/files/neg/t8736-c.scala
new file mode 100644
index 0000000000..8432775ae1
--- /dev/null
+++ b/test/files/neg/t8736-c.scala
@@ -0,0 +1,7 @@
+// scalac: -feature -language:-higherKinds,_ -Xfatal-warnings
+// showing that wildcard doesn't supersede explicit disablement
+class X {
+ def hk[M[_]] = ???
+
+ implicit def imp(x: X): Int = x.hashCode
+}
diff --git a/test/files/pos/t8736-b.flags b/test/files/pos/t8736-b.flags
new file mode 100644
index 0000000000..1ad4eabe0f
--- /dev/null
+++ b/test/files/pos/t8736-b.flags
@@ -0,0 +1 @@
+-feature -language:_ -Xfatal-warnings
diff --git a/test/files/pos/t8736-b.scala b/test/files/pos/t8736-b.scala
new file mode 100644
index 0000000000..903292d232
--- /dev/null
+++ b/test/files/pos/t8736-b.scala
@@ -0,0 +1,7 @@
+// scalac: -feature -language:_ -Xfatal-warnings
+// showing that all are set
+class X {
+ def hk[M[_]] = ???
+
+ implicit def imp(x: X): Int = x.hashCode
+}
diff --git a/test/files/pos/t8736.flags b/test/files/pos/t8736.flags
new file mode 100644
index 0000000000..7fe42f7340
--- /dev/null
+++ b/test/files/pos/t8736.flags
@@ -0,0 +1 @@
+-feature -language:implicitConversions -language:higherKinds -language:-implicitConversions -Xfatal-warnings
diff --git a/test/files/pos/t8736.scala b/test/files/pos/t8736.scala
new file mode 100644
index 0000000000..46c0cdfd00
--- /dev/null
+++ b/test/files/pos/t8736.scala
@@ -0,0 +1,7 @@
+// scalac: -feature -language:implicitConversions -language:higherKinds -language:-implicitConversions -Xfatal-warnings
+// showing that multiple settings are respected, and explicit enablement has precedence
+class X {
+ def hk[M[_]] = ???
+
+ implicit def imp(x: X): Int = x.hashCode
+}
diff --git a/test/files/pos/t8743.scala b/test/files/pos/t8743.scala
new file mode 100644
index 0000000000..03b0cd7044
--- /dev/null
+++ b/test/files/pos/t8743.scala
@@ -0,0 +1,15 @@
+import annotation.varargs
+
+object VarArgs {
+ @varargs
+ def foo[A](x: A, xs: String*): A = ???
+
+ @varargs
+ def bar[A](x: List[A], xs: String*): A = ???
+
+ @varargs
+ def baz[A](x: List[A], xs: String*): A = ???
+
+ @varargs
+ def boz[A](x: A, xs: String*): Nothing = ???
+}
diff --git a/test/files/pos/t8781/Macro_1.scala b/test/files/pos/t8781/Macro_1.scala
new file mode 100644
index 0000000000..ecd9c5e8d5
--- /dev/null
+++ b/test/files/pos/t8781/Macro_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.macros.whitebox.Context
+import language.experimental.macros
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ val name = TypeName(c.freshName())
+ q"class $name extends T; new $name"
+ }
+ def fresh: Any = macro impl
+}
+
+trait T
diff --git a/test/files/pos/t8781/Test_2.flags b/test/files/pos/t8781/Test_2.flags
new file mode 100644
index 0000000000..24e2109690
--- /dev/null
+++ b/test/files/pos/t8781/Test_2.flags
@@ -0,0 +1 @@
+-Ymacro-expand:discard -Ystop-after:typer
diff --git a/test/files/pos/t8781/Test_2.scala b/test/files/pos/t8781/Test_2.scala
new file mode 100644
index 0000000000..3ca6406599
--- /dev/null
+++ b/test/files/pos/t8781/Test_2.scala
@@ -0,0 +1,5 @@
+object Test {
+ implicit class RichT(t: T) { def augmented = "" }
+
+ Macros.fresh.augmented
+}
diff --git a/test/files/run/private-override.check b/test/files/run/private-override.check
deleted file mode 100644
index 00750edc07..0000000000
--- a/test/files/run/private-override.check
+++ /dev/null
@@ -1 +0,0 @@
-3
diff --git a/test/files/run/t6440.check b/test/files/run/t6440.check
index 27d5d1380e..2358f08fcc 100644
--- a/test/files/run/t6440.check
+++ b/test/files/run/t6440.check
@@ -1,4 +1,5 @@
-pos: source-newSource1.scala,line-9,offset=109 bad symbolic reference to <root>.pack1 encountered in class file 'U.class'.
-Cannot access term pack1 in package <root>. The current classpath may be
-missing a definition for <root>.pack1, or U.class may have been compiled against a version that's
-incompatible with the one found on the current classpath. ERROR
+pos: source-newSource1.scala,line-9,offset=109 missing or invalid dependency detected while loading class file 'U.class'.
+Could not access term pack1 in package <root>,
+because it (or its dependencies) are missing. Check your build definition for
+missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
+A full rebuild may help if 'U.class' was compiled against an incompatible version of <root>. ERROR
diff --git a/test/files/run/t6440b.check b/test/files/run/t6440b.check
index 0b642c2c35..a6100d6d1e 100644
--- a/test/files/run/t6440b.check
+++ b/test/files/run/t6440b.check
@@ -1,4 +1,5 @@
-pos: NoPosition bad symbolic reference to pack1.T encountered in class file 'U.class'.
-Cannot access type T in package pack1. The current classpath may be
-missing a definition for pack1.T, or U.class may have been compiled against a version that's
-incompatible with the one found on the current classpath. ERROR
+pos: NoPosition missing or invalid dependency detected while loading class file 'U.class'.
+Could not access type T in package pack1,
+because it (or its dependencies) are missing. Check your build definition for
+missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
+A full rebuild may help if 'U.class' was compiled against an incompatible version of pack1. ERROR
diff --git a/test/files/run/t8738.scala b/test/files/run/t8738.scala
new file mode 100644
index 0000000000..6898301db7
--- /dev/null
+++ b/test/files/run/t8738.scala
@@ -0,0 +1,16 @@
+object Test {
+ def check(a: Range, b: Range) = (a == b) == (a.toList == b.toList)
+ def main(args: Array[String]) {
+ val lo = -2 to 2
+ val hi = lo
+ val step = List(-6,-2,-1,1,2,6)
+ for (i <- lo; j <- hi; n <- step; k <- lo; l <- hi; m <- step) {
+ assert(
+ check(i until j by n, k until l by m) &&
+ check(i until j by n, k to l by m) &&
+ check(i to j by n, k until l by m) &&
+ check(i to j by n, k to l by m)
+ )
+ }
+ }
+}
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
index 1fbdc62a1e..3d2b9f77be 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
+++ b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
@@ -36,8 +36,8 @@ object Test extends StoreReporterDirectTest {
println(filteredInfos.mkString("\n"))
storeReporter.infos.clear()
compileApp();
- // we should get bad symbolic reference errors, because we're trying to use an implicit that can't be unpickled
+ // we should get "missing or invalid dependency detected" errors, because we're trying to use an implicit that can't be unpickled
// but we don't know the number of these errors and their order, so I just ignore them all
- println(filteredInfos.filterNot(_.msg.contains("bad symbolic reference")).mkString("\n"))
+ println(filteredInfos.filterNot(_.msg.contains("missing or invalid dependency detected")).mkString("\n"))
}
}
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
index 6804baa0c3..a865f4d137 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
+++ b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
@@ -40,8 +40,8 @@ object Test extends StoreReporterDirectTest {
println(filteredInfos.mkString("\n"))
storeReporter.infos.clear()
compileApp();
- // we should get bad symbolic reference errors, because we're trying to use an implicit that can't be unpickled
+ // we should get "missing or invalid dependency detected" errors, because we're trying to use an implicit that can't be unpickled
// but we don't know the number of these errors and their order, so I just ignore them all
- println(filteredInfos.filterNot (_.msg.contains("bad symbolic reference")).mkString("\n"))
+ println(filteredInfos.filterNot (_.msg.contains("missing or invalid dependency detected")).mkString("\n"))
}
}
diff --git a/versions.properties b/versions.properties
index c334629d20..cd53a343f6 100644
--- a/versions.properties
+++ b/versions.properties
@@ -1,10 +1,10 @@
-#Tue, 20 May 2014 10:01:37 +0200
+#Wed, 23 Jul 2014 08:37:26 +0200
# NOTE: this file determines the content of the scala-distribution
# via scala-dist-pom.xml and scala-library-all-pom.xml
# when adding new properties that influence a release,
# also add them to the update.versions mechanism in build.xml,
# which is used by scala-release-2.11.x in scala/jenkins-scripts
-starr.version=2.11.1
+starr.version=2.11.2
starr.use.released=1
# These are the versions of the modules that go with this release.
@@ -14,21 +14,21 @@ starr.use.released=1
scala.binary.version=2.11
# e.g. 2.11.0-RC1, 2.11.0, 2.11.1-RC1, 2.11.1
# this defines the dependency on scala-continuations-plugin in scala-dist's pom
-scala.full.version=2.11.1
+scala.full.version=2.11.2
# external modules shipped with distribution, as specified by scala-library-all's pom
scala-xml.version.number=1.0.2
-scala-parser-combinators.version.number=1.0.1
+scala-parser-combinators.version.number=1.0.2
scala-continuations-plugin.version.number=1.0.2
scala-continuations-library.version.number=1.0.2
scala-swing.version.number=1.0.1
-akka-actor.version.number=2.3.3
+akka-actor.version.number=2.3.4
actors-migration.version.number=1.1.0
jline.version=2.12
# external modules, used internally (not shipped)
partest.version.number=1.0.0
-scalacheck.version.number=1.11.3
+scalacheck.version.number=1.11.4
# TODO: modularize the compiler
#scala-compiler-doc.version.number=1.0.0-RC1