From e1f36840d451811d8c9a85d1fdb4459fea6ee2c7 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Wed, 17 Jan 2024 18:58:07 +1100 Subject: [PATCH] Cross compile inline statements correctly --- .scalafmt.conf | 1 + .../inline-parser-states.excludes | 7 +++ .../main/scala-2/jawn/AsyncParserStates.scala | 47 +++++++++++++++++++ .../src/main/scala-2/jawn/ParserStates.scala | 32 +++++++++++++ .../main/scala-3/jawn/AsyncParserStates.scala | 47 +++++++++++++++++++ .../src/main/scala-3/jawn/ParserStates.scala | 32 +++++++++++++ .../src/main/scala/jawn/AsyncParser.scala | 25 +--------- .../shared/src/main/scala/jawn/Parser.scala | 16 +------ 8 files changed, 169 insertions(+), 38 deletions(-) create mode 100644 parser/jvm/src/main/mima-filters/1.5.1.backwards.excludes/inline-parser-states.excludes create mode 100644 parser/shared/src/main/scala-2/jawn/AsyncParserStates.scala create mode 100644 parser/shared/src/main/scala-2/jawn/ParserStates.scala create mode 100644 parser/shared/src/main/scala-3/jawn/AsyncParserStates.scala create mode 100644 parser/shared/src/main/scala-3/jawn/ParserStates.scala diff --git a/.scalafmt.conf b/.scalafmt.conf index 0efee40c..ed3f5b60 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -9,3 +9,4 @@ danglingParentheses.preset = true rewrite.rules = [AvoidInfix, SortImports, RedundantBraces, RedundantParens, SortModifiers] docstrings.style = Asterisk align.preset = none +project.layout = StandardConvention diff --git a/parser/jvm/src/main/mima-filters/1.5.1.backwards.excludes/inline-parser-states.excludes b/parser/jvm/src/main/mima-filters/1.5.1.backwards.excludes/inline-parser-states.excludes new file mode 100644 index 00000000..879a39a1 --- /dev/null +++ b/parser/jvm/src/main/mima-filters/1.5.1.backwards.excludes/inline-parser-states.excludes @@ -0,0 +1,7 @@ +ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.jawn.Parser.ARRBEG") +ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.jawn.Parser.ARREND") +ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.jawn.Parser.DATA") +ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.jawn.Parser.KEY") +ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.jawn.Parser.OBJBEG") +ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.jawn.Parser.OBJEND") +ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.jawn.Parser.SEP") diff --git a/parser/shared/src/main/scala-2/jawn/AsyncParserStates.scala b/parser/shared/src/main/scala-2/jawn/AsyncParserStates.scala new file mode 100644 index 00000000..7ad443ea --- /dev/null +++ b/parser/shared/src/main/scala-2/jawn/AsyncParserStates.scala @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012 Typelevel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.typelevel.jawn + +private[jawn] trait AsyncParserStates { + + /** + * Explanation of the new synthetic states. The parser machinery uses positive integers for states while parsing json + * values. We use these negative states to keep track of the async parser's status between json values. + * + * ASYNC_PRESTART: We haven't seen any non-whitespace yet. We could be parsing an array, or not. We are waiting for + * valid JSON. + * + * ASYNC_START: We've seen an array and have begun unwrapping it. We could see a ] if the array is empty, or valid + * JSON. + * + * ASYNC_END: We've parsed an array and seen the final ]. At this point we should only see whitespace or an EOF. + * + * ASYNC_POSTVAL: We just parsed a value from inside the array. We expect to see whitespace, a comma, or a ]. + * + * ASYNC_PREVAL: We are in an array and we just saw a comma. We expect to see whitespace or a JSON value. + */ + @inline final def ASYNC_PRESTART = -5 + @inline final def ASYNC_START = -4 + @inline final def ASYNC_END = -3 + @inline final def ASYNC_POSTVAL = -2 + @inline final def ASYNC_PREVAL = -1 +} diff --git a/parser/shared/src/main/scala-2/jawn/ParserStates.scala b/parser/shared/src/main/scala-2/jawn/ParserStates.scala new file mode 100644 index 00000000..db2f3242 --- /dev/null +++ b/parser/shared/src/main/scala-2/jawn/ParserStates.scala @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Typelevel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.typelevel.jawn + +private[jawn] trait ParserStates { + @inline final val ARRBEG = 6 + @inline final val OBJBEG = 7 + @inline final val DATA = 1 + @inline final val KEY = 2 + @inline final val SEP = 3 + @inline final val ARREND = 4 + @inline final val OBJEND = 5 +} diff --git a/parser/shared/src/main/scala-3/jawn/AsyncParserStates.scala b/parser/shared/src/main/scala-3/jawn/AsyncParserStates.scala new file mode 100644 index 00000000..855f60bd --- /dev/null +++ b/parser/shared/src/main/scala-3/jawn/AsyncParserStates.scala @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012 Typelevel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.typelevel.jawn + +private[jawn] trait AsyncParserStates { + + /** + * Explanation of the new synthetic states. The parser machinery uses positive integers for states while parsing json + * values. We use these negative states to keep track of the async parser's status between json values. + * + * ASYNC_PRESTART: We haven't seen any non-whitespace yet. We could be parsing an array, or not. We are waiting for + * valid JSON. + * + * ASYNC_START: We've seen an array and have begun unwrapping it. We could see a ] if the array is empty, or valid + * JSON. + * + * ASYNC_END: We've parsed an array and seen the final ]. At this point we should only see whitespace or an EOF. + * + * ASYNC_POSTVAL: We just parsed a value from inside the array. We expect to see whitespace, a comma, or a ]. + * + * ASYNC_PREVAL: We are in an array and we just saw a comma. We expect to see whitespace or a JSON value. + */ + final inline def ASYNC_PRESTART = -5 + final inline def ASYNC_START = -4 + final inline def ASYNC_END = -3 + final inline def ASYNC_POSTVAL = -2 + final inline def ASYNC_PREVAL = -1 +} diff --git a/parser/shared/src/main/scala-3/jawn/ParserStates.scala b/parser/shared/src/main/scala-3/jawn/ParserStates.scala new file mode 100644 index 00000000..7bdbc8f7 --- /dev/null +++ b/parser/shared/src/main/scala-3/jawn/ParserStates.scala @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Typelevel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.typelevel.jawn + +private[jawn] trait ParserStates { + final inline val ARRBEG = 6 + final inline val OBJBEG = 7 + final inline val DATA = 1 + final inline val KEY = 2 + final inline val SEP = 3 + final inline val ARREND = 4 + final inline val OBJEND = 5 +} diff --git a/parser/shared/src/main/scala/jawn/AsyncParser.scala b/parser/shared/src/main/scala/jawn/AsyncParser.scala index e2323128..a0b3bcdd 100644 --- a/parser/shared/src/main/scala/jawn/AsyncParser.scala +++ b/parser/shared/src/main/scala/jawn/AsyncParser.scala @@ -106,7 +106,8 @@ final class AsyncParser[J] protected[jawn] ( protected[jawn] var done: Boolean, protected[jawn] var streamMode: Int, protected[jawn] val multiValue: Boolean -) extends ByteBasedParser[J] { +) extends ByteBasedParser[J] + with AsyncParserStates { protected[jawn] def this(state: Int, curr: Int, @@ -180,28 +181,6 @@ final class AsyncParser[J] protected[jawn] ( allocated = newsize } - /** - * Explanation of the new synthetic states. The parser machinery uses positive integers for states while parsing json - * values. We use these negative states to keep track of the async parser's status between json values. - * - * ASYNC_PRESTART: We haven't seen any non-whitespace yet. We could be parsing an array, or not. We are waiting for - * valid JSON. - * - * ASYNC_START: We've seen an array and have begun unwrapping it. We could see a ] if the array is empty, or valid - * JSON. - * - * ASYNC_END: We've parsed an array and seen the final ]. At this point we should only see whitespace or an EOF. - * - * ASYNC_POSTVAL: We just parsed a value from inside the array. We expect to see whitespace, a comma, or a ]. - * - * ASYNC_PREVAL: We are in an array and we just saw a comma. We expect to see whitespace or a JSON value. - */ - @inline final private[this] def ASYNC_PRESTART = -5 - @inline final private[this] def ASYNC_START = -4 - @inline final private[this] def ASYNC_END = -3 - @inline final private[this] def ASYNC_POSTVAL = -2 - @inline final private[this] def ASYNC_PREVAL = -1 - protected[jawn] def churn()(implicit facade: Facade[J]): Either[ParseException, collection.Seq[J]] = { // accumulates json values diff --git a/parser/shared/src/main/scala/jawn/Parser.scala b/parser/shared/src/main/scala/jawn/Parser.scala index 5ef5d0ba..e83f13a9 100644 --- a/parser/shared/src/main/scala/jawn/Parser.scala +++ b/parser/shared/src/main/scala/jawn/Parser.scala @@ -488,7 +488,7 @@ abstract class Parser[J] { } } -object Parser extends ParserCompanionPlatform { +object Parser extends ParserCompanionPlatform with ParserStates { def parseUnsafe[J](s: String)(implicit facade: Facade[J]): J = new StringParser(s).parse() @@ -507,20 +507,6 @@ object Parser extends ParserCompanionPlatform { def async[J](mode: AsyncParser.Mode): AsyncParser[J] = AsyncParser[J](mode) - /** - * Private variables. - */ - /** - * Valid parser states. - */ - @inline final private[jawn] val ARRBEG = 6 - @inline final private[jawn] val OBJBEG = 7 - @inline final private[jawn] val DATA = 1 - @inline final private[jawn] val KEY = 2 - @inline final private[jawn] val SEP = 3 - @inline final private[jawn] val ARREND = 4 - @inline final private[jawn] val OBJEND = 5 - final private[jawn] val HexChars: Array[Int] = { val arr = Array.fill(128)(-1) var i = 0