From a9701a4ec62c60ae958dd7a33ff0c7163b54ec0a Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Thu, 31 Jan 2019 16:37:10 +0100 Subject: [PATCH 1/6] Update to fastparse 2 (#510) Disabled 'native' targets for now since fastparse 2 has not been released for Scala Native yet. --- .travis.yml | 14 +-- build.sbt | 18 ++- project/plugins.sbt | 2 +- .../src/test/scala/SchemaGenerators.scala | 2 +- .../src/main/scala/scalapb/TextFormat.scala | 8 +- .../scala/scalapb/textformat/Basics.scala | 52 ++++----- .../scalapb/textformat/ProtoAsciiParser.scala | 31 ++--- .../scala/scalapb/textformat/BasicsSpec.scala | 106 +++++++++--------- .../scala/scalapb/textformat/ParserSpec.scala | 54 ++++----- .../scalapb/textformat/ParserSuite.scala | 21 ++-- 10 files changed, 151 insertions(+), 157 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6ef9a04c..1163f1843 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,13 +28,13 @@ matrix: jobs: include: - - env: SCALA_NATIVE - scala: 2.11.12 - before_install: - - sudo apt-get update - - curl https://raw.githubusercontent.com/scala-native/scala-native/master/scripts/travis_setup.sh | bash -x - script: - - sbt ++2.11.12 runtimeNative/test lensesNative/test + #- env: SCALA_NATIVE + # scala: 2.11.12 + # before_install: + # - sudo apt-get update + # - curl https://raw.githubusercontent.com/scala-native/scala-native/master/scripts/travis_setup.sh | bash -x + # script: + # - sbt ++2.11.12 runtimeNative/test lensesNative/test - env: EXAMPLES_AND_FORMATTING scala: 2.11.12 script: diff --git a/build.sbt b/build.sbt index dfd7b8895..d09214f21 100644 --- a/build.sbt +++ b/build.sbt @@ -85,12 +85,14 @@ lazy val root = proptest, scalapbc) -lazy val runtime = crossProject(JSPlatform, JVMPlatform, NativePlatform) +// fastparse 2 is not available for Scala Native yet +// https://github.com/lihaoyi/fastparse/issues/215 +lazy val runtime = crossProject(JSPlatform, JVMPlatform/*, NativePlatform*/) .crossType(CrossType.Full).in(file("scalapb-runtime")) .settings( name := "scalapb-runtime", libraryDependencies ++= Seq( - "com.lihaoyi" %%% "fastparse" % "1.0.0", + "com.lihaoyi" %%% "fastparse" % "2.1.0", "com.lihaoyi" %%% "utest" % "0.6.6" % "test", "commons-codec" % "commons-codec" % "1.11" % "test", "com.google.protobuf" % "protobuf-java-util" % protobufVersion % "test", @@ -129,7 +131,7 @@ lazy val runtime = crossProject(JSPlatform, JVMPlatform, NativePlatform) } ) .dependsOn(lenses) - .platformsSettings(JSPlatform, NativePlatform)( + .platformsSettings(JSPlatform/*, NativePlatform*/)( libraryDependencies ++= Seq( "com.thesamet.scalapb" %%% "protobuf-runtime-scala" % "0.7.1" ), @@ -152,14 +154,16 @@ lazy val runtime = crossProject(JSPlatform, JVMPlatform, NativePlatform) }, unmanagedResourceDirectories in Compile += baseDirectory.value / "../../third_party" ) +/* .nativeSettings( sharedNativeSettings ) +*/ lazy val runtimeJVM = runtime.jvm lazy val runtimeJS = runtime.js -lazy val runtimeNative = runtime.native +//lazy val runtimeNative = runtime.native lazy val grpcRuntime = project.in(file("scalapb-runtime-grpc")) .dependsOn(runtimeJVM) @@ -307,7 +311,7 @@ createVersionFile := { log.info(s"Created $f2") } -lazy val lenses = crossProject(JSPlatform, JVMPlatform, NativePlatform).in(file("lenses")) +lazy val lenses = crossProject(JSPlatform, JVMPlatform/*, NativePlatform*/).in(file("lenses")) .settings( name := "lenses", sources in Test := { @@ -340,13 +344,15 @@ lazy val lenses = crossProject(JSPlatform, JVMPlatform, NativePlatform).in(file( s"-P:scalajs:mapSourceURI:$a->$g/" } ) +/* .nativeSettings( sharedNativeSettings ) +*/ lazy val lensesJVM = lenses.jvm lazy val lensesJS = lenses.js -lazy val lensesNative = lenses.native +//lazy val lensesNative = lenses.native lazy val docs = project.in(file("docs")) .enablePlugins(MicrositesPlugin, ScalaUnidocPlugin) diff --git a/project/plugins.sbt b/project/plugins.sbt index 7957b6a43..ff641675b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -10,7 +10,7 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.16") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.0") -addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "0.6.0") +//addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "0.6.0") addSbtPlugin("org.scala-js" % "sbt-scalajs" % scalaJSVersion) diff --git a/proptest/src/test/scala/SchemaGenerators.scala b/proptest/src/test/scala/SchemaGenerators.scala index a1615e9f0..8040ab24f 100644 --- a/proptest/src/test/scala/SchemaGenerators.scala +++ b/proptest/src/test/scala/SchemaGenerators.scala @@ -228,7 +228,7 @@ object SchemaGenerators { jarForClass[com.google.common.util.concurrent.ListenableFuture[_]], jarForClass[javax.annotation.Nullable], jarForClass[scalapb.lenses.Lens[_, _]].getPath, - jarForClass[fastparse.core.Parsed[_, _, _]].getPath, + jarForClass[fastparse.Parsed[_]].getPath, rootDir ) val annotationJar = diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala b/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala index cc9b8758b..09e297877 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala @@ -1,7 +1,7 @@ package scalapb import scalapb.textformat.{AstUtils, Printer, ProtoAsciiParser} -import fastparse.core.{ParseError, Parsed} +import fastparse._ case class TextFormatError(msg: String) @@ -20,13 +20,13 @@ object TextFormat { d: GeneratedMessageCompanion[T], s: String ): Either[TextFormatError, T] = { - ProtoAsciiParser.Message.parse(s) match { + parse(s, ProtoAsciiParser.Message(_)) match { case Parsed.Success(msg, _) => AstUtils.parseMessage(d, msg).left.map { a => TextFormatError(s"${a.error} (${indexToLineCol(s, a.index)})") } - case f: Parsed.Failure[Char, String] => - Left(TextFormatError(ParseError(f).getMessage)) + case f: Parsed.Failure => + Left(TextFormatError(f.longMsg)) } } diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala index 3c90a28da..e90586a81 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala @@ -1,14 +1,14 @@ package scalapb.textformat -import fastparse.core.ParserApi +import fastparse.NoWhitespace._ import scala.language.implicitConversions object Basics extends ParserCompat { - import fastparse.all._ + import fastparse._ - val Newline = P(StringIn("\r\n", "\n")) + def Newline[_: P] = P(StringIn("\r\n", "\n")) case class NamedFunction[T, V](f: T => V, name: String) extends (T => V) { def apply(t: T) = f(t) @@ -24,49 +24,49 @@ object Basics extends ParserCompat { val CharChunk = NamedFunction((c: Char) => !"\n\r".contains(c), "CharChunk") // TODO(nadavsr): figure out this - val sameLineCharChunks = P(CharsWhile(CharChunk) | (!Newline) ~ AnyChar) + def sameLineCharChunks[_: P] = P(CharsWhile(CharChunk) | (!Newline) ~ AnyChar) - val lineComment = P("#" ~ sameLineCharChunks.rep ~ &(Newline | End)) + def lineComment[_: P] = P("#" ~ sameLineCharChunks.rep ~ &(Newline | End)) - val whiteSpace = (CharIn(" \n\r\t\f") | lineComment).opaque("whitespace").rep + def whiteSpace[_: P] = (CharIn(" \n\r\t\f") | lineComment).opaque("whitespace").rep - val identifier = P(CharIn('a' to 'z', 'A' to 'Z', '0' to '9', "_").rep(1).!).opaque("identifier") + def identifier[_: P] = P(CharIn("a-z", "A-Z", "0-9", "_").rep(1).!).opaque("identifier") - val literal = P(CharIn('a' to 'z', 'A' to 'Z', '0' to '9', "_-.").rep(1).!).opaque("literal") + def literal[_: P] = P(CharIn("a-z", "A-Z", "0-9", "_\\-.").rep(1).!).opaque("literal") - val digits = P(CharsWhile(Digits)) - val hexDigits = P(CharsWhile(HexDigits)) - val octDigits = P(CharsWhile(OctDigits)) + def digits[_: P] = P(CharsWhile(Digits)) + def hexDigits[_: P] = P(CharsWhile(HexDigits)) + def octDigits[_: P] = P(CharsWhile(OctDigits)) - val exponent = P(CharIn("eE") ~ CharIn("+-").? ~ digits) - val fractional = - (CharIn("+-").? ~ (digits ~ "." ~ digits.? | "." ~ digits) ~ exponent.? ~ CharIn("fF").?).! + def exponent[_: P] = P(CharIn("eE") ~ CharIn("+\\-").? ~ digits) + def fractional[_: P] = + (CharIn("+\\-").? ~ (digits ~ "." ~ digits.? | "." ~ digits) ~ exponent.? ~ CharIn("fF").?).! - val decIntegral = P("0" | CharIn('1' to '9') ~ digits.?).!.map(p => BigInt(p)) - val hexIntegral = P("0x" ~/ hexDigits.!).map(p => BigInt(p, 16)) - val octIntegral = P("0" ~ octDigits.!).map(p => BigInt(p, 8)) + def decIntegral[_: P] = P("0" | CharIn("1-9") ~ digits.?).!.map(p => BigInt(p)) + def hexIntegral[_: P] = P("0x" ~/ hexDigits.!).map(p => BigInt(p, 16)) + def octIntegral[_: P] = P("0" ~ octDigits.!).map(p => BigInt(p, 8)) - val integral: P[BigInt] = P(hexIntegral | octIntegral | decIntegral) + def integral[_: P]: P[BigInt] = P(hexIntegral | octIntegral | decIntegral) - val bigInt: P[BigInt] = P(CharIn("+-").!.? ~ integral).map({ + def bigInt[_: P]: P[BigInt] = P(CharIn("+\\-").!.? ~ integral).map({ case (Some("-"), number) => -number case (_, number) => number }) - val strNoDQChars = P(CharsWhile(!"\"\n\\".contains(_: Char))) - val strNoQChars = P(CharsWhile(!"'\n\\".contains(_: Char))) - val escape = P("\\" ~ AnyChar) - val singleBytesLiteral = P( + def strNoDQChars[_: P] = P(CharsWhile(!"\"\n\\".contains(_: Char))) + def strNoQChars [_: P] = P(CharsWhile(!"'\n\\".contains(_: Char))) + def escape [_: P] = P("\\" ~ AnyChar) + def singleBytesLiteral[_: P] = P( "\"" ~/ (strNoDQChars | escape).rep.! ~ "\"" | "'" ~/ (strNoQChars | escape).rep.! ~ "'" ).opaque("string") - val bytesLiteral = P(singleBytesLiteral.rep(1, whiteSpace)).map(_.mkString) + def bytesLiteral[_: P] = P(singleBytesLiteral.rep(1, whiteSpace)).map(_.mkString) - val boolean: P[Boolean] = P( + def boolean[_: P]: P[Boolean] = P( ("true" | "t" | "1").map(_ => true) | ("false" | "f" | "0").map(_ => false) ).opaque("'true' or 'false'") - def ws(s: String): P[Unit] = P(s ~ &(whiteSpace)) + def ws[_: P](s: String): P[Unit] = P(s ~ &(whiteSpace)) } diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala index 3ed31fce8..3c7d4e458 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala @@ -1,48 +1,37 @@ package scalapb.textformat -import fastparse.WhitespaceApi +import fastparse._ +import fastparse.ScriptWhitespace._ import scala.language.implicitConversions private[scalapb] object ProtoAsciiParser { - val White = WhitespaceApi.Wrapper { - import fastparse.all._ - - NoTrace(Basics.whiteSpace) - } - - import fastparse.noApi._ - - // This is needed due to https://github.com/lihaoyi/fastparse/issues/72 - protected implicit def strToParserApi(s: String): WhitespaceApi[Unit] = White.parserApi(s) - protected implicit def parserToParserApi[T](s: Parser[T]): WhitespaceApi[T] = White.parserApi(s) - - val PrimitiveValue: P[TPrimitive] = P( + def PrimitiveValue[_: P]: P[TPrimitive] = P( (Index ~ Basics.fractional).map(TLiteral.tupled) | (Index ~ Basics.bigInt).map(TIntLiteral.tupled) | (Index ~ Basics.bytesLiteral).map(TBytes.tupled) | (Index ~ Basics.literal).map(TLiteral.tupled) ) - val MessageValue: P[TMessage] = P( + def MessageValue[_: P]: P[TMessage] = P( Index ~ "{" ~/ KeyValue.rep ~/ "}" | Index ~ "<" ~/ KeyValue.rep ~/ ">" ).map(TMessage.tupled) - val ValueArray: P[TValue] = - P((Index ~ "[" ~/ (PrimitiveValue | MessageValue).rep(0, ",".~/) ~/ "]")).map(TArray.tupled) + def ValueArray[_: P]: P[TValue] = + P((Index ~ "[" ~/ (PrimitiveValue | MessageValue).rep(0, ",") ~/ "]")).map(TArray.tupled) - val MessageArray: P[TValue] = + def MessageArray[_: P]: P[TValue] = P((Index ~ "[" ~/ MessageValue.rep(0, ",") ~/ "]")).map(TArray.tupled) - val Value: P[TValue] = P( + def Value[_: P]: P[TValue] = P( MessageValue | MessageArray | ":" ~/ (MessageValue | ValueArray | PrimitiveValue) ).opaque("':', '{', '<', or '['") - val KeyValue: P[TField] = P( + def KeyValue[_: P]: P[TField] = P( Index ~ Basics.identifier ~/ Value ).map(TField.tupled) - val Message: P[TMessage] = P(Index ~ KeyValue.rep ~ End).map(TMessage.tupled) + def Message[_: P]: P[TMessage] = P(Index ~ KeyValue.rep ~ End).map(TMessage.tupled) } diff --git a/scalapb-runtime/shared/src/test/scala/scalapb/textformat/BasicsSpec.scala b/scalapb-runtime/shared/src/test/scala/scalapb/textformat/BasicsSpec.scala index f2ae8d775..02dbc10a2 100644 --- a/scalapb-runtime/shared/src/test/scala/scalapb/textformat/BasicsSpec.scala +++ b/scalapb-runtime/shared/src/test/scala/scalapb/textformat/BasicsSpec.scala @@ -6,75 +6,75 @@ object BasicsSpec extends TestSuite with ParserSuite { import Basics._ - val tests = TestSuite { + val tests = Tests { 'identifier { - check(identifier, "abcd", "abcd") - check(identifier, "abcd_2", "abcd_2") - check(identifier, "abcd_2_vxyz", "abcd_2_vxyz") - check(identifier, "abcd bar", "abcd") - check(identifier, "2abc", "2abc") - checkFail(identifier, " abcd") + check(identifier(_), "abcd", "abcd") + check(identifier(_), "abcd_2", "abcd_2") + check(identifier(_), "abcd_2_vxyz", "abcd_2_vxyz") + check(identifier(_), "abcd bar", "abcd") + check(identifier(_), "2abc", "2abc") + checkFail(identifier(_), " abcd") } 'number { - check(fractional, "0.2", "0.2") - check(fractional, "2.0", "2.0") - check(fractional, "2.0f", "2.0f") - check(fractional, "-12.34f", "-12.34f") - check(fractional, ".2", ".2") - check(fractional, "2.3e+14", "2.3e+14") - check(fractional, "2.3e-14", "2.3e-14") - check(fractional, ".3e-14", ".3e-14") - check(fractional, ".3e+14", ".3e+14") - check(fractional, ".3e+14F", ".3e+14F") - check(fractional, "2.", "2.") - check(fractional, "2.e+5", "2.e+5") - check(fractional, "2.e+5f", "2.e+5f") - checkFail(fractional, ".") - checkFail(fractional, "17") - checkFail(fractional, "0") + check(fractional(_), "0.2", "0.2") + check(fractional(_), "2.0", "2.0") + check(fractional(_), "2.0f", "2.0f") + check(fractional(_), "-12.34f", "-12.34f") + check(fractional(_), ".2", ".2") + check(fractional(_), "2.3e+14", "2.3e+14") + check(fractional(_), "2.3e-14", "2.3e-14") + check(fractional(_), ".3e-14", ".3e-14") + check(fractional(_), ".3e+14", ".3e+14") + check(fractional(_), ".3e+14F", ".3e+14F") + check(fractional(_), "2.", "2.") + check(fractional(_), "2.e+5", "2.e+5") + check(fractional(_), "2.e+5f", "2.e+5f") + checkFail(fractional(_), ".") + checkFail(fractional(_), "17") + checkFail(fractional(_), "0") } 'bigint { - check(bigInt, "0", 0) - check(bigInt, "-0", 0) - check(bigInt, "0x14", 0x14) - check(bigInt, "-0x14", -0x14) - check(bigInt, "025", 21) - check(bigInt, "-025", -21) - check(bigInt, "1417", 1417) - check(bigInt, "-1417", -1417) - check(bigInt, "33353333333333333333333333333", BigInt("33353333333333333333333333333")) - check(bigInt, "-33353333333333333333333333333", BigInt("-33353333333333333333333333333")) - checkFail(bigInt, "abcd") + check(bigInt(_), "0", 0) + check(bigInt(_), "-0", 0) + check(bigInt(_), "0x14", 0x14) + check(bigInt(_), "-0x14", -0x14) + check(bigInt(_), "025", 21) + check(bigInt(_), "-025", -21) + check(bigInt(_), "1417", 1417) + check(bigInt(_), "-1417", -1417) + check(bigInt(_), "33353333333333333333333333333", BigInt("33353333333333333333333333333")) + check(bigInt(_), "-33353333333333333333333333333", BigInt("-33353333333333333333333333333")) + checkFail(bigInt(_), "abcd") } 'literal { - check(literal, "1.0f", "1.0f") + check(literal(_), "1.0f", "1.0f") } 'boolean { - check(boolean, "t", true) - check(boolean, "1", true) - check(boolean, "f", false) - check(boolean, "0", false) + check(boolean(_), "t", true) + check(boolean(_), "1", true) + check(boolean(_), "f", false) + check(boolean(_), "0", false) } 'bytes { - check(bytesLiteral, "\"hello\"", "hello") - check(bytesLiteral, "\"he'llo\"", "he'llo") - check(bytesLiteral, "\"he\\\"llo\"", "he\\\"llo") - check(bytesLiteral, "\"he\\'llo\"", "he\\'llo") - check(bytesLiteral, "'he\"llo'", "he\"llo") - check(bytesLiteral, "\"hello world\"", "hello world") - check(bytesLiteral, "\"hello world\" \"boo\"", "hello worldboo") - check(bytesLiteral, "\"hello world\" \'boo\'", "hello worldboo") - check(bytesLiteral, "\"hello\\nfoo\"", "hello\\nfoo") - check(bytesLiteral, "\"\\000\\001\\a\\n\"", "\\000\\001\\a\\n") - check(bytesLiteral, "\"\\000\\001\\a\\n\"", "\\000\\001\\a\\n") - check(bytesLiteral, "\"\u5d8b\u2367\u633d\"", "\u5d8b\u2367\u633d") - checkFail(bytesLiteral, "\"hello\nfoo\"") - checkFail(bytesLiteral, "\"hello\'") + check(bytesLiteral(_), "\"hello\"", "hello") + check(bytesLiteral(_), "\"he'llo\"", "he'llo") + check(bytesLiteral(_), "\"he\\\"llo\"", "he\\\"llo") + check(bytesLiteral(_), "\"he\\'llo\"", "he\\'llo") + check(bytesLiteral(_), "'he\"llo'", "he\"llo") + check(bytesLiteral(_), "\"hello world\"", "hello world") + check(bytesLiteral(_), "\"hello world\" \"boo\"", "hello worldboo") + check(bytesLiteral(_), "\"hello world\" \'boo\'", "hello worldboo") + check(bytesLiteral(_), "\"hello\\nfoo\"", "hello\\nfoo") + check(bytesLiteral(_), "\"\\000\\001\\a\\n\"", "\\000\\001\\a\\n") + check(bytesLiteral(_), "\"\\000\\001\\a\\n\"", "\\000\\001\\a\\n") + check(bytesLiteral(_), "\"\u5d8b\u2367\u633d\"", "\u5d8b\u2367\u633d") + checkFail(bytesLiteral(_), "\"hello\nfoo\"") + checkFail(bytesLiteral(_), "\"hello\'") } } diff --git a/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSpec.scala b/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSpec.scala index 660a0aac5..3407dbb22 100644 --- a/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSpec.scala +++ b/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSpec.scala @@ -6,18 +6,18 @@ object ParserSpec extends TestSuite with ParserSuite { import ProtoAsciiParser._ - val tests = TestSuite { + val tests = Tests { 'KeyValue { - check(KeyValue, "foo: 17", TField(0, "foo", TIntLiteral(5, 17))) - check(KeyValue, "foo: 0x13 ", TField(0, "foo", TIntLiteral(8, 0x13))) - check(KeyValue, "bar: true", TField(0, "bar", TLiteral(5, "true"))) - check(KeyValue, "bar: true ", TField(0, "bar", TLiteral(12, "true"))) - check(KeyValue, "bar : true ", TField(0, "bar", TLiteral(14, "true"))) - check(KeyValue, "barr: true ", TField(0, "barr", TLiteral(13, "true"))) + check(KeyValue(_), "foo: 17", TField(0, "foo", TIntLiteral(5, 17))) + check(KeyValue(_), "foo: 0x13 ", TField(0, "foo", TIntLiteral(8, 0x13))) + check(KeyValue(_), "bar: true", TField(0, "bar", TLiteral(5, "true"))) + check(KeyValue(_), "bar: true ", TField(0, "bar", TLiteral(12, "true"))) + check(KeyValue(_), "bar : true ", TField(0, "bar", TLiteral(14, "true"))) + check(KeyValue(_), "barr: true ", TField(0, "barr", TLiteral(13, "true"))) // check(KeyValue, "barr: 1e-17 ", PField(0, "barr", PLiteral(13, "1e-17"))) check( - KeyValue, + KeyValue(_), "foo { x: 3 }", TField( 0, @@ -32,7 +32,7 @@ object ParserSpec extends TestSuite with ParserSuite { ) check( - KeyValue, + KeyValue(_), "foo { x: 3 y: 4}", TField( 0, @@ -48,7 +48,7 @@ object ParserSpec extends TestSuite with ParserSuite { ) check( - KeyValue, + KeyValue(_), """foo { | | x: 3 y: 4 @@ -67,7 +67,7 @@ object ParserSpec extends TestSuite with ParserSuite { ) check( - KeyValue, + KeyValue(_), """foo { | # comment | x: 3 # comment 2 @@ -91,7 +91,7 @@ object ParserSpec extends TestSuite with ParserSuite { ) check( - KeyValue, + KeyValue(_), """foo < | # comment | x: 3 # comment 2 @@ -115,7 +115,7 @@ object ParserSpec extends TestSuite with ParserSuite { ) check( - KeyValue, + KeyValue(_), "foo [{bar: 4}, {t: 17}]", TField( 0, @@ -131,41 +131,41 @@ object ParserSpec extends TestSuite with ParserSuite { ) check( - KeyValue, + KeyValue(_), "foo: [0, 2]", TField(0, "foo", TArray(5, Seq(TIntLiteral(6, 0), TIntLiteral(9, 2)))) ) - check(KeyValue, "foo: []", TField(0, "foo", TArray(5, Seq()))) + check(KeyValue(_), "foo: []", TField(0, "foo", TArray(5, Seq()))) - check(KeyValue, "foo []", TField(0, "foo", TArray(4, Seq()))) + check(KeyValue(_), "foo []", TField(0, "foo", TArray(4, Seq()))) - check(KeyValue, "foo { }", TField(0, "foo", TMessage(4, Seq()))) + check(KeyValue(_), "foo { }", TField(0, "foo", TMessage(4, Seq()))) - check(KeyValue, "foo: { }", TField(0, "foo", TMessage(5, Seq()))) + check(KeyValue(_), "foo: { }", TField(0, "foo", TMessage(5, Seq()))) check( - KeyValue, + KeyValue(_), "foo: \"\u5d8b\u2367\u633d\"", TField(0, "foo", TBytes(5, "\u5d8b\u2367\u633d")) ) check( - KeyValue, + KeyValue(_), "foo: [{bar: 4}]", TField(0, "foo", TArray(5, Seq(TMessage(6, Seq(TField(7, "bar", TIntLiteral(12, 4))))))) ) - checkFail(KeyValue, "foo 17") - checkFail(KeyValue, "foo: [[17, 5]]") - checkFail(KeyValue, "foo { x: 3") - checkFail(KeyValue, "foo [{bar: 4}, 17]") - checkFail(KeyValue, "foo [,]") + checkFail(KeyValue(_), "foo 17") + checkFail(KeyValue(_), "foo: [[17, 5]]") + checkFail(KeyValue(_), "foo { x: 3") + checkFail(KeyValue(_), "foo [{bar: 4}, 17]") + checkFail(KeyValue(_), "foo [,]") } 'Message { check( - Message, + Message(_), """foo: 4 |baz: true |bal: [3, 4, 5] @@ -206,7 +206,7 @@ object ParserSpec extends TestSuite with ParserSuite { ) ) check( - Message, + Message(_), """wa { | e5 { | brr { diff --git a/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSuite.scala b/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSuite.scala index 1eee9444a..c92c99ea6 100644 --- a/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSuite.scala +++ b/scalapb-runtime/shared/src/test/scala/scalapb/textformat/ParserSuite.scala @@ -1,28 +1,27 @@ package scalapb.textformat -import fastparse.core.Parsed import utest.assert trait ParserSuite { - import fastparse.all.P + import fastparse._ - def check[T](parser: P[T], input: String, expected: T) = { - val Parsed.Success(value, _) = parser.parse(input) + def check[T](parser: P[_] => P[T], input: String, expected: T) = { + val Parsed.Success(value, _) = parse(input, parser(_)) assert(value == expected) } - def check[T](parser: P[T], input: String)(checker: T => Boolean) = { - val Parsed.Success(value, _) = parser.parse(input) + def check[T](parser: P[_] => P[T], input: String)(checker: T => Boolean) = { + val Parsed.Success(value, _) = parse(input, parser(_)) assert(checker(value)) } - def checkFail[T](parser: P[T], input: String) = { - assert(parser.parse(input).isInstanceOf[Parsed.Failure[_, _]]) + def checkFail[T](parser: P[_] => P[T], input: String) = { + assert(parse(input, parser(_)).isInstanceOf[Parsed.Failure]) } - def checkFail[T](parser: P[T], input: String, expectedTrace: String) = { - val failure = parser.parse(input).asInstanceOf[Parsed.Failure[_, _]] - val actualTrace = failure.extra.traced.trace + def checkFail[T](parser: P[_] => P[T], input: String, expectedTrace: String) = { + val failure = parse(input, parser(_)).asInstanceOf[Parsed.Failure] + val actualTrace = failure.extra.trace(true).msg assert(expectedTrace.trim == actualTrace.trim) } } From ef00fc31fee13fe14d7e8b8855a547ef22a843ef Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Thu, 31 Jan 2019 18:03:54 +0100 Subject: [PATCH 2/6] Exclude parsing code from MiMa As I don't think it is supposed to be part of the public API? --- build.sbt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index d09214f21..776b7a912 100644 --- a/build.sbt +++ b/build.sbt @@ -126,7 +126,11 @@ lazy val runtime = crossProject(JSPlatform, JVMPlatform/*, NativePlatform*/) ProblemFilters.exclude[DirectMissingMethodProblem]("scalapb.descriptors.FieldDescriptor.buildFieldDescriptor"), ProblemFilters.exclude[DirectMissingMethodProblem]("scalapb.descriptors.FieldDescriptor.this"), ProblemFilters.exclude[DirectMissingMethodProblem]("scalapb.descriptors.Descriptor.this"), - ProblemFilters.exclude[DirectMissingMethodProblem]("scalapb.descriptors.EnumDescriptor.this") + ProblemFilters.exclude[DirectMissingMethodProblem]("scalapb.descriptors.EnumDescriptor.this"), + + // Parsing + ProblemFilters.exclude[DirectMissingMethodProblem]("scalapb.textformat.Basics.*"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scalapb.textformat.ProtoAsciiParser.*"), ) } ) From 5ba03c6f635962899758ca46227975bacce69c67 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Thu, 31 Jan 2019 19:35:47 +0100 Subject: [PATCH 3/6] Make e2e tests compile --- e2e/src/test/scala/scalapb/TextFormatSpec.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/src/test/scala/scalapb/TextFormatSpec.scala b/e2e/src/test/scala/scalapb/TextFormatSpec.scala index 9d15c69c3..7665fbe1b 100644 --- a/e2e/src/test/scala/scalapb/TextFormatSpec.scala +++ b/e2e/src/test/scala/scalapb/TextFormatSpec.scala @@ -324,16 +324,16 @@ class TextFormatSpec extends FlatSpec with GeneratorDrivenPropertyChecks with Mu } def parseInt32[T](input: String): Int = - AstUtils.parseInt32(ProtoAsciiParser.PrimitiveValue.parse(input).get.value).right.get.value + AstUtils.parseInt32(fastparse.parse(input, ProtoAsciiParser.PrimitiveValue(_)).get.value).right.get.value def parseInt64[T](input: String): Long = - AstUtils.parseInt64(ProtoAsciiParser.PrimitiveValue.parse(input).get.value).right.get.value + AstUtils.parseInt64(fastparse.parse(input, ProtoAsciiParser.PrimitiveValue(_)).get.value).right.get.value def parseUInt32[T](input: String): Int = - AstUtils.parseUint32(ProtoAsciiParser.PrimitiveValue.parse(input).get.value).right.get.value + AstUtils.parseUint32(fastparse.parse(input, ProtoAsciiParser.PrimitiveValue(_)).get.value).right.get.value def parseUInt64[T](input: String): Long = - AstUtils.parseUint64(ProtoAsciiParser.PrimitiveValue.parse(input).get.value).right.get.value + AstUtils.parseUint64(fastparse.parse(input, ProtoAsciiParser.PrimitiveValue(_)).get.value).right.get.value "testParseInteger" should "pass" in { 0 must be(parseInt32( "0")) From 745cb66a44f5062ca9d045827bfdb34bda972d3a Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Thu, 31 Jan 2019 19:36:02 +0100 Subject: [PATCH 4/6] Skip 2.10 --- .travis.yml | 8 -------- build.sbt | 4 +--- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1163f1843..96d897a26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ stages: if: (branch = master AND type = push AND repo = "scalapb/ScalaPB") OR (tag IS present) scala: -- 2.10.7 - 2.11.12 - 2.12.8 @@ -19,13 +18,6 @@ env: - TEST_SCRIPT=mima.sh - TEST_SCRIPT=proptest.sh -matrix: - exclude: - - scala: 2.10.7 - env: TEST_SCRIPT=e2e.sh E2E_SHADED=0 - - scala: 2.10.7 - env: TEST_SCRIPT=e2e.sh E2E_SHADED=1 - jobs: include: #- env: SCALA_NATIVE diff --git a/build.sbt b/build.sbt index 776b7a912..c48eccf69 100644 --- a/build.sbt +++ b/build.sbt @@ -1,8 +1,6 @@ import ReleaseTransformations._ import sbtcrossproject.CrossPlugin.autoImport.{CrossType, crossProject} -val Scala210 = "2.10.7" - val Scala211 = "2.11.12" val Scala212 = "2.12.8" @@ -18,7 +16,7 @@ val grpcVersion = "1.18.0" scalaVersion in ThisBuild := Scala212 -crossScalaVersions in ThisBuild := Seq(Scala210, Scala211, Scala212) +crossScalaVersions in ThisBuild := Seq(Scala211, Scala212) scalacOptions in ThisBuild ++= { CrossVersion.partialVersion(scalaVersion.value) match { From 4b8138d4536833f35dcc1b8510686263b493dc83 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Thu, 31 Jan 2019 19:36:52 +0100 Subject: [PATCH 5/6] Fix e2e test --- e2e/src/test/scala/scalapb/TextFormatSpec.scala | 4 ++-- .../shared/src/main/scala/scalapb/TextFormat.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/src/test/scala/scalapb/TextFormatSpec.scala b/e2e/src/test/scala/scalapb/TextFormatSpec.scala index 7665fbe1b..c2f3aa5c7 100644 --- a/e2e/src/test/scala/scalapb/TextFormatSpec.scala +++ b/e2e/src/test/scala/scalapb/TextFormatSpec.scala @@ -250,9 +250,9 @@ class TextFormatSpec extends FlatSpec with GeneratorDrivenPropertyChecks with Mu "optional_string: \"ueoauaoe\noptional_int32: 123" must failParsingWith( EXPECTED_FIELD) "[nosuchext]: 123" must failParsingWith( - "expected identifier") + "Expected Message") "[protobuf_unittest.optional_int32_extension]: 123" must failParsingWith( - "expected identifier") + "Expected Message") "nosuchfield: 123" must failParsingWith( "Unknown field name 'nosuchfield' (line 1, column 1)") "optional_nested_enum: NO_SUCH_VALUE" must failParsingWith( diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala b/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala index 09e297877..3332c9406 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/TextFormat.scala @@ -26,7 +26,7 @@ object TextFormat { TextFormatError(s"${a.error} (${indexToLineCol(s, a.index)})") } case f: Parsed.Failure => - Left(TextFormatError(f.longMsg)) + Left(TextFormatError(f.trace(true).longMsg)) } } From 56076536c263f5fe14330a8fe313cfcdbe1951d5 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Thu, 31 Jan 2019 20:35:54 +0100 Subject: [PATCH 6/6] Formatting --- .../scala/scalapb/textformat/Basics.scala | 33 ++++++++++--------- .../scalapb/textformat/ProtoAsciiParser.scala | 25 +++++++------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala index e90586a81..9dd97a223 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/Basics.scala @@ -32,7 +32,7 @@ object Basics extends ParserCompat { def identifier[_: P] = P(CharIn("a-z", "A-Z", "0-9", "_").rep(1).!).opaque("identifier") - def literal[_: P] = P(CharIn("a-z", "A-Z", "0-9", "_\\-.").rep(1).!).opaque("literal") + def literal[_: P] = P(CharIn("a-z", "A-Z", "0-9", "_\\-.").rep(1).!).opaque("literal") def digits[_: P] = P(CharsWhile(Digits)) def hexDigits[_: P] = P(CharsWhile(HexDigits)) @@ -48,25 +48,28 @@ object Basics extends ParserCompat { def integral[_: P]: P[BigInt] = P(hexIntegral | octIntegral | decIntegral) - def bigInt[_: P]: P[BigInt] = P(CharIn("+\\-").!.? ~ integral).map({ - case (Some("-"), number) => -number - case (_, number) => number - }) + def bigInt[_: P]: P[BigInt] = + P(CharIn("+\\-").!.? ~ integral).map({ + case (Some("-"), number) => -number + case (_, number) => number + }) def strNoDQChars[_: P] = P(CharsWhile(!"\"\n\\".contains(_: Char))) - def strNoQChars [_: P] = P(CharsWhile(!"'\n\\".contains(_: Char))) - def escape [_: P] = P("\\" ~ AnyChar) - def singleBytesLiteral[_: P] = P( - "\"" ~/ (strNoDQChars | escape).rep.! ~ "\"" | - "'" ~/ (strNoQChars | escape).rep.! ~ "'" - ).opaque("string") + def strNoQChars[_: P] = P(CharsWhile(!"'\n\\".contains(_: Char))) + def escape[_: P] = P("\\" ~ AnyChar) + def singleBytesLiteral[_: P] = + P( + "\"" ~/ (strNoDQChars | escape).rep.! ~ "\"" | + "'" ~/ (strNoQChars | escape).rep.! ~ "'" + ).opaque("string") def bytesLiteral[_: P] = P(singleBytesLiteral.rep(1, whiteSpace)).map(_.mkString) - def boolean[_: P]: P[Boolean] = P( - ("true" | "t" | "1").map(_ => true) | - ("false" | "f" | "0").map(_ => false) - ).opaque("'true' or 'false'") + def boolean[_: P]: P[Boolean] = + P( + ("true" | "t" | "1").map(_ => true) | + ("false" | "f" | "0").map(_ => false) + ).opaque("'true' or 'false'") def ws[_: P](s: String): P[Unit] = P(s ~ &(whiteSpace)) } diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala index 3c7d4e458..d18312ea5 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/textformat/ProtoAsciiParser.scala @@ -13,10 +13,11 @@ private[scalapb] object ProtoAsciiParser { (Index ~ Basics.literal).map(TLiteral.tupled) ) - def MessageValue[_: P]: P[TMessage] = P( - Index ~ "{" ~/ KeyValue.rep ~/ "}" | - Index ~ "<" ~/ KeyValue.rep ~/ ">" - ).map(TMessage.tupled) + def MessageValue[_: P]: P[TMessage] = + P( + Index ~ "{" ~/ KeyValue.rep ~/ "}" | + Index ~ "<" ~/ KeyValue.rep ~/ ">" + ).map(TMessage.tupled) def ValueArray[_: P]: P[TValue] = P((Index ~ "[" ~/ (PrimitiveValue | MessageValue).rep(0, ",") ~/ "]")).map(TArray.tupled) @@ -24,14 +25,16 @@ private[scalapb] object ProtoAsciiParser { def MessageArray[_: P]: P[TValue] = P((Index ~ "[" ~/ MessageValue.rep(0, ",") ~/ "]")).map(TArray.tupled) - def Value[_: P]: P[TValue] = P( - MessageValue | MessageArray | - ":" ~/ (MessageValue | ValueArray | PrimitiveValue) - ).opaque("':', '{', '<', or '['") + def Value[_: P]: P[TValue] = + P( + MessageValue | MessageArray | + ":" ~/ (MessageValue | ValueArray | PrimitiveValue) + ).opaque("':', '{', '<', or '['") - def KeyValue[_: P]: P[TField] = P( - Index ~ Basics.identifier ~/ Value - ).map(TField.tupled) + def KeyValue[_: P]: P[TField] = + P( + Index ~ Basics.identifier ~/ Value + ).map(TField.tupled) def Message[_: P]: P[TMessage] = P(Index ~ KeyValue.rep ~ End).map(TMessage.tupled) }