From b8b0f8758bd8425e5a0bcd5cc920f0e21a46c480 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Fri, 3 Jul 2015 23:10:50 +0200 Subject: [PATCH 01/17] Speed up line/column in OffsetPosition Building the index again and again for every OffsetPosition instance makes very little sense. So this makes it build it only once for a given source. I'm not sure if this is the best way to implement it and I'm afraid that a global synchronized map may be a performance bottleneck once the number of processors goes into the hundreds, but I know very little Scala/Java to do this properly. :-( Fixes http://stackoverflow.com/questions/14707127/accessing-position-information-in-a-scala-combinatorparser-kills-performance --- .../util/parsing/input/OffsetPosition.scala | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala index 23f79c74..08527375 100644 --- a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala +++ b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala @@ -23,6 +23,16 @@ case class OffsetPosition(source: java.lang.CharSequence, offset: Int) extends P /** An index that contains all line starts, including first line, and eof. */ private lazy val index: Array[Int] = { + Option(OffsetPosition.indexCache.get(source)) match { + case Some(index) => index + case None => + val index = genIndex + OffsetPosition.indexCache.put(source, index) + index + } + } + + private def genIndex: Array[Int] = { val lineStarts = new ArrayBuffer[Int] lineStarts += 0 for (i <- 0 until source.length) @@ -71,3 +81,12 @@ case class OffsetPosition(source: java.lang.CharSequence, offset: Int) extends P this.line == that.line && this.column < that.column } } + +/** An object holding the index cache. + * + * @author Tomáš Janoušek + */ +object OffsetPosition { + private lazy val indexCache = java.util.Collections.synchronizedMap( + new java.util.WeakHashMap[java.lang.CharSequence, Array[Int]]) +} From f809b066ba220568921f611e652301590abb0b3a Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Tue, 4 Aug 2015 16:12:50 +0200 Subject: [PATCH 02/17] Fix packrat caching with PagedSeqReader This fixes #45. The problem was that whenever PagedSeqReader is constructed, source is assigned seq (although lazily) but since PagedSeq is not a subclass of java.lang.CharSequence, an implicit conversion takes place via Predef#SeqCharSequence, creating a new object. The problem is that this happens every time PagedSeqReader#rest or drop is called, breaking packrat caching entirely. --- .../scala/util/parsing/input/PagedSeqReader.scala | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/scala/scala/util/parsing/input/PagedSeqReader.scala b/src/main/scala/scala/util/parsing/input/PagedSeqReader.scala index 500c80c7..51e66943 100644 --- a/src/main/scala/scala/util/parsing/input/PagedSeqReader.scala +++ b/src/main/scala/scala/util/parsing/input/PagedSeqReader.scala @@ -30,10 +30,10 @@ object PagedSeqReader { * @author Martin Odersky */ class PagedSeqReader(seq: PagedSeq[Char], - override val offset: Int) extends Reader[Char] { + override val offset: Int) extends Reader[Char] { outer => import PagedSeqReader._ - override lazy val source: java.lang.CharSequence = seq + override val source: java.lang.CharSequence = seq /** Construct a `PagedSeqReader` with its first element at * `source(0)` and position `(1,1)`. @@ -51,7 +51,9 @@ class PagedSeqReader(seq: PagedSeq[Char], * otherwise, it's a `PagedSeqReader` containing the rest of input. */ def rest: PagedSeqReader = - if (seq.isDefinedAt(offset)) new PagedSeqReader(seq, offset + 1) + if (seq.isDefinedAt(offset)) new PagedSeqReader(seq, offset + 1) { + override val source: java.lang.CharSequence = outer.source + } else this /** The position of the first element in the reader. @@ -67,5 +69,7 @@ class PagedSeqReader(seq: PagedSeq[Char], * `n` elements. */ override def drop(n: Int): PagedSeqReader = - new PagedSeqReader(seq, offset + n) + new PagedSeqReader(seq, offset + n) { + override val source: java.lang.CharSequence = outer.source + } } From b6ee1f6a115cbe63d7a1fb49ba194a66813aa3be Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Thu, 6 Aug 2015 15:41:26 +0200 Subject: [PATCH 03/17] Use a thread local WeakHashMap instead of synchronized This should scale much better. --- .../scala/util/parsing/input/OffsetPosition.scala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala index 08527375..1449dbd4 100644 --- a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala +++ b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala @@ -10,6 +10,8 @@ package scala package util.parsing.input import scala.collection.mutable.ArrayBuffer +import java.lang.{CharSequence, ThreadLocal} +import java.util.WeakHashMap /** `OffsetPosition` is a standard class for positions * represented as offsets into a source ``document''. @@ -19,7 +21,7 @@ import scala.collection.mutable.ArrayBuffer * * @author Martin Odersky */ -case class OffsetPosition(source: java.lang.CharSequence, offset: Int) extends Position { +case class OffsetPosition(source: CharSequence, offset: Int) extends Position { /** An index that contains all line starts, including first line, and eof. */ private lazy val index: Array[Int] = { @@ -87,6 +89,11 @@ case class OffsetPosition(source: java.lang.CharSequence, offset: Int) extends P * @author Tomáš Janoušek */ object OffsetPosition { - private lazy val indexCache = java.util.Collections.synchronizedMap( - new java.util.WeakHashMap[java.lang.CharSequence, Array[Int]]) + private lazy val indexCacheTL = + // not DynamicVariable as that would share the map from parent to child :-( + new ThreadLocal[java.util.Map[CharSequence, Array[Int]]] { + override def initialValue = new WeakHashMap[CharSequence, Array[Int]] + } + + private def indexCache = indexCacheTL.get } From 0345e49849da4fa33df8c87d20f6920b0f1df0f0 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Sat, 8 Aug 2015 11:54:18 +0200 Subject: [PATCH 04/17] Add test for #45 --- .../scala/util/parsing/combinator/gh45.scala | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/test/scala/scala/util/parsing/combinator/gh45.scala diff --git a/src/test/scala/scala/util/parsing/combinator/gh45.scala b/src/test/scala/scala/util/parsing/combinator/gh45.scala new file mode 100644 index 00000000..e184719a --- /dev/null +++ b/src/test/scala/scala/util/parsing/combinator/gh45.scala @@ -0,0 +1,46 @@ +package scala.util.parsing.combinator + +import scala.util.parsing.input._ +import scala.collection.immutable.PagedSeq + +import org.junit.Test +import org.junit.Assert.assertTrue + +import scala.util.parsing.combinator.syntactical.StandardTokenParsers + +class gh45 { + + @Test + def test4: Unit = { + def check(rd: Reader[Char]): Unit = { + val g = new grammar + val p = g.phrase(g.script) + val parseResult = p(new g.lexical.Scanner(rd)) + assertTrue(parseResult.isInstanceOf[g.Success[_]]) + } + + val str = "x once y" + check(new CharSequenceReader(str)) + /* Note that this only tests PagedSeq.rest since neither + * PackratReader nor lexical.Scanner override/use the drop method. + */ + check(new PagedSeqReader(PagedSeq.fromStrings(List(str)))) + } + +} + +private final class grammar extends StandardTokenParsers with PackratParsers { + lexical.reserved ++= List("x", "y", "z", "once") + + var onceCnt: Int = 0 + lazy val once: PackratParser[String] = memo("once") ^? { + case s if onceCnt == 0 => + onceCnt += 1 + s + } + + lazy val script: PackratParser[Any] = + ( "x" ~ once ~ "z" + | "x" ~ once ~ "y" + ) +} From aa52548150d471f3a4dd1b4228a7dd11acf77e6f Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Mon, 27 Jul 2015 17:45:59 +0200 Subject: [PATCH 05/17] [backport] add maintenance status on README, remove link to JIRA (cherry picked from commit b89018c84f9ce1a3d94d6d5fc40196b64ce0cc1a) --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3b9023b4..31e4105a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -scala-parser-combinators [](https://travis-ci.org/scala/scala-parser-combinators) +scala-parser-combinators [](https://travis-ci.org/scala/scala-parser-combinators) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-parser-combinators_2.11) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-parser-combinators_2.12*) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/scala/scala-parser-combinators) ======================== ### Scala Standard Parser Combinator Library +This library is now community-maintained. If you are interested in helping please contact @gourlaysama or mention it [on Gitter](https://gitter.im/scala/scala-parser-combinators). + As of Scala 2.11, this library is a separate jar that can be omitted from Scala projects that do not use Parser Combinators. ## Documentation @@ -24,4 +26,5 @@ To support multiple Scala versions, see the example in https://github.com/scala/ ## Contributing * See the [Scala Developer Guidelines](https://github.com/scala/scala/blob/2.12.x/CONTRIBUTING.md) for general contributing guidelines - * Have a look at [existing issues](https://issues.scala-lang.org/issues/?filter=12606) + * Have a look at [existing issues](https://github.com/scala/scala-parser-combinators/issues) + * Ask questions and discuss [on Gitter](https://gitter.im/scala/scala-parser-combinators) From ab6e080efbb8218fb73b094478e194528b10e1fd Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Fri, 11 Sep 2015 22:40:52 +0200 Subject: [PATCH 06/17] Fix binary incompatibilities in object OffsetPosition --- src/main/scala/scala/util/parsing/input/OffsetPosition.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala index 1449dbd4..23fd2c8e 100644 --- a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala +++ b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala @@ -88,7 +88,7 @@ case class OffsetPosition(source: CharSequence, offset: Int) extends Position { * * @author Tomáš Janoušek */ -object OffsetPosition { +object OffsetPosition extends scala.runtime.AbstractFunction2[CharSequence,Int,OffsetPosition] { private lazy val indexCacheTL = // not DynamicVariable as that would share the map from parent to child :-( new ThreadLocal[java.util.Map[CharSequence, Array[Int]]] { From 057730acd3e391dd4addd29feb38ff95b0717989 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Tue, 15 Sep 2015 11:16:26 +0200 Subject: [PATCH 07/17] Fix whitespace in Parsers.phrase --- .../scala/scala/util/parsing/combinator/Parsers.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/scala/util/parsing/combinator/Parsers.scala b/src/main/scala/scala/util/parsing/combinator/Parsers.scala index f6011d3a..18bfc438 100644 --- a/src/main/scala/scala/util/parsing/combinator/Parsers.scala +++ b/src/main/scala/scala/util/parsing/combinator/Parsers.scala @@ -880,11 +880,11 @@ trait Parsers { def phrase[T](p: Parser[T]) = new Parser[T] { def apply(in: Input) = lastNoSuccessVar.withValue(None) { p(in) match { - case s @ Success(out, in1) => - if (in1.atEnd) - s - else - lastNoSuccessVar.value filterNot { _.next.pos < in1.pos } getOrElse Failure("end of input expected", in1) + case s @ Success(out, in1) => + if (in1.atEnd) + s + else + lastNoSuccessVar.value filterNot { _.next.pos < in1.pos } getOrElse Failure("end of input expected", in1) case ns => lastNoSuccessVar.value.getOrElse(ns) } } From 72ea0d78bd5ababc8b352dcfc95212916068d609 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Tue, 15 Sep 2015 11:27:54 +0200 Subject: [PATCH 08/17] Fix lastNoSuccessVar memory leak Fixes https://issues.scala-lang.org/browse/SI-9010, see https://issues.scala-lang.org/browse/SI-4929 for discussion. The leak happened when parsers are used outside of phrase, which seems to be not so common until one realizes that that's exactly how lexers are used in Scanner, so every lexer leaked. This should fix it. --- .../scala/util/parsing/combinator/Parsers.scala | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/scala/scala/util/parsing/combinator/Parsers.scala b/src/main/scala/scala/util/parsing/combinator/Parsers.scala index 18bfc438..115ee135 100644 --- a/src/main/scala/scala/util/parsing/combinator/Parsers.scala +++ b/src/main/scala/scala/util/parsing/combinator/Parsers.scala @@ -156,14 +156,19 @@ trait Parsers { val successful = true } - private lazy val lastNoSuccessVar = new DynamicVariable[Option[NoSuccess]](None) + /* two layers of Option: + * outer Option is None if lastNoSuccess tracking is disabled (outside of + * phrase) and Some if tracking is enabled + * inner Option is None if NoSuccess hasn't been seen yet, Some otherwise + * this is necessary to avoid leaking NoSuccesses in thread locals */ + private lazy val lastNoSuccessVar = new DynamicVariable[Option[Option[NoSuccess]]](None) /** A common super-class for unsuccessful parse results. */ sealed abstract class NoSuccess(val msg: String, override val next: Input) extends ParseResult[Nothing] { // when we don't care about the difference between Failure and Error val successful = false - if (lastNoSuccessVar.value forall (v => !(next.pos < v.next.pos))) - lastNoSuccessVar.value = Some(this) + if (lastNoSuccessVar.value exists (_ forall (v => !(next.pos < v.next.pos)))) + lastNoSuccessVar.value = Some(Some(this)) def map[U](f: Nothing => U) = this def mapPartial[U](f: PartialFunction[Nothing, U], error: Nothing => String): ParseResult[U] = this @@ -878,14 +883,14 @@ trait Parsers { * if `p` consumed all the input. */ def phrase[T](p: Parser[T]) = new Parser[T] { - def apply(in: Input) = lastNoSuccessVar.withValue(None) { + def apply(in: Input) = lastNoSuccessVar.withValue(Some(None)) { p(in) match { case s @ Success(out, in1) => if (in1.atEnd) s else - lastNoSuccessVar.value filterNot { _.next.pos < in1.pos } getOrElse Failure("end of input expected", in1) - case ns => lastNoSuccessVar.value.getOrElse(ns) + lastNoSuccessVar.value flatMap (_ filterNot { _.next.pos < in1.pos }) getOrElse Failure("end of input expected", in1) + case ns => lastNoSuccessVar.value.flatten.getOrElse(ns) } } } From 01c5bacbf8b062912487f719a5bab6147280d6d2 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Tue, 15 Sep 2015 15:58:19 +0200 Subject: [PATCH 09/17] Add test for SI-9010 This is extremely ugly (not only does it use reflection, is uses Java reflection with hard-coded mangled symbol name because of a bug in Scala reflection), but I don't know of a better solution. :-( --- .../scala/util/parsing/combinator/t9010.scala | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/scala/scala/util/parsing/combinator/t9010.scala diff --git a/src/test/scala/scala/util/parsing/combinator/t9010.scala b/src/test/scala/scala/util/parsing/combinator/t9010.scala new file mode 100644 index 00000000..61fafd3d --- /dev/null +++ b/src/test/scala/scala/util/parsing/combinator/t9010.scala @@ -0,0 +1,51 @@ +import scala.util.parsing.combinator._ +import scala.util.DynamicVariable + +import org.junit.Test + +class t9010 { + @Test + def test: Unit = { + val p = new grammar + val lastNoSuccessVar = getLastNoSuccessVar(p) + import p._ + + val res1 = parse(x, "x") + assert(res1.successful) + assert(lastNoSuccessVar.value == None) + + val res2 = parse(x, "y") + assert(!res2.successful) + assert(lastNoSuccessVar.value == None) + + val res3 = parseAll(x, "x") + assert(res3.successful) + assert(lastNoSuccessVar.value == None) + + val res4 = parseAll(x, "y") + assert(!res4.successful) + assert(lastNoSuccessVar.value == None) + } + + private def getLastNoSuccessVar(p: Parsers): DynamicVariable[Option[_]] = { + // use java reflection instead of scala (see below) because of + // https://issues.scala-lang.org/browse/SI-9306 + val fn = "scala$util$parsing$combinator$Parsers$$lastNoSuccessVar" + val f = p.getClass.getDeclaredMethod(fn) + f.setAccessible(true) + f.invoke(p).asInstanceOf[DynamicVariable[Option[_]]] + + /* + val ru = scala.reflect.runtime.universe + val mirror = ru.runtimeMirror(getClass.getClassLoader) + val lastNoSuccessVarField = + ru.typeOf[Parsers].decl(ru.TermName("lastNoSuccessVar")).asTerm.accessed.asTerm + mirror.reflect(p).reflectField(lastNoSuccessVarField).get. + asInstanceOf[DynamicVariable[Option[_]]] + */ + } + + private final class grammar extends RegexParsers { + val x: Parser[String] = "x" + } +} From 3eef4564503a366ae6701b034126c3720ed921bb Mon Sep 17 00:00:00 2001 From: Todd O'Bryan Date: Tue, 29 Dec 2015 11:51:16 -0800 Subject: [PATCH 10/17] Fixes OffsetPosition.lineContents so that it doesn't grab a newline at the end of the line. Includes tests. --- .../util/parsing/input/OffsetPosition.scala | 10 +++- .../scala/util/parsing/combinator/gh56.scala | 57 +++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/test/scala/scala/util/parsing/combinator/gh56.scala diff --git a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala index 23fd2c8e..bbaa5e00 100644 --- a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala +++ b/src/main/scala/scala/util/parsing/input/OffsetPosition.scala @@ -62,8 +62,14 @@ case class OffsetPosition(source: CharSequence, offset: Int) extends Position { * * @return the line at `offset` (not including a newline) */ - def lineContents: String = - source.subSequence(index(line - 1), index(line)).toString + def lineContents: String = { + val endIndex = if (source.charAt(index(line) - 1) == '\n') { + index(line) - 1 + } else { + index(line) + } + source.subSequence(index(line - 1), endIndex).toString + } /** Returns a string representation of the `Position`, of the form `line.column`. */ override def toString = line+"."+column diff --git a/src/test/scala/scala/util/parsing/combinator/gh56.scala b/src/test/scala/scala/util/parsing/combinator/gh56.scala new file mode 100644 index 00000000..34e1d551 --- /dev/null +++ b/src/test/scala/scala/util/parsing/combinator/gh56.scala @@ -0,0 +1,57 @@ +package scala.util.parsing.combinator + +import org.junit.Assert.{assertEquals, assertTrue} +import org.junit.Test + +import scala.util.parsing.combinator.syntactical.StandardTokenParsers + +/** + * Test for issue 56: https://github.com/scala/scala-parser-combinators/issues/56 + * + * Makes sure that lineContents (and thus longString) in the Position trait doesn't + * include a newline + */ +class gh56 { + private object grammar extends StandardTokenParsers with PackratParsers { + lazy val term = (numericLit | stringLit | ident)+ + } + + @Test + def test1: Unit = { + import grammar._ + + val expr = + """/* an unclosed comment + |of multiple lines + |just to check longString/lineContents + """.stripMargin + + val fail = + """[1.1] failure: identifier expected + | + |/* an unclosed comment + |^""".stripMargin + + val parseResult = phrase(term)(new lexical.Scanner(expr)) + assertTrue(parseResult.isInstanceOf[Failure]) + assertEquals(fail, parseResult.toString) + } + + + @Test + def test2: Unit = { + import grammar._ + + val expr = "/* an unclosed comment without newline" + + val fail = + """[1.1] failure: identifier expected + | + |/* an unclosed comment without newline + |^""".stripMargin + + val parseResult = phrase(term)(new lexical.Scanner(expr)) + assertTrue(parseResult.isInstanceOf[Failure]) + assertEquals(fail, parseResult.toString) + } +} From 51d69b465bb0411cd1b94dabaac43143ba4cc221 Mon Sep 17 00:00:00 2001 From: Todd O'Bryan Date: Wed, 6 Jan 2016 10:37:41 -0800 Subject: [PATCH 11/17] Add Travis workaround based on both hostname and /etc/hosts See https://github.com/travis-ci/travis-ci/issues/5227. --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5633424f..25c7ca59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,11 @@ language: scala +before_install: + - cat /etc/hosts # optionally check the content *before* + - sudo hostname "$(hostname | cut -c1-63)" + - sed -e "s/^\\(127\\.0\\.0\\.1.*\\)/\\1 $(hostname | cut -c1-63)/" /etc/hosts | sudo tee /etc/hosts + - cat /etc/hosts # optionally check the content *after* + env: global: - PUBLISH_JDK=openjdk6 From 26d36ac175f0219124d8165295623b67bac10838 Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Fri, 12 Feb 2016 18:56:07 +0100 Subject: [PATCH 12/17] bump scala, sbt and scala-module-plugin versions Also restrict 2.12 to jdk8 builds. --- .travis.yml | 1 + build.sbt | 12 +++++++++--- project/build.properties | 2 +- project/plugins.sbt | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25c7ca59..cdb254b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ script: admin/build.sh jdk: - openjdk6 - openjdk7 + - oraclejdk8 notifications: email: diff --git a/build.sbt b/build.sbt index 6a5a6f29..0b709dbe 100644 --- a/build.sbt +++ b/build.sbt @@ -6,9 +6,15 @@ name := "scala-parser-combinators" version := "1.0.5-SNAPSHOT" -scalaVersion := crossScalaVersions.value.head - -crossScalaVersions := Seq("2.11.6", "2.12.0-M1") +crossScalaVersions in ThisBuild := { + val javaVersion = System.getProperty("java.version") + val isJDK6Or7 = + javaVersion.startsWith("1.6.") || javaVersion.startsWith("1.7.") + if (isJDK6Or7) + Seq("2.11.7") + else + Seq("2.11.7", "2.12.0-M3") +} // important!! must come here (why?) scalaModuleOsgiSettings diff --git a/project/build.properties b/project/build.properties index a6e117b6..817bc38d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.8 +sbt.version=0.13.9 diff --git a/project/plugins.sbt b/project/plugins.sbt index 25f33731..65dea32c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-lang.modules" % "scala-module-plugin" % "1.0.3") +addSbtPlugin("org.scala-lang.modules" % "scala-module-plugin" % "1.0.4") From 3dd55ddaef13d4317443335dc9e85438933f74c0 Mon Sep 17 00:00:00 2001 From: Eduardo Gulias Davis Date: Wed, 20 Jul 2016 00:53:14 +0200 Subject: [PATCH 13/17] Change apostrophe in error message I'm not sure if this was intentionally left with `'` instead of ` in the closing apostrophe, but just in case it was not I made the PR. Scala CLA has been signed. --- src/main/scala/scala/util/parsing/combinator/Parsers.scala | 2 +- .../scala/util/parsing/combinator/PackratParsersTest.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/scala/util/parsing/combinator/Parsers.scala b/src/main/scala/scala/util/parsing/combinator/Parsers.scala index 115ee135..f8190e37 100644 --- a/src/main/scala/scala/util/parsing/combinator/Parsers.scala +++ b/src/main/scala/scala/util/parsing/combinator/Parsers.scala @@ -565,7 +565,7 @@ trait Parsers { * @return a `tParser` that succeeds if `e` is the next available input. */ - implicit def accept(e: Elem): Parser[Elem] = acceptIf(_ == e)("`"+e+"' expected but " + _ + " found") + implicit def accept(e: Elem): Parser[Elem] = acceptIf(_ == e)("'"+e+"' expected but " + _ + " found") /** A parser that matches only the given list of element `es`. * diff --git a/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala b/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala index 5a7e6d2e..aec44bc0 100644 --- a/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala +++ b/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala @@ -122,7 +122,7 @@ class PackratParsersTest { val failure = parseResult.asInstanceOf[Failure] assertEquals(expectedFailureMsg, failure.msg) } - assertFailure("``b'' expected but `c' found", "a a a a b b b c c c c") + assertFailure("'`b'' expected but `c' found", "a a a a b b b c c c c") assertFailure("end of input", "a a a a b b b b c c c") } From ac7c33fbab65e3af062565851219eab7f1cec4e3 Mon Sep 17 00:00:00 2001 From: Eduardo Gulias Davis Date: Fri, 9 Sep 2016 22:43:15 +0200 Subject: [PATCH 14/17] fix travis-ci hosts --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cdb254b7..501e32d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ language: scala before_install: - cat /etc/hosts # optionally check the content *before* - sudo hostname "$(hostname | cut -c1-63)" - - sed -e "s/^\\(127\\.0\\.0\\.1.*\\)/\\1 $(hostname | cut -c1-63)/" /etc/hosts | sudo tee /etc/hosts + - sed -e "s/^\\(127\\.0\\.0\\.1.*\\)/\\1 $(hostname | cut -c1-63)/" /etc/hosts > /tmp/hosts + - sudo mv /tmp/hosts /etc/hosts - cat /etc/hosts # optionally check the content *after* env: From ad635975e68dbf4c0a4370c94b3c5069552238d6 Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Tue, 20 Sep 2016 12:33:13 +0200 Subject: [PATCH 15/17] [backport] Scala.js support for 1.0.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit backports the commit below, with two caveats: - the fix in #68 doesn't work with Scala.js, so it is only enabled on the JVM for now - the scalaVersion/crossScalaVersion madness breaks the sbt build in 1.0.x (it didn't in master for some reason), so the second backport commit below had to be squashed with this one [backport] Add support for Scala.js, with cross-compilation. Scala versions were upgraded to 2.11.7 and 2.12.0-M3. 2.12 is only used when running the build on JDK8 or later. JavaTokenParsers.identifier was rewritten not to use a regexp, but rather primitive parsers and Character.isJavaIdentifier{Start,Part}. The regexp-based implementation relies on Java-specific character ranges. JavaTokenParsers.stringLiteral was slightly adapted with an expansion of `\p{Cntrl}` into `[\x00-\x1F\x7F]`. The former character range is Java-specific. We also removed an invalid (and useless) `+` at the end of the regexp. The test t4929.scala is JVM-only. (Author: Sébastien Doeraene ) (cherry picked from commit 98737a23dbdc2ad4bf0fcb59dbe576dcd695fcbb) --- [backport] set Scala version in a more dbuild-friendly way having scalaVersion and crossScalaVersions set in different places was confusing dbuild needed to fix scala/community-builds#215 (Author: Seth Tisue ) (cherry picked from commit bde222c4249346f64f9ea058d5dcc2d41c634fda) --- build.sbt | 63 +++++++++++++------ .../util/parsing/input/PositionCache.scala | 14 +++++ .../util/parsing/input/PositionCache.scala | 17 +++++ .../scala/util/parsing/combinator/t4929.scala | 0 .../scala/util/parsing/combinator/t9010.scala | 0 project/plugins.sbt | 2 + .../combinator/ImplicitConversions.scala | 0 .../parsing/combinator/JavaTokenParsers.scala | 10 ++- .../parsing/combinator/PackratParsers.scala | 0 .../util/parsing/combinator/Parsers.scala | 0 .../parsing/combinator/RegexParsers.scala | 0 .../util/parsing/combinator/SubSequence.scala | 0 .../parsing/combinator/lexical/Lexical.scala | 0 .../parsing/combinator/lexical/Scanners.scala | 0 .../combinator/lexical/StdLexical.scala | 0 .../syntactical/StandardTokenParsers.scala | 0 .../syntactical/StdTokenParsers.scala | 0 .../combinator/syntactical/TokenParsers.scala | 0 .../parsing/combinator/token/StdTokens.scala | 0 .../parsing/combinator/token/Tokens.scala | 0 .../util/parsing/input/CharArrayReader.scala | 0 .../parsing/input/CharSequenceReader.scala | 0 .../scala/util/parsing/input/NoPosition.scala | 0 .../util/parsing/input/OffsetPosition.scala | 12 +--- .../util/parsing/input/PagedSeqReader.scala | 0 .../scala/util/parsing/input/Position.scala | 0 .../scala/util/parsing/input/Positional.scala | 0 .../scala/util/parsing/input/Reader.scala | 0 .../util/parsing/input/StreamReader.scala | 0 .../scala/scala/util/parsing/json/JSON.scala | 0 .../scala/scala/util/parsing/json/Lexer.scala | 0 .../scala/util/parsing/json/Parser.scala | 0 .../combinator/JavaTokenParsersTest.scala | 2 +- .../util/parsing/combinator/JsonTest.scala | 5 +- .../combinator/PackratParsersTest.scala | 0 .../parsing/combinator/RegexParsersTest.scala | 0 .../util/parsing/combinator/UnitTestIO.scala | 0 .../scala/util/parsing/combinator/gh45.scala | 0 .../scala/util/parsing/combinator/gh56.scala | 0 .../scala/util/parsing/combinator/t0700.scala | 0 .../scala/util/parsing/combinator/t1100.scala | 0 .../scala/util/parsing/combinator/t4138.scala | 0 .../scala/util/parsing/combinator/t5514.scala | 0 .../scala/util/parsing/combinator/t8879.scala | 0 44 files changed, 89 insertions(+), 36 deletions(-) create mode 100644 js/src/main/scala/scala/util/parsing/input/PositionCache.scala create mode 100644 jvm/src/main/scala/scala/util/parsing/input/PositionCache.scala rename {src => jvm/src}/test/scala/scala/util/parsing/combinator/t4929.scala (100%) rename {src => jvm/src}/test/scala/scala/util/parsing/combinator/t9010.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/ImplicitConversions.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/JavaTokenParsers.scala (88%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/PackratParsers.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/Parsers.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/RegexParsers.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/SubSequence.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/lexical/Lexical.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/lexical/Scanners.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/lexical/StdLexical.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/syntactical/TokenParsers.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/token/StdTokens.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/combinator/token/Tokens.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/CharArrayReader.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/CharSequenceReader.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/NoPosition.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/OffsetPosition.scala (89%) rename {src => shared/src}/main/scala/scala/util/parsing/input/PagedSeqReader.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/Position.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/Positional.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/Reader.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/input/StreamReader.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/json/JSON.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/json/Lexer.scala (100%) rename {src => shared/src}/main/scala/scala/util/parsing/json/Parser.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/JavaTokenParsersTest.scala (96%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/JsonTest.scala (98%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/RegexParsersTest.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/UnitTestIO.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/gh45.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/gh56.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/t0700.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/t1100.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/t4138.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/t5514.scala (100%) rename {src => shared/src}/test/scala/scala/util/parsing/combinator/t8879.scala (100%) diff --git a/build.sbt b/build.sbt index 0b709dbe..61cdd133 100644 --- a/build.sbt +++ b/build.sbt @@ -1,10 +1,4 @@ -import com.typesafe.tools.mima.plugin.{MimaPlugin, MimaKeys} - -scalaModuleSettings - -name := "scala-parser-combinators" - -version := "1.0.5-SNAPSHOT" +scalaVersion in ThisBuild := crossScalaVersions.value.head crossScalaVersions in ThisBuild := { val javaVersion = System.getProperty("java.version") @@ -16,16 +10,45 @@ crossScalaVersions in ThisBuild := { Seq("2.11.7", "2.12.0-M3") } -// important!! must come here (why?) -scalaModuleOsgiSettings - -OsgiKeys.exportPackage := Seq(s"scala.util.parsing.*;version=${version.value}") - -// needed to fix classloader issues (see scala-xml#20) -fork in Test := true - -libraryDependencies += "junit" % "junit" % "4.11" % "test" - -libraryDependencies += "com.novocode" % "junit-interface" % "0.10" % "test" - -mimaPreviousVersion := Some("1.0.2") +lazy val `scala-parser-combinators` = crossProject.in(file(".")). + settings(scalaModuleSettings: _*). + settings( + name := "scala-parser-combinators-root" + ). + jvmSettings( + // Mima uses the name of the jvm project in the artifactId + // when resolving previous versions (so no "-jvm" project) + name := "scala-parser-combinators" + ). + jsSettings( + name := "scala-parser-combinators-js" + ). + settings( + moduleName := "scala-parser-combinators", + version := "1.0.5-SNAPSHOT" + ). + jvmSettings( + // important!! must come here (why?) + scalaModuleOsgiSettings: _* + ). + jvmSettings( + OsgiKeys.exportPackage := Seq(s"scala.util.parsing.*;version=${version.value}"), + + // needed to fix classloader issues (see scala-xml#20) + fork in Test := true + ). + jsSettings( + // Scala.js cannot run forked tests + fork in Test := false + ). + jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin)). + jvmSettings( + libraryDependencies += "junit" % "junit" % "4.11" % "test", + libraryDependencies += "com.novocode" % "junit-interface" % "0.10" % "test" + ). + jvmSettings( + mimaPreviousVersion := Some("1.0.4") + ) + +lazy val `scala-parser-combinatorsJVM` = `scala-parser-combinators`.jvm +lazy val `scala-parser-combinatorsJS` = `scala-parser-combinators`.js diff --git a/js/src/main/scala/scala/util/parsing/input/PositionCache.scala b/js/src/main/scala/scala/util/parsing/input/PositionCache.scala new file mode 100644 index 00000000..ff9f144f --- /dev/null +++ b/js/src/main/scala/scala/util/parsing/input/PositionCache.scala @@ -0,0 +1,14 @@ +package scala.util.parsing.input + +import java.lang.CharSequence +import java.util.{AbstractMap, Collections} + +private[input] trait PositionCache { + private[input] lazy val indexCache: java.util.Map[CharSequence,Array[Int]] = new AbstractMap[CharSequence, Array[Int]] { + + override def entrySet() = Collections.emptySet() + + // the /dev/null of Maps + override def put(ch: CharSequence, a: Array[Int]) = null + } +} diff --git a/jvm/src/main/scala/scala/util/parsing/input/PositionCache.scala b/jvm/src/main/scala/scala/util/parsing/input/PositionCache.scala new file mode 100644 index 00000000..84b1edfb --- /dev/null +++ b/jvm/src/main/scala/scala/util/parsing/input/PositionCache.scala @@ -0,0 +1,17 @@ +package scala.util.parsing.input + +import java.lang.{CharSequence, ThreadLocal} +import java.util.WeakHashMap + +/** + * @author Tomáš Janoušek + */ +private[input] trait PositionCache { + private lazy val indexCacheTL = + // not DynamicVariable as that would share the map from parent to child :-( + new ThreadLocal[java.util.Map[CharSequence, Array[Int]]] { + override def initialValue = new WeakHashMap[CharSequence, Array[Int]] + } + + private[input] def indexCache = indexCacheTL.get +} diff --git a/src/test/scala/scala/util/parsing/combinator/t4929.scala b/jvm/src/test/scala/scala/util/parsing/combinator/t4929.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/t4929.scala rename to jvm/src/test/scala/scala/util/parsing/combinator/t4929.scala diff --git a/src/test/scala/scala/util/parsing/combinator/t9010.scala b/jvm/src/test/scala/scala/util/parsing/combinator/t9010.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/t9010.scala rename to jvm/src/test/scala/scala/util/parsing/combinator/t9010.scala diff --git a/project/plugins.sbt b/project/plugins.sbt index 65dea32c..8fef081e 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1,3 @@ addSbtPlugin("org.scala-lang.modules" % "scala-module-plugin" % "1.0.4") + +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.6") diff --git a/src/main/scala/scala/util/parsing/combinator/ImplicitConversions.scala b/shared/src/main/scala/scala/util/parsing/combinator/ImplicitConversions.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/ImplicitConversions.scala rename to shared/src/main/scala/scala/util/parsing/combinator/ImplicitConversions.scala diff --git a/src/main/scala/scala/util/parsing/combinator/JavaTokenParsers.scala b/shared/src/main/scala/scala/util/parsing/combinator/JavaTokenParsers.scala similarity index 88% rename from src/main/scala/scala/util/parsing/combinator/JavaTokenParsers.scala rename to shared/src/main/scala/scala/util/parsing/combinator/JavaTokenParsers.scala index 1e6b1624..12bb4838 100644 --- a/src/main/scala/scala/util/parsing/combinator/JavaTokenParsers.scala +++ b/shared/src/main/scala/scala/util/parsing/combinator/JavaTokenParsers.scala @@ -26,8 +26,12 @@ trait JavaTokenParsers extends RegexParsers { * The Java Language Spec. * Generally, this means a letter, followed by zero or more letters or numbers. */ - def ident: Parser[String] = - """\p{javaJavaIdentifierStart}\p{javaJavaIdentifierPart}*""".r + def ident: Parser[String] = ( + "" ~> // handle whitespace + rep1(acceptIf(Character.isJavaIdentifierStart)("identifier expected but `" + _ + "' found"), + elem("identifier part", Character.isJavaIdentifierPart(_: Char))) ^^ (_.mkString) + ) + /** An integer, without sign or with a negative sign. */ def wholeNumber: Parser[String] = """-?\d+""".r @@ -49,7 +53,7 @@ trait JavaTokenParsers extends RegexParsers { */ @migration("`stringLiteral` allows escaping single and double quotes, but not forward slashes any longer.", "2.10.0") def stringLiteral: Parser[String] = - ("\""+"""([^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*+"""+"\"").r + ("\""+"""([^"\x00-\x1F\x7F\\]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*"""+"\"").r /** A number following the rules of `decimalNumber`, with the following * optional additions: * diff --git a/src/main/scala/scala/util/parsing/combinator/PackratParsers.scala b/shared/src/main/scala/scala/util/parsing/combinator/PackratParsers.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/PackratParsers.scala rename to shared/src/main/scala/scala/util/parsing/combinator/PackratParsers.scala diff --git a/src/main/scala/scala/util/parsing/combinator/Parsers.scala b/shared/src/main/scala/scala/util/parsing/combinator/Parsers.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/Parsers.scala rename to shared/src/main/scala/scala/util/parsing/combinator/Parsers.scala diff --git a/src/main/scala/scala/util/parsing/combinator/RegexParsers.scala b/shared/src/main/scala/scala/util/parsing/combinator/RegexParsers.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/RegexParsers.scala rename to shared/src/main/scala/scala/util/parsing/combinator/RegexParsers.scala diff --git a/src/main/scala/scala/util/parsing/combinator/SubSequence.scala b/shared/src/main/scala/scala/util/parsing/combinator/SubSequence.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/SubSequence.scala rename to shared/src/main/scala/scala/util/parsing/combinator/SubSequence.scala diff --git a/src/main/scala/scala/util/parsing/combinator/lexical/Lexical.scala b/shared/src/main/scala/scala/util/parsing/combinator/lexical/Lexical.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/lexical/Lexical.scala rename to shared/src/main/scala/scala/util/parsing/combinator/lexical/Lexical.scala diff --git a/src/main/scala/scala/util/parsing/combinator/lexical/Scanners.scala b/shared/src/main/scala/scala/util/parsing/combinator/lexical/Scanners.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/lexical/Scanners.scala rename to shared/src/main/scala/scala/util/parsing/combinator/lexical/Scanners.scala diff --git a/src/main/scala/scala/util/parsing/combinator/lexical/StdLexical.scala b/shared/src/main/scala/scala/util/parsing/combinator/lexical/StdLexical.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/lexical/StdLexical.scala rename to shared/src/main/scala/scala/util/parsing/combinator/lexical/StdLexical.scala diff --git a/src/main/scala/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala b/shared/src/main/scala/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala rename to shared/src/main/scala/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala diff --git a/src/main/scala/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala b/shared/src/main/scala/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala rename to shared/src/main/scala/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala diff --git a/src/main/scala/scala/util/parsing/combinator/syntactical/TokenParsers.scala b/shared/src/main/scala/scala/util/parsing/combinator/syntactical/TokenParsers.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/syntactical/TokenParsers.scala rename to shared/src/main/scala/scala/util/parsing/combinator/syntactical/TokenParsers.scala diff --git a/src/main/scala/scala/util/parsing/combinator/token/StdTokens.scala b/shared/src/main/scala/scala/util/parsing/combinator/token/StdTokens.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/token/StdTokens.scala rename to shared/src/main/scala/scala/util/parsing/combinator/token/StdTokens.scala diff --git a/src/main/scala/scala/util/parsing/combinator/token/Tokens.scala b/shared/src/main/scala/scala/util/parsing/combinator/token/Tokens.scala similarity index 100% rename from src/main/scala/scala/util/parsing/combinator/token/Tokens.scala rename to shared/src/main/scala/scala/util/parsing/combinator/token/Tokens.scala diff --git a/src/main/scala/scala/util/parsing/input/CharArrayReader.scala b/shared/src/main/scala/scala/util/parsing/input/CharArrayReader.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/CharArrayReader.scala rename to shared/src/main/scala/scala/util/parsing/input/CharArrayReader.scala diff --git a/src/main/scala/scala/util/parsing/input/CharSequenceReader.scala b/shared/src/main/scala/scala/util/parsing/input/CharSequenceReader.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/CharSequenceReader.scala rename to shared/src/main/scala/scala/util/parsing/input/CharSequenceReader.scala diff --git a/src/main/scala/scala/util/parsing/input/NoPosition.scala b/shared/src/main/scala/scala/util/parsing/input/NoPosition.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/NoPosition.scala rename to shared/src/main/scala/scala/util/parsing/input/NoPosition.scala diff --git a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala b/shared/src/main/scala/scala/util/parsing/input/OffsetPosition.scala similarity index 89% rename from src/main/scala/scala/util/parsing/input/OffsetPosition.scala rename to shared/src/main/scala/scala/util/parsing/input/OffsetPosition.scala index bbaa5e00..c69fc4d9 100644 --- a/src/main/scala/scala/util/parsing/input/OffsetPosition.scala +++ b/shared/src/main/scala/scala/util/parsing/input/OffsetPosition.scala @@ -91,15 +91,5 @@ case class OffsetPosition(source: CharSequence, offset: Int) extends Position { } /** An object holding the index cache. - * - * @author Tomáš Janoušek */ -object OffsetPosition extends scala.runtime.AbstractFunction2[CharSequence,Int,OffsetPosition] { - private lazy val indexCacheTL = - // not DynamicVariable as that would share the map from parent to child :-( - new ThreadLocal[java.util.Map[CharSequence, Array[Int]]] { - override def initialValue = new WeakHashMap[CharSequence, Array[Int]] - } - - private def indexCache = indexCacheTL.get -} +object OffsetPosition extends scala.runtime.AbstractFunction2[CharSequence,Int,OffsetPosition] with PositionCache diff --git a/src/main/scala/scala/util/parsing/input/PagedSeqReader.scala b/shared/src/main/scala/scala/util/parsing/input/PagedSeqReader.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/PagedSeqReader.scala rename to shared/src/main/scala/scala/util/parsing/input/PagedSeqReader.scala diff --git a/src/main/scala/scala/util/parsing/input/Position.scala b/shared/src/main/scala/scala/util/parsing/input/Position.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/Position.scala rename to shared/src/main/scala/scala/util/parsing/input/Position.scala diff --git a/src/main/scala/scala/util/parsing/input/Positional.scala b/shared/src/main/scala/scala/util/parsing/input/Positional.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/Positional.scala rename to shared/src/main/scala/scala/util/parsing/input/Positional.scala diff --git a/src/main/scala/scala/util/parsing/input/Reader.scala b/shared/src/main/scala/scala/util/parsing/input/Reader.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/Reader.scala rename to shared/src/main/scala/scala/util/parsing/input/Reader.scala diff --git a/src/main/scala/scala/util/parsing/input/StreamReader.scala b/shared/src/main/scala/scala/util/parsing/input/StreamReader.scala similarity index 100% rename from src/main/scala/scala/util/parsing/input/StreamReader.scala rename to shared/src/main/scala/scala/util/parsing/input/StreamReader.scala diff --git a/src/main/scala/scala/util/parsing/json/JSON.scala b/shared/src/main/scala/scala/util/parsing/json/JSON.scala similarity index 100% rename from src/main/scala/scala/util/parsing/json/JSON.scala rename to shared/src/main/scala/scala/util/parsing/json/JSON.scala diff --git a/src/main/scala/scala/util/parsing/json/Lexer.scala b/shared/src/main/scala/scala/util/parsing/json/Lexer.scala similarity index 100% rename from src/main/scala/scala/util/parsing/json/Lexer.scala rename to shared/src/main/scala/scala/util/parsing/json/Lexer.scala diff --git a/src/main/scala/scala/util/parsing/json/Parser.scala b/shared/src/main/scala/scala/util/parsing/json/Parser.scala similarity index 100% rename from src/main/scala/scala/util/parsing/json/Parser.scala rename to shared/src/main/scala/scala/util/parsing/json/Parser.scala diff --git a/src/test/scala/scala/util/parsing/combinator/JavaTokenParsersTest.scala b/shared/src/test/scala/scala/util/parsing/combinator/JavaTokenParsersTest.scala similarity index 96% rename from src/test/scala/scala/util/parsing/combinator/JavaTokenParsersTest.scala rename to shared/src/test/scala/scala/util/parsing/combinator/JavaTokenParsersTest.scala index 28cf1ba7..9527feea 100644 --- a/src/test/scala/scala/util/parsing/combinator/JavaTokenParsersTest.scala +++ b/shared/src/test/scala/scala/util/parsing/combinator/JavaTokenParsersTest.scala @@ -97,7 +97,7 @@ class JavaTokenParsersTest { case Failure(message, next) => assertEquals(next.pos.line, 1) assertEquals(next.pos.column, 1) - assert(message.endsWith(s"regex `\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*' expected but `-' found")) + assert(message.endsWith(s"identifier expected but `-' found")) case _ => sys.error(parseResult.toString) } diff --git a/src/test/scala/scala/util/parsing/combinator/JsonTest.scala b/shared/src/test/scala/scala/util/parsing/combinator/JsonTest.scala similarity index 98% rename from src/test/scala/scala/util/parsing/combinator/JsonTest.scala rename to shared/src/test/scala/scala/util/parsing/combinator/JsonTest.scala index cb24a334..84e15bfb 100644 --- a/src/test/scala/scala/util/parsing/combinator/JsonTest.scala +++ b/shared/src/test/scala/scala/util/parsing/combinator/JsonTest.scala @@ -120,7 +120,10 @@ class JsonTest { assertEquals("{\"name\" : {\"name1\" : \"va1ue1\", \"name2\" : \"va1ue2\"}}", JSONObject(Map("name" -> JSONObject(TreeMap("name1" -> "va1ue1", "name2" -> "va1ue2")))).toString()) - assertEquals("[4.0, 1.0, 3.0, 2.0, 6.0, 5.0, 8.0, 7.0]", JSONArray(List[Double](4,1,3,2,6,5,8,7)).toString()) + val expected = + if (1.0.toString == "1") "[4, 1, 3, 2, 6, 5, 8, 7]" + else "[4.0, 1.0, 3.0, 2.0, 6.0, 5.0, 8.0, 7.0]" + assertEquals(expected, JSONArray(List[Double](4,1,3,2,6,5,8,7)).toString()) } // A test method that escapes all characters in strings diff --git a/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala b/shared/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala rename to shared/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala diff --git a/src/test/scala/scala/util/parsing/combinator/RegexParsersTest.scala b/shared/src/test/scala/scala/util/parsing/combinator/RegexParsersTest.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/RegexParsersTest.scala rename to shared/src/test/scala/scala/util/parsing/combinator/RegexParsersTest.scala diff --git a/src/test/scala/scala/util/parsing/combinator/UnitTestIO.scala b/shared/src/test/scala/scala/util/parsing/combinator/UnitTestIO.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/UnitTestIO.scala rename to shared/src/test/scala/scala/util/parsing/combinator/UnitTestIO.scala diff --git a/src/test/scala/scala/util/parsing/combinator/gh45.scala b/shared/src/test/scala/scala/util/parsing/combinator/gh45.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/gh45.scala rename to shared/src/test/scala/scala/util/parsing/combinator/gh45.scala diff --git a/src/test/scala/scala/util/parsing/combinator/gh56.scala b/shared/src/test/scala/scala/util/parsing/combinator/gh56.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/gh56.scala rename to shared/src/test/scala/scala/util/parsing/combinator/gh56.scala diff --git a/src/test/scala/scala/util/parsing/combinator/t0700.scala b/shared/src/test/scala/scala/util/parsing/combinator/t0700.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/t0700.scala rename to shared/src/test/scala/scala/util/parsing/combinator/t0700.scala diff --git a/src/test/scala/scala/util/parsing/combinator/t1100.scala b/shared/src/test/scala/scala/util/parsing/combinator/t1100.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/t1100.scala rename to shared/src/test/scala/scala/util/parsing/combinator/t1100.scala diff --git a/src/test/scala/scala/util/parsing/combinator/t4138.scala b/shared/src/test/scala/scala/util/parsing/combinator/t4138.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/t4138.scala rename to shared/src/test/scala/scala/util/parsing/combinator/t4138.scala diff --git a/src/test/scala/scala/util/parsing/combinator/t5514.scala b/shared/src/test/scala/scala/util/parsing/combinator/t5514.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/t5514.scala rename to shared/src/test/scala/scala/util/parsing/combinator/t5514.scala diff --git a/src/test/scala/scala/util/parsing/combinator/t8879.scala b/shared/src/test/scala/scala/util/parsing/combinator/t8879.scala similarity index 100% rename from src/test/scala/scala/util/parsing/combinator/t8879.scala rename to shared/src/test/scala/scala/util/parsing/combinator/t8879.scala From 5df662c9a2e81c716afe6e12f992d00086ea04f9 Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Tue, 20 Sep 2016 14:59:31 +0200 Subject: [PATCH 16/17] bump sbt, scala & dependency versions to latest --- build.sbt | 8 ++++---- project/build.properties | 2 +- project/plugins.sbt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.sbt b/build.sbt index 61cdd133..a4f93bcf 100644 --- a/build.sbt +++ b/build.sbt @@ -5,9 +5,9 @@ crossScalaVersions in ThisBuild := { val isJDK6Or7 = javaVersion.startsWith("1.6.") || javaVersion.startsWith("1.7.") if (isJDK6Or7) - Seq("2.11.7") + Seq("2.11.8") else - Seq("2.11.7", "2.12.0-M3") + Seq("2.11.8", "2.12.0-RC1") } lazy val `scala-parser-combinators` = crossProject.in(file(".")). @@ -43,8 +43,8 @@ lazy val `scala-parser-combinators` = crossProject.in(file(".")). ). jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin)). jvmSettings( - libraryDependencies += "junit" % "junit" % "4.11" % "test", - libraryDependencies += "com.novocode" % "junit-interface" % "0.10" % "test" + libraryDependencies += "junit" % "junit" % "4.12" % "test", + libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" ). jvmSettings( mimaPreviousVersion := Some("1.0.4") diff --git a/project/build.properties b/project/build.properties index 817bc38d..35c88bab 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.9 +sbt.version=0.13.12 diff --git a/project/plugins.sbt b/project/plugins.sbt index 8fef081e..983683a9 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ addSbtPlugin("org.scala-lang.modules" % "scala-module-plugin" % "1.0.4") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.6") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.12") From cdfba62ae6ea58ceb255a1f836815fa5c9efa800 Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Tue, 4 Oct 2016 17:56:54 +0200 Subject: [PATCH 17/17] Redo how cross-version publishing works It used to be: only publish on JDK 6. But now, 2.12.x requires Java 8. So we want the 2.11.x version to be published on JDK 6, the 2.12.x version on JDK 8, and nothing on JDK 7. Outside of publishing, we just run and test everything that can run on the current JDK, like before. This is inspired by Seth's commit at scala/scala-xml@38fbbbeeff6bc97c4438e3e37041894c93538e46 --- .travis.yml | 2 -- admin/README.md | 3 +-- admin/build.sh | 2 +- build.sbt | 22 ++++++++++++++++------ 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 501e32d6..fc712cd6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ before_install: env: global: - - PUBLISH_JDK=openjdk6 # PGP_PASSPHRASE - secure: "SkBtn/6OjEldoikn0MFuyeLT/pau27kwKSDYTVQeJ4BKDzdWLwLE5Q3RukLGttIfNdhOvRoocpQSW9GkZfibTHmwrRnAokucfZCqTsKbwoOp1xIoOh5GrrVrB6gcP7WBTKinqFdBgSvLOrP7GviImz4ZuB9wq1r+mToGG4pDrXc=" # SONA_USER @@ -21,7 +20,6 @@ script: admin/build.sh jdk: - openjdk6 - - openjdk7 - oraclejdk8 notifications: diff --git a/admin/README.md b/admin/README.md index 55ae9c8a..7f38379a 100644 --- a/admin/README.md +++ b/admin/README.md @@ -19,7 +19,7 @@ To configure tag driven releases from Travis CI. Edit `.travis.yml` as prompted. 4. Edit `.travis.yml` to use `./admin/build.sh` as the build script, and edit that script to use the tasks required for this project. - 5. Edit `.travis.yml` to select which JDK will be used for publishing. + 5. Edit `build.sbt` to select which JDK will be used for publishing. It is important to add comments in .travis.yml to identify the name of each environment variable encoded in a `:secure` section. @@ -30,7 +30,6 @@ form: language: scala env: global: - - PUBLISH_JDK=openjdk6 # PGP_PASSPHRASE - secure: "XXXXXX" # SONA_USER diff --git a/admin/build.sh b/admin/build.sh index ddd6d5e0..ce76249d 100755 --- a/admin/build.sh +++ b/admin/build.sh @@ -7,7 +7,7 @@ set -e # git on travis does not fetch tags, but we have TRAVIS_TAG # headTag=$(git describe --exact-match ||:) -if [ "$TRAVIS_JDK_VERSION" == "$PUBLISH_JDK" ] && [[ "$TRAVIS_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)? ]]; then +if [[ "$TRAVIS_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)? ]]; then echo "Going to release from tag $TRAVIS_TAG!" myVer=$(echo $TRAVIS_TAG | sed -e s/^v//) publishVersion='set every version := "'$myVer'"' diff --git a/build.sbt b/build.sbt index a4f93bcf..0e3d33f7 100644 --- a/build.sbt +++ b/build.sbt @@ -1,13 +1,23 @@ scalaVersion in ThisBuild := crossScalaVersions.value.head crossScalaVersions in ThisBuild := { + val v211 = List("2.11.8") + val v212 = List("2.12.0-RC1") + val javaVersion = System.getProperty("java.version") - val isJDK6Or7 = - javaVersion.startsWith("1.6.") || javaVersion.startsWith("1.7.") - if (isJDK6Or7) - Seq("2.11.8") - else - Seq("2.11.8", "2.12.0-RC1") + val isTravisPublishing = !util.Properties.envOrElse("TRAVIS_TAG", "").trim.isEmpty + + if (isTravisPublishing) { + if (javaVersion.startsWith("1.6.")) v211 + else if (javaVersion.startsWith("1.8.")) v212 + else Nil + } else if (javaVersion.startsWith("1.6.") || javaVersion.startsWith("1.7.")) { + v211 + } else if (javaVersion.startsWith("1.8.") || javaVersion.startsWith("9")) { + v211 ++ v212 + } else { + sys.error(s"Unsupported java version: $javaVersion.") + } } lazy val `scala-parser-combinators` = crossProject.in(file(".")).