summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.sbt1
-rwxr-xr-xbuild.xml40
-rw-r--r--src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala (renamed from src/repl/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala)0
-rw-r--r--src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala (renamed from src/repl/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala)0
-rw-r--r--src/repl-jline/scala/tools/nsc/interpreter/jline/JLineHistory.scala (renamed from src/repl/scala/tools/nsc/interpreter/jline/JLineHistory.scala)0
-rw-r--r--src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala (renamed from src/repl/scala/tools/nsc/interpreter/jline/JLineReader.scala)2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala40
7 files changed, 70 insertions, 13 deletions
diff --git a/build.sbt b/build.sbt
index 553c217d4a..76d66481d0 100644
--- a/build.sbt
+++ b/build.sbt
@@ -191,6 +191,7 @@ lazy val interactive = configureAsSubproject(project)
.settings(disableDocsAndPublishingTasks: _*)
.dependsOn(compiler)
+// TODO: SI-9339 embed shaded copy of jline & its interface (see #4563)
lazy val repl = configureAsSubproject(project)
.settings(libraryDependencies += jlineDep)
.settings(disableDocsAndPublishingTasks: _*)
diff --git a/build.xml b/build.xml
index 421646a2b0..589e1931b8 100755
--- a/build.xml
+++ b/build.xml
@@ -275,6 +275,10 @@ TODO:
<dependency groupId="biz.aQute" artifactId="bnd" version="1.50.0"/>
</artifact:dependencies>
+ <artifact:dependencies pathId="jarjar.classpath">
+ <dependency groupId="com.googlecode.jarjar" artifactId="jarjar" version="1.3"/>
+ </artifact:dependencies>
+
<!-- JUnit -->
<property name="junit.version" value="4.11"/>
<artifact:dependencies pathId="junit.classpath" filesetId="junit.fileset">
@@ -696,7 +700,7 @@ TODO:
<property name="partest-javaagent.description" value="Scala Compiler Testing Tool (compiler-specific java agent)"/>
<!-- projects without project-specific options: forkjoin, manual, bin, repl -->
- <for list="actors,compiler,interactive,scaladoc,library,parser-combinators,partest,partest-extras,partest-javaagent,reflect,scalap,swing,xml,continuations-plugin,continuations-library" param="project">
+ <for list="actors,compiler,interactive,scaladoc,library,parser-combinators,partest,partest-extras,partest-javaagent,reflect,scalap,swing,xml,continuations-plugin,continuations-library,repl-jline" param="project">
<sequential>
<!-- description is mandatory -->
<init-project-prop project="@{project}" name="package" default=""/> <!-- used by mvn-package, copy-bundle, make-bundle -->
@@ -799,6 +803,11 @@ TODO:
<path id="quick.repl.build.path">
<path refid="quick.compiler.build.path"/>
<pathelement location="${build-quick.dir}/classes/repl"/>
+ </path>
+
+ <path id="quick.repl-jline.build.path">
+ <path refid="quick.repl.build.path"/>
+ <pathelement location="${build-quick.dir}/classes/repl-jline"/>
<path refid="repl.deps.classpath"/>
</path>
@@ -873,6 +882,8 @@ TODO:
<fileset dir="${build-quick.dir}/classes/actors"/>
</path>
+ <path id="pack.repl-jline.files"> <fileset dir="${build-quick.dir}/classes/repl-jline"/> </path>
+
<path id="pack.compiler.files">
<fileset dir="${build-quick.dir}/classes/compiler"/>
@@ -1076,6 +1087,7 @@ TODO:
</patternset>
<taskdef resource="scala/tools/ant/sabbus/antlib.xml" classpathref="starr.compiler.path"/>
+ <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpathref="jarjar.classpath" />
</target>
<!-- ===========================================================================
@@ -1157,7 +1169,31 @@ TODO:
<staged-build with="locker" stage="quick" project="compiler"/> </target>
<target name="quick.repl" depends="quick.comp">
- <staged-build with="locker" stage="quick" project="repl"/> </target>
+ <staged-build with="locker" stage="quick" project="repl"/>
+ <staged-build with="locker" stage="quick" project="repl-jline"/>
+
+ <staged-pack project="repl-jline"/>
+
+ <!-- make jline_embedded jar with classes of repl-jline and jline, then shade-->
+ <jarjar jarfile="${build-pack.dir}/${repl-jline.targetdir}/scala-repl-jline-embedded.jar" whenmanifestonly="fail">
+ <zipfileset src="${jline:jline:jar}"/>
+ <zipfileset src="${build-pack.dir}/${repl-jline.targetdir}/${repl-jline.targetjar}"/>
+
+ <rule pattern="org.fusesource.**" result="scala.tools.fusesource_embedded.@1"/>
+ <rule pattern="jline.**" result="scala.tools.jline_embedded.@1"/>
+ <rule pattern="scala.tools.nsc.interpreter.jline.**" result="scala.tools.nsc.interpreter.jline_embedded.@1"/>
+ <keep pattern="scala.tools.**"/>
+ </jarjar>
+
+ <!-- unzip jar to repl's class dir to obtain
+ - standard repl-jline
+ - a shaded repl-jline (scala/tools/nsc/interpreter/jline_embedded) & jline (scala.tools.jline_embedded)
+ -->
+ <copy todir="${build-quick.dir}/classes/repl">
+ <zipfileset src="${build-pack.dir}/${repl-jline.targetdir}/${repl-jline.targetjar}"/>
+ <zipfileset src="${build-pack.dir}/${repl-jline.targetdir}/scala-repl-jline-embedded.jar"/>
+ </copy>
+ </target>
<target name="quick.scaladoc" depends="quick.comp">
<staged-build with="locker" stage="quick" project="scaladoc" version="scaladoc"/> </target>
diff --git a/src/repl/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala b/src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala
index b6c9792ec0..b6c9792ec0 100644
--- a/src/repl/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala
+++ b/src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala
diff --git a/src/repl/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala
index c18a9809a0..c18a9809a0 100644
--- a/src/repl/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala
+++ b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineDelimiter.scala
diff --git a/src/repl/scala/tools/nsc/interpreter/jline/JLineHistory.scala b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineHistory.scala
index 1f6a1f7022..1f6a1f7022 100644
--- a/src/repl/scala/tools/nsc/interpreter/jline/JLineHistory.scala
+++ b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineHistory.scala
diff --git a/src/repl/scala/tools/nsc/interpreter/jline/JLineReader.scala b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala
index 414868a7e5..f0fce13fe8 100644
--- a/src/repl/scala/tools/nsc/interpreter/jline/JLineReader.scala
+++ b/src/repl-jline/scala/tools/nsc/interpreter/jline/JLineReader.scala
@@ -24,7 +24,7 @@ import scala.tools.nsc.interpreter.session.History
*
* Eagerly instantiates all relevant JLine classes, so that we can detect linkage errors on `new JLineReader` and retry.
*/
-class JLineReader(completer: () => Completion) extends interpreter.InteractiveReader {
+class InteractiveReader(completer: () => Completion) extends interpreter.InteractiveReader {
val interactive = true
val history: History = new JLineHistory.JLineFileHistory()
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 3ce9668b97..a3047ccc8e 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -26,6 +26,8 @@ import scala.concurrent.{ ExecutionContext, Await, Future, future }
import ExecutionContext.Implicits._
import java.io.{ BufferedReader, FileReader }
+import scala.util.{Try, Success, Failure}
+
/** The Scala interactive shell. It provides a read-eval-print loop
* around the Interpreter class.
* After instantiation, clients should call the main() method.
@@ -860,18 +862,36 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
* with SimpleReader.
*/
def chooseReader(settings: Settings): InteractiveReader = {
- def mkJLineReader(completer: () => Completion): InteractiveReader =
- try new jline.JLineReader(completer)
- catch {
- case ex@(_: Exception | _: NoClassDefFoundError) =>
- Console.println(f"Failed to created JLineReader: ${ex}%nFalling back to SimpleReader.")
- SimpleReader()
- }
-
if (settings.Xnojline || Properties.isEmacsShell) SimpleReader()
else {
- if (settings.noCompletion) mkJLineReader(() => NoCompletion)
- else mkJLineReader(() => new JLineCompletion(intp))
+ type Completer = () => Completion
+ type ReaderMaker = Completer => InteractiveReader
+
+ def instantiate(className: String): ReaderMaker = completer => {
+ if (settings.debug) Console.println(s"Trying to instantiate a InteractiveReader from $className")
+ Class.forName(className).getConstructor(classOf[Completer]).
+ newInstance(completer).
+ asInstanceOf[InteractiveReader]
+ }
+
+ def mkReader(maker: ReaderMaker) =
+ if (settings.noCompletion) maker(() => NoCompletion)
+ else maker(() => new JLineCompletion(intp)) // JLineCompletion is a misnomer -- it's not tied to jline
+
+ def internalClass(kind: String) = s"scala.tools.nsc.interpreter.$kind.InteractiveReader"
+ val readerClasses = sys.props.get("scala.repl.reader").toStream ++ Stream(internalClass("jline"), internalClass("jline_embedded"))
+ val readers = readerClasses map (cls => Try { mkReader(instantiate(cls)) })
+
+ val reader = (readers collect { case Success(reader) => reader } headOption) getOrElse SimpleReader()
+
+ if (settings.debug) {
+ val readerDiags = (readerClasses, readers).zipped map {
+ case (cls, Failure(e)) => s" - $cls --> " + e.getStackTrace.mkString(e.toString+"\n\t", "\n\t","\n")
+ case (cls, Success(_)) => s" - $cls OK"
+ }
+ Console.println(s"All InteractiveReaders tried: ${readerDiags.mkString("\n","\n","\n")}")
+ }
+ reader
}
}