summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2013-12-03 16:38:55 -0800
committerSom Snytt <som.snytt@gmail.com>2013-12-03 16:56:18 -0800
commit30f779b4d9b699800e323eeba31cf04c16b4fbcd (patch)
tree128e704dd783731294062b76c832abb17c0c778d
parent6c63ab153651f7946ece5740d52e0f2b701e349d (diff)
downloadscala-30f779b4d9b699800e323eeba31cf04c16b4fbcd.tar.gz
scala-30f779b4d9b699800e323eeba31cf04c16b4fbcd.tar.bz2
scala-30f779b4d9b699800e323eeba31cf04c16b4fbcd.zip
SI-8027 REPL double tab regression
Where did double tab go? "The shadow knows." The regression was introduced by the last flurry before we were left to wallow in whatever white space remained. Some xs put other xs under erasure. It's clear that somebody's daughter walked into the room and asked for a story, because, shockingly, the case arrows don't line up. We need a plug-in for Jenkins, or I guess Travis, to fail the build if arrows and equals don't align, because it clearly indicates a lapse of some kind.
-rw-r--r--src/reflect/scala/reflect/internal/util/StringOps.scala16
-rw-r--r--src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala5
-rw-r--r--test/junit/scala/reflect/internal/util/StringOpsTest.scala52
3 files changed, 64 insertions, 9 deletions
diff --git a/src/reflect/scala/reflect/internal/util/StringOps.scala b/src/reflect/scala/reflect/internal/util/StringOps.scala
index 14f349f502..efb8126ff0 100644
--- a/src/reflect/scala/reflect/internal/util/StringOps.scala
+++ b/src/reflect/scala/reflect/internal/util/StringOps.scala
@@ -23,12 +23,16 @@ trait StringOps {
def oempty(xs: String*) = xs filterNot (x => x == null || x == "")
def ojoin(xs: String*): String = oempty(xs: _*) mkString " "
def longestCommonPrefix(xs: List[String]): String = xs match {
- case Nil => ""
- case xs if xs contains "" => ""
- case x :: xs =>
- val ch = x charAt 0
- if (xs exists (_.head != ch)) ""
- else "" + ch + longestCommonPrefix(xs map (_ substring 1))
+ case Nil => ""
+ case w :: Nil => w
+ case _ =>
+ def lcp(ss: List[String]): String = {
+ val w :: ws = ss
+ if (w == "") ""
+ else if (ws exists (s => s == "" || (s charAt 0) != (w charAt 0))) ""
+ else w.substring(0, 1) + lcp(ss map (_ substring 1))
+ }
+ lcp(xs)
}
/** Like String#trim, but trailing whitespace only.
*/
diff --git a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
index 1b3d60d41a..53c7c82e89 100644
--- a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -294,7 +294,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
// This is jline's entry point for completion.
override def complete(buf: String, cursor: Int): Candidates = {
verbosity = if (isConsecutiveTabs(buf, cursor)) verbosity + 1 else 0
- repldbg("\ncomplete(%s, %d) last = (%s, %d), verbosity: %s".format(buf, cursor, lastBuf, lastCursor, verbosity))
+ repldbg(f"%ncomplete($buf, $cursor%d) last = ($lastBuf, $lastCursor%d), verbosity: $verbosity")
// we don't try lower priority completions unless higher ones return no results.
def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Candidates] = {
@@ -307,8 +307,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
val advance = longestCommonPrefix(winners)
lastCursor = p.position + advance.length
lastBuf = (buf take p.position) + advance
- repldbg("tryCompletion(%s, _) lastBuf = %s, lastCursor = %s, p.position = %s".format(
- p, lastBuf, lastCursor, p.position))
+ repldbg(s"tryCompletion($p, _) lastBuf = $lastBuf, lastCursor = $lastCursor, p.position = ${p.position}")
p.position
}
diff --git a/test/junit/scala/reflect/internal/util/StringOpsTest.scala b/test/junit/scala/reflect/internal/util/StringOpsTest.scala
new file mode 100644
index 0000000000..13d3a6435e
--- /dev/null
+++ b/test/junit/scala/reflect/internal/util/StringOpsTest.scala
@@ -0,0 +1,52 @@
+package scala.reflect.internal.util
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class StringOpsTest {
+ @Test
+ def prefixOfNone(): Unit = {
+ val so = new StringOps { }
+ val ss = Nil
+ val lcp = so longestCommonPrefix ss
+ assert(lcp == "")
+ }
+ @Test
+ def prefixWithEmpty(): Unit = {
+ val so = new StringOps { }
+ val ss = List("abc", "", "abd")
+ val lcp = so longestCommonPrefix ss
+ assert(lcp == "")
+ }
+ @Test
+ def prefixOfOne(): Unit = {
+ val so = new StringOps { }
+ val ss = List("abc")
+ val lcp = so longestCommonPrefix ss
+ assert(lcp == "abc")
+ }
+ @Test
+ def prefixOfMany(): Unit = {
+ val so = new StringOps { }
+ val ss = List("abc", "abd", "abe")
+ val lcp = so longestCommonPrefix ss
+ assert(lcp == "ab")
+ }
+ @Test
+ def prefixOfPrefix(): Unit = {
+ val so = new StringOps { }
+ val ss = List("abc", "abcd")
+ val lcp = so longestCommonPrefix ss
+ assert(lcp == "abc")
+ }
+ @Test
+ def prefixOfPrefixMiddling(): Unit = {
+ val so = new StringOps { }
+ val ss = List("abce", "abc", "abcd")
+ val lcp = so longestCommonPrefix ss
+ assert(lcp == "abc")
+ }
+}