From f4256780617fcc231a1a1403006c9c7b6c175aaf Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Fri, 18 Apr 2025 15:06:45 +0200 Subject: [PATCH 01/13] fix compilation errors with -Xsource:3 --- .gitignore | 2 +- .../main/scala/sjsonnet/ParserBenchmark.scala | 2 +- .../scala/sjsonnet/ProfilingEvaluator.scala | 4 +- build.sbt | 21 ++- build.sc | 4 +- project/build.properties | 2 +- project/plugins.sbt | 3 +- .../src/sjsonnet/SjsonnetServerMain.scala | 7 +- .../sjsonnet/CachedResolvedFile.scala | 10 +- sjsonnet/src-jvm-native/sjsonnet/OsPath.scala | 2 +- .../sjsonnet/SjsonnetMain.scala | 10 +- sjsonnet/src-jvm/sjsonnet/Platform.scala | 6 +- sjsonnet/src/sjsonnet/BaseCharRenderer.scala | 6 +- sjsonnet/src/sjsonnet/BaseRenderer.scala | 31 ++-- sjsonnet/src/sjsonnet/DecimalFormat.scala | 4 +- sjsonnet/src/sjsonnet/Error.scala | 12 +- sjsonnet/src/sjsonnet/Evaluator.scala | 33 ++-- sjsonnet/src/sjsonnet/Expr.scala | 12 +- sjsonnet/src/sjsonnet/ExprTransform.scala | 26 +-- sjsonnet/src/sjsonnet/Format.scala | 38 ++--- sjsonnet/src/sjsonnet/Importer.scala | 10 +- sjsonnet/src/sjsonnet/Materializer.scala | 2 +- sjsonnet/src/sjsonnet/Parser.scala | 149 +++++++++--------- .../src/sjsonnet/PrettyYamlRenderer.scala | 73 +++++---- sjsonnet/src/sjsonnet/ReadWriter.scala | 40 ++--- sjsonnet/src/sjsonnet/Renderer.scala | 38 ++--- .../src/sjsonnet/ScopedExprTransform.scala | 26 +-- sjsonnet/src/sjsonnet/StaticOptimizer.scala | 8 +- sjsonnet/src/sjsonnet/Std.scala | 18 +-- sjsonnet/src/sjsonnet/TomlRenderer.scala | 8 +- sjsonnet/src/sjsonnet/Val.scala | 40 ++--- sjsonnet/src/sjsonnet/ValScope.scala | 15 +- sjsonnet/src/sjsonnet/ValVisitor.scala | 6 +- sjsonnet/src/sjsonnet/YamlRenderer.scala | 10 +- sjsonnet/test/src-jvm-native/ErrorTests.scala | 9 +- .../PrettyYamlRendererTests.scala | 8 +- .../BufferedRandomAccessFileTests.scala | 8 +- .../src-jvm/sjsonnet/ErrorTestsJvmOnly.scala | 9 +- .../test/src-jvm/sjsonnet/FileTests.scala | 13 +- .../test/src-jvm/sjsonnet/MainTests.scala | 4 +- .../test/src-jvm/sjsonnet/StdGzipTests.scala | 2 +- .../test/src-jvm/sjsonnet/StdMd5Tests.scala | 2 +- .../test/src-jvm/sjsonnet/StdXzTests.scala | 2 +- .../test/src-jvm/sjsonnet/XxHash64Tests.scala | 4 +- .../src/sjsonnet/DecimalFormatTests.scala | 4 +- .../test/src/sjsonnet/EvaluatorTests.scala | 2 +- sjsonnet/test/src/sjsonnet/FormatTests.scala | 8 +- .../src/sjsonnet/NonBooleanExprTests.scala | 2 +- sjsonnet/test/src/sjsonnet/OldRenderer.scala | 22 +-- .../test/src/sjsonnet/OldYamlRenderer.scala | 16 +- sjsonnet/test/src/sjsonnet/ParserTests.scala | 6 +- .../src/sjsonnet/PreserveOrderTests.scala | 2 +- .../test/src/sjsonnet/RendererTests.scala | 2 +- .../src/sjsonnet/Std0150FunctionsTests.scala | 2 +- .../test/src/sjsonnet/StdFlatMapTests.scala | 2 +- .../src/sjsonnet/StdMergePatchTests.scala | 2 +- .../src/sjsonnet/StdStripCharsTests.scala | 2 +- .../test/src/sjsonnet/StdWithKeyFTests.scala | 2 +- .../test/src/sjsonnet/YamlRendererTests.scala | 2 +- 59 files changed, 420 insertions(+), 395 deletions(-) diff --git a/.gitignore b/.gitignore index 00f85e7e..11770223 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ out/ .bloop /project/.bloop /project/project/ -/project/metals.sbt \ No newline at end of file +/project/metals.sbt diff --git a/bench/src/main/scala/sjsonnet/ParserBenchmark.scala b/bench/src/main/scala/sjsonnet/ParserBenchmark.scala index 6100534d..7af7dbe5 100644 --- a/bench/src/main/scala/sjsonnet/ParserBenchmark.scala +++ b/bench/src/main/scala/sjsonnet/ParserBenchmark.scala @@ -28,7 +28,7 @@ class ParserBenchmark { def main(bh: Blackhole): Unit = { bh.consume(allFiles.foreach { case (p, s) => val res = fastparse.parse(s, new Parser(p, true, HashMap.empty, HashMap.empty).document(_)) - bh.consume(res.asInstanceOf[Success[_]]) + bh.consume(res.asInstanceOf[Success[?]]) }) } } diff --git a/bench/src/main/scala/sjsonnet/ProfilingEvaluator.scala b/bench/src/main/scala/sjsonnet/ProfilingEvaluator.scala index bbcab661..550937e0 100644 --- a/bench/src/main/scala/sjsonnet/ProfilingEvaluator.scala +++ b/bench/src/main/scala/sjsonnet/ProfilingEvaluator.scala @@ -96,8 +96,8 @@ class ProfilingEvaluator(resolver: CachedResolver, case a: Array[Expr.Bind] => a.iterator.flatMap(getChildren).toSeq case a: Array[Expr.Member.Field] => a.iterator.flatMap(getChildren).toSeq case a: Array[Expr.Member.AssertStmt] => a.iterator.flatMap(getChildren).toSeq - case s: Seq[_] => s.collect { case e: Expr => e } - case s: Some[_] => s.collect { case e: Expr => e } + case s: Seq[?] => s.collect { case e: Expr => e } + case s: Some[?] => s.collect { case e: Expr => e } case _ => Nil }.filter(_ != null).toSeq case _ => Nil diff --git a/build.sbt b/build.sbt index 389f51b4..79b75cc2 100644 --- a/build.sbt +++ b/build.sbt @@ -1,12 +1,21 @@ val sjsonnetVersion = "0.4.15.1" -scalaVersion in Global := "2.13.16" +val scala213 = "2.13.16" +val scala3 = "3.6.4" cancelable in Global := true +val scala3Options = Seq() +val scala2Options = Seq("-opt:l:inline", "-opt-inline-from:sjsonnet.*,sjsonnet.**", "-Xsource:3") + lazy val main = (project in file("sjsonnet")) .settings( - Compile / scalacOptions ++= Seq("-opt:l:inline", "-opt-inline-from:sjsonnet.*,sjsonnet.**"), + scalaVersion := scala3, + crossScalaVersions := Seq(scala213, scala3), + scalacOptions ++= {CrossVersion.partialVersion(scalaVersion.value) match { + case Some((3, _)) => scala3Options + case _ => scala2Options + }}, Test / fork := true, Test / javaOptions += "-Xss100m", Test / baseDirectory := (ThisBuild / baseDirectory).value, @@ -57,5 +66,11 @@ lazy val bench = (project in file("bench")) .dependsOn(main % "compile->test") .enablePlugins(JmhPlugin) .settings( - run / fork := true, + run / fork := true ) + + lazy val root = (project in file(".")) + .aggregate(main) + .settings( + publishArtifact := false + ) \ No newline at end of file diff --git a/build.sc b/build.sc index bac052a5..264787f9 100644 --- a/build.sc +++ b/build.sc @@ -5,7 +5,7 @@ import java.util.Base64 val sjsonnetVersion = "0.4.15.1" -val scalaVersions = Seq("2.12.20", "2.13.16") +val scalaVersions = Seq("2.12.20", "2.13.16", "3.6.4") trait SjsonnetCrossModule extends CrossScalaModule with PublishModule { def crossValue: String @@ -153,7 +153,7 @@ object sjsonnet extends Module { ivy"org.yaml:snakeyaml::2.0", ivy"com.google.re2j:re2j:1.8", ) - def scalacOptions = Seq("-opt:l:inline", "-opt-inline-from:sjsonnet.*,sjsonnet.**") + def scalacOptions = Seq("-opt:l:inline", "-opt-inline-from:sjsonnet.*,sjsonnet.**", "-Xsource:3") object test extends ScalaTests with CrossTests { def forkArgs = Seq("-Xss100m") diff --git a/project/build.properties b/project/build.properties index 081fdbbc..cc68b53f 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.0 +sbt.version=1.10.11 diff --git a/project/plugins.sbt b/project/plugins.sbt index b0a3453b..42535658 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1 @@ -//addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.7") -addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.3") +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") \ No newline at end of file diff --git a/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala b/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala index e6c41f6f..539208d0 100644 --- a/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala +++ b/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala @@ -151,8 +151,9 @@ class Server[T](lockBase: String, @volatile var done = false @volatile var idle = false - val t = new Thread(() => - try { + val t = new Thread(new Runnable{ + override def run(): Unit = { + try { val (result, newStateCache) = sm.main0( args, sm.stateCache, @@ -173,6 +174,8 @@ class Server[T](lockBase: String, } finally{ done = true idle = true + } + } }, "SjsonnetServerActionRunner" ) diff --git a/sjsonnet/src-jvm-native/sjsonnet/CachedResolvedFile.scala b/sjsonnet/src-jvm-native/sjsonnet/CachedResolvedFile.scala index 0fddc037..20be704c 100644 --- a/sjsonnet/src-jvm-native/sjsonnet/CachedResolvedFile.scala +++ b/sjsonnet/src-jvm-native/sjsonnet/CachedResolvedFile.scala @@ -26,7 +26,7 @@ class CachedResolvedFile(val resolvedImportPath: OsPath, memoryLimitBytes: Long, // Assert that the file is less than limit assert(jFile.length() <= memoryLimitBytes, s"Resolved import path $resolvedImportPath is too large: ${jFile.length()} bytes > ${memoryLimitBytes} bytes") - private[this] val resolvedImportContent: ResolvedFile = { + private val resolvedImportContent: ResolvedFile = { // TODO: Support caching binary data if (jFile.length() > cacheThresholdBytes) { // If the file is too large, then we will just read it from disk @@ -38,11 +38,11 @@ class CachedResolvedFile(val resolvedImportPath: OsPath, memoryLimitBytes: Long, } } - private[this] def readString(jFile: File): String = { + private def readString(jFile: File): String = { new String(Files.readAllBytes(jFile.toPath), StandardCharsets.UTF_8); } - private[this] def readRawBytes(jFile: File): Array[Byte] = Files.readAllBytes(jFile.toPath) + private def readRawBytes(jFile: File): Array[Byte] = Files.readAllBytes(jFile.toPath) /** * A method that will return a reader for the resolved import. If the import is too large, then this will return @@ -67,12 +67,12 @@ class CachedResolvedFile(val resolvedImportPath: OsPath, memoryLimitBytes: Long, } - override lazy val contentHash: String = { + override def contentHash(): String = { if (resolvedImportContent == null) { // If the file is too large, then we will just read it from disk Platform.hashFile(jFile) } else { - resolvedImportContent.contentHash + resolvedImportContent.contentHash() } } diff --git a/sjsonnet/src-jvm-native/sjsonnet/OsPath.scala b/sjsonnet/src-jvm-native/sjsonnet/OsPath.scala index 91827ef0..39795e84 100644 --- a/sjsonnet/src-jvm-native/sjsonnet/OsPath.scala +++ b/sjsonnet/src-jvm-native/sjsonnet/OsPath.scala @@ -29,6 +29,6 @@ case class OsPath(p: os.Path) extends Path{ ":" + Util.prettyIndex(lineStarts, offset) } - p.relativeTo(os.pwd) + offsetStr + p.relativeTo(os.pwd).toString + offsetStr } } \ No newline at end of file diff --git a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala index 2c982026..c45dae4e 100644 --- a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala +++ b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala @@ -107,7 +107,7 @@ object SjsonnetMain { private def writeFile(config: Config, f: os.Path, contents: String): Either[String, Unit] = handleWriteFile(os.write.over(f, contents, createFolders = config.createDirs.value)) - private def writeToFile(config: Config, wd: os.Path)(materialize: Writer => Either[String, _]): Either[String, String] = { + private def writeToFile(config: Config, wd: os.Path)(materialize: Writer => Either[String, ?]): Either[String, String] = { config.outputFile match{ case None => val sw = new StringWriter @@ -199,12 +199,12 @@ object SjsonnetMain { importer = importer match{ case Some(i) => new Importer { def resolve(docBase: Path, importName: String): Option[Path] = - i(docBase, importName).map(OsPath) + i(docBase, importName).map(OsPath.apply) def read(path: Path, binaryData: Boolean): Option[ResolvedFile] = { readPath(path, binaryData) } } - case None => resolveImport(config.jpaths.map(os.Path(_, wd)).map(OsPath), allowedInputs) + case None => resolveImport(config.jpaths.map(os.Path(_, wd)).map(OsPath.apply), allowedInputs) }, parseCache, settings = new Settings( @@ -242,7 +242,7 @@ object SjsonnetMain { Right(writer.toString) } } - relPath = os.FilePath(multiPath) / os.RelPath(f) + relPath = (os.FilePath(multiPath) / os.RelPath(f)).asInstanceOf[os.FilePath] _ <- writeFile(config, relPath.resolveFrom(wd), rendered) } yield relPath } @@ -295,7 +295,7 @@ object SjsonnetMain { * of caching on top of the underlying file system. Small files are read into memory, while large * files are read from disk. */ - private[this] def readPath(path: Path, binaryData: Boolean): Option[ResolvedFile] = { + private def readPath(path: Path, binaryData: Boolean): Option[ResolvedFile] = { val osPath = path.asInstanceOf[OsPath].p if (os.exists(osPath) && os.isFile(osPath)) { Some(new CachedResolvedFile(path.asInstanceOf[OsPath], memoryLimitBytes = Int.MaxValue.toLong, binaryData = binaryData)) diff --git a/sjsonnet/src-jvm/sjsonnet/Platform.scala b/sjsonnet/src-jvm/sjsonnet/Platform.scala index 45a9946c..8a40fc2a 100644 --- a/sjsonnet/src-jvm/sjsonnet/Platform.scala +++ b/sjsonnet/src-jvm/sjsonnet/Platform.scala @@ -59,8 +59,8 @@ object Platform { yaml.size match { case 0 => "{}" case 1 => yaml.head match { - case m: java.util.Map[_, _] => new JSONObject(m).toString() - case l: java.util.List[_] => new JSONArray(l).toString() + case m: java.util.Map[?, ?] => new JSONObject(m).toString() + case l: java.util.List[?] => new JSONArray(l).toString() case _ => new JSONArray(yaml.asJava).get(0).toString } case _ => new JSONArray(yaml.asJava).toString() @@ -89,7 +89,7 @@ object Platform { // Same as go-jsonnet https://github.com/google/go-jsonnet/blob/2b4d7535f540f128e38830492e509a550eb86d57/builtins.go#L959 def sha3(s: String): String = computeHash("SHA3-512", s) - private[this] val xxHashFactory = XXHashFactory.fastestInstance() + private val xxHashFactory = XXHashFactory.fastestInstance() def hashFile(file: File): String = { val buffer = new Array[Byte](8192) diff --git a/sjsonnet/src/sjsonnet/BaseCharRenderer.scala b/sjsonnet/src/sjsonnet/BaseCharRenderer.scala index 9e9aedf3..d38a9ab0 100644 --- a/sjsonnet/src/sjsonnet/BaseCharRenderer.scala +++ b/sjsonnet/src/sjsonnet/BaseCharRenderer.scala @@ -15,15 +15,15 @@ class BaseCharRenderer[T <: upickle.core.CharOps.Output] override def visitJsonableObject(length: Int, index: Int): ObjVisitor[T,T] = visitObject(length, index) - protected[this] val elemBuilder = new upickle.core.CharBuilder + protected val elemBuilder = new upickle.core.CharBuilder def flushCharBuilder(): Unit = { elemBuilder.writeOutToIfLongerThan(out, if (depth == 0) 0 else 1000) } - protected[this] var depth: Int = 0 + protected var depth: Int = 0 - protected[this] var commaBuffered = false + protected var commaBuffered = false def flushBuffer(): Unit = { if (commaBuffered) { diff --git a/sjsonnet/src/sjsonnet/BaseRenderer.scala b/sjsonnet/src/sjsonnet/BaseRenderer.scala index 99428bf8..7109097f 100644 --- a/sjsonnet/src/sjsonnet/BaseRenderer.scala +++ b/sjsonnet/src/sjsonnet/BaseRenderer.scala @@ -19,24 +19,27 @@ class BaseRenderer[T <: java.io.Writer] override def visitJsonableObject(length: Int, index: Int): ObjVisitor[T,T] = visitObject(length, index) var depth: Int = 0 - val colonSnippet = if (indent == -1) ":" else ": " + val colonSnippet: String = if (indent == -1) ":" else ": " var commaBuffered = false - def flushBuffer() = { + def flushBuffer(): Unit = { if (commaBuffered) { commaBuffered = false out.append(',') renderIndent() } } - def visitArray(length: Int, index: Int) = new ArrVisitor[T, T] { + + override def visitJsonableObject(length: Int, index: Int): ObjVisitor[T,T] = visitObject(length, index) + + def visitArray(length: Int, index: Int): upickle.core.ArrVisitor[T,T]{def subVisitor: sjsonnet.BaseRenderer[T]} = new ArrVisitor[T, T] { flushBuffer() out.append('[') depth += 1 renderIndent() - def subVisitor = BaseRenderer.this + def subVisitor: sjsonnet.BaseRenderer[T] = BaseRenderer.this def visitValue(v: T, index: Int): Unit = { flushBuffer() commaBuffered = true @@ -50,13 +53,13 @@ class BaseRenderer[T <: java.io.Writer] } } - def visitObject(length: Int, index: Int) = new ObjVisitor[T, T] { + def visitObject(length: Int, index: Int): ObjVisitor[T,T] = new ObjVisitor[T, T] { flushBuffer() out.append('{') depth += 1 renderIndent() - def subVisitor = BaseRenderer.this - def visitKey(index: Int) = BaseRenderer.this + def subVisitor: sjsonnet.BaseRenderer[T] = BaseRenderer.this + def visitKey(index: Int): sjsonnet.BaseRenderer[T]= BaseRenderer.this def visitKeyValue(s: Any): Unit = out.append(colonSnippet) def visitValue(v: T, index: Int): Unit = { commaBuffered = true @@ -70,31 +73,31 @@ class BaseRenderer[T <: java.io.Writer] } } - def visitNull(index: Int) = { + def visitNull(index: Int): T = { flushBuffer() out.append("null") out } - def visitFalse(index: Int) = { + def visitFalse(index: Int): T = { flushBuffer() out.append("false") out } - def visitTrue(index: Int) = { + def visitTrue(index: Int): T = { flushBuffer() out.append("true") out } - def visitFloat64StringParts(s: CharSequence, decIndex: Int, expIndex: Int, index: Int) = { + def visitFloat64StringParts(s: CharSequence, decIndex: Int, expIndex: Int, index: Int): T = { flushBuffer() out.append(s) out } - override def visitFloat64(d: Double, index: Int) = { + override def visitFloat64(d: Double, index: Int): T = { d match{ case Double.PositiveInfinity => visitString("Infinity", -1) case Double.NegativeInfinity => visitString("-Infinity", -1) @@ -109,7 +112,7 @@ class BaseRenderer[T <: java.io.Writer] out } - def visitString(s: CharSequence, index: Int) = { + def visitString(s: CharSequence, index: Int): T = { flushBuffer() if (s == null) out.append("null") else BaseRenderer.escape(out, s, escapeUnicode) @@ -117,7 +120,7 @@ class BaseRenderer[T <: java.io.Writer] out } - final def renderIndent() = { + final def renderIndent(): Unit = { if (indent == -1) () else { out.append('\n') diff --git a/sjsonnet/src/sjsonnet/DecimalFormat.scala b/sjsonnet/src/sjsonnet/DecimalFormat.scala index 0e0566d3..77f22ac1 100644 --- a/sjsonnet/src/sjsonnet/DecimalFormat.scala +++ b/sjsonnet/src/sjsonnet/DecimalFormat.scala @@ -8,7 +8,7 @@ package sjsonnet */ object DecimalFormat { - def trailingZeroes(n: Long) = { + def trailingZeroes(n: Long): Int = { var count = 0 var current = n var done = false @@ -31,7 +31,7 @@ object DecimalFormat { val n = (n0 / Math.pow(10, trailingZeroes(n0))).toInt assert(n == math.abs(n)) val nWidth = if (n == 0) 1 else Math.log10(n).toInt + 1 - (n + "0" * (minWidth - nWidth)).take(maxWidth) + ("" + n + "0" * (minWidth - nWidth)).take(maxWidth) } } def format(fracLengthOpt: Option[(Int, Int)], expLengthOpt: Option[Int], number: Double): String = { diff --git a/sjsonnet/src/sjsonnet/Error.scala b/sjsonnet/src/sjsonnet/Error.scala index 49e30f32..bde82bf2 100644 --- a/sjsonnet/src/sjsonnet/Error.scala +++ b/sjsonnet/src/sjsonnet/Error.scala @@ -32,11 +32,11 @@ class Error(msg: String, stack: List[Error.Frame] = Nil, underlying: Option[Thro def asSeenFrom(ev: EvalErrorScope): Error = copy(stack = stack.map(_.asSeenFrom(ev))) - protected[this] def copy(msg: String = msg, stack: List[Error.Frame] = stack, + protected def copy(msg: String = msg, stack: List[Error.Frame] = stack, underlying: Option[Throwable] = underlying) = new Error(msg, stack, underlying) - private[this] def alwaysAddPos(expr: Expr): Boolean = expr match { + private def alwaysAddPos(expr: Expr): Boolean = expr match { case _: Expr.LocalExpr | _: Expr.Arr | _: Expr.ObjExtend | _: Expr.ObjBody | _: Expr.IfElse => false case _ => true } @@ -77,16 +77,16 @@ object Error { class ParseError(msg: String, stack: List[Error.Frame] = Nil, underlying: Option[Throwable] = None) extends Error(msg, stack, underlying) { - override protected[this] def copy(msg: String = msg, stack: List[Error.Frame] = stack, - underlying: Option[Throwable] = underlying) = + override protected def copy(msg: String = msg, stack: List[Error.Frame] = stack, + underlying: Option[Throwable] = underlying): sjsonnet.ParseError = new ParseError(msg, stack, underlying) } class StaticError(msg: String, stack: List[Error.Frame] = Nil, underlying: Option[Throwable] = None) extends Error(msg, stack, underlying) { - override protected[this] def copy(msg: String = msg, stack: List[Error.Frame] = stack, - underlying: Option[Throwable] = underlying) = + override protected def copy(msg: String = msg, stack: List[Error.Frame] = stack, + underlying: Option[Throwable] = underlying): sjsonnet.StaticError = new StaticError(msg, stack, underlying) } diff --git a/sjsonnet/src/sjsonnet/Evaluator.scala b/sjsonnet/src/sjsonnet/Evaluator.scala index 99de24b8..e18a7bc3 100644 --- a/sjsonnet/src/sjsonnet/Evaluator.scala +++ b/sjsonnet/src/sjsonnet/Evaluator.scala @@ -27,7 +27,7 @@ class Evaluator(resolver: CachedResolver, def warn(e: Error): Unit = if(warnLogger != null) warnLogger(e) def materialize(v: Val): Value = Materializer.apply(v) - val cachedImports = collection.mutable.HashMap.empty[Path, Val] + val cachedImports: mutable.HashMap[Path,Val] = collection.mutable.HashMap.empty[Path, Val] var tailstrict: Boolean = false override def visitExpr(e: Expr)(implicit scope: ValScope): Val = try { @@ -69,8 +69,9 @@ class Evaluator(resolver: CachedResolver, case e: Expr.Error => visitError(e) case e => visitInvalid(e) } - } catch Error.withStackFrame(e) - + } catch { + Error.withStackFrame(e) + } // This is only needed for --no-static-errors, otherwise these expression types do not make it past the optimizer def visitInvalid(e: Expr): Nothing = e match { case Id(pos, name) => @@ -323,6 +324,7 @@ class Evaluator(resolver: CachedResolver, private def visitApplyBuiltin(e: ApplyBuiltin)(implicit scope: ValScope) = { val arr = new Array[Lazy](e.argExprs.length) var idx = 0 + if (tailstrict) { while (idx < e.argExprs.length) { arr(idx) = visitExpr(e.argExprs(idx)) @@ -339,6 +341,7 @@ class Evaluator(resolver: CachedResolver, tailstrict = false res } else { + while (idx < e.argExprs.length) { val boundIdx = idx arr(idx) = visitAsLazy(e.argExprs(boundIdx)) @@ -433,21 +436,23 @@ class Evaluator(resolver: CachedResolver, ) } - def visitAnd(e: And)(implicit scope: ValScope) = { + def visitAnd(e: And)(implicit scope: ValScope): Val.Bool = { visitExpr(e.lhs) match { case _: Val.True => visitExpr(e.rhs) match{ - case b: Val.Bool => b + case b: Val.Bool => + b case unknown => Error.fail(s"binary operator && does not operate on ${unknown.prettyName}s.", e.pos) } - case _: Val.False => Val.False(e.pos) + case _: Val.False => + Val.False(e.pos) case unknown => Error.fail(s"binary operator && does not operate on ${unknown.prettyName}s.", e.pos) } } - def visitOr(e: Or)(implicit scope: ValScope) = { + def visitOr(e: Or)(implicit scope: ValScope): Val.Bool = { visitExpr(e.lhs) match { case _: Val.True => Val.True(e.pos) case _: Val.False => @@ -461,7 +466,7 @@ class Evaluator(resolver: CachedResolver, } } - def visitInSuper(e: InSuper)(implicit scope: ValScope) = { + def visitInSuper(e: InSuper)(implicit scope: ValScope): Val.Bool = { val sup = scope.bindings(e.selfIdx+1).asInstanceOf[Val.Obj] if(sup == null) Val.False(e.pos) else { @@ -470,7 +475,7 @@ class Evaluator(resolver: CachedResolver, } } - def visitBinaryOp(e: BinaryOp)(implicit scope: ValScope) = { + def visitBinaryOp(e: BinaryOp)(implicit scope: ValScope): Val.Literal = { val l = visitExpr(e.lhs) val r = visitExpr(e.rhs) val pos = e.pos @@ -594,7 +599,7 @@ class Evaluator(resolver: CachedResolver, } } - def visitMethod(rhs: Expr, params: Params, outerPos: Position)(implicit scope: ValScope) = + def visitMethod(rhs: Expr, params: Params, outerPos: Position)(implicit scope: ValScope): Val.Func = new Val.Func(outerPos, scope, params) { def evalRhs(vs: ValScope, es: EvalScope, fs: FileScope, pos: Position): Val = visitExpr(rhs)(vs) override def evalDefault(expr: Expr, vs: ValScope, es: EvalScope) = visitExpr(expr)(vs) @@ -619,14 +624,16 @@ class Evaluator(resolver: CachedResolver, def visitMemberList(objPos: Position, e: ObjBody.MemberList, sup: Val.Obj)(implicit scope: ValScope): Val.Obj = { val asserts = e.asserts val fields = e.fields - var cachedSimpleScope: ValScope = null.asInstanceOf[ValScope] + var cachedSimpleScope: Option[ValScope] = None var cachedObj: Val.Obj = null var asserting: Boolean = false def makeNewScope(self: Val.Obj, sup: Val.Obj): ValScope = { if((sup eq null) && (self eq cachedObj)) { - if(cachedSimpleScope == null.asInstanceOf[ValScope]) cachedSimpleScope = createNewScope(self, sup) - cachedSimpleScope + cachedSimpleScope.getOrElse{ + cachedSimpleScope = Some(createNewScope(self, sup)) + cachedSimpleScope.get + } } else createNewScope(self, sup) } diff --git a/sjsonnet/src/sjsonnet/Expr.scala b/sjsonnet/src/sjsonnet/Expr.scala index 28bac9b2..d5c0aa2e 100644 --- a/sjsonnet/src/sjsonnet/Expr.scala +++ b/sjsonnet/src/sjsonnet/Expr.scala @@ -22,7 +22,7 @@ trait Expr{ override def toString: String = s"$exprErrorString@$pos" } object Expr{ - private final def arrStr(a: Array[_]): String = { + private final def arrStr(a: Array[?]): String = { if(a == null) "null" else a.mkString("[", ", ", "]") } @@ -37,7 +37,7 @@ object Expr{ override def exprErrorString: String = s"${super.exprErrorString} $name" } case class Arr(pos: Position, value: Array[Expr]) extends Expr { - override def toString = s"Arr($pos, ${arrStr(value)})" + override def toString: String = s"Arr($pos, ${arrStr(value)})" } sealed trait FieldName @@ -62,14 +62,14 @@ object Expr{ args: Params, sep: Visibility, rhs: Expr) extends Member { - def isStatic = fieldName.isInstanceOf[FieldName.Fixed] && !plus && args == null && sep == Visibility.Normal && rhs.isInstanceOf[Val.Literal] + def isStatic: Boolean = fieldName.isInstanceOf[FieldName.Fixed] && !plus && args == null && sep == Visibility.Normal && rhs.isInstanceOf[Val.Literal] } case class AssertStmt(value: Expr, msg: Expr) extends Member } case class Params(names: Array[String], defaultExprs: Array[Expr]){ val paramMap = names.zipWithIndex.toMap - override def toString = s"Params(${arrStr(names)}, ${arrStr(defaultExprs)})" + override def toString: String = s"Params(${arrStr(names)}, ${arrStr(defaultExprs)})" } case class UnaryOp(pos: Position, op: Int, value: Expr) extends Expr { @@ -115,7 +115,7 @@ object Expr{ } case class AssertExpr(pos: Position, asserted: Member.AssertStmt, returned: Expr) extends Expr case class LocalExpr(pos: Position, bindings: Array[Bind], returned: Expr) extends Expr { - override def toString = s"LocalExpr($pos, ${arrStr(bindings)}, $returned)" + override def toString: String = s"LocalExpr($pos, ${arrStr(bindings)}, $returned)" override def equals(o: Any): Boolean = o match { case o: LocalExpr => pos == o.pos && Arrays.equals(bindings.asInstanceOf[Array[AnyRef]], o.bindings.asInstanceOf[Array[AnyRef]]) && returned == o.returned @@ -185,7 +185,7 @@ object Expr{ postLocals: Array[Bind], first: ForSpec, rest: List[CompSpec]) extends ObjBody { - override def toString = s"ObjComp($pos, ${arrStr(preLocals)}, $key, $value, ${arrStr(postLocals)}, $first, $rest)" + override def toString: String = s"ObjComp($pos, ${arrStr(preLocals)}, $key, $value, ${arrStr(postLocals)}, $first, $rest)" } } } diff --git a/sjsonnet/src/sjsonnet/ExprTransform.scala b/sjsonnet/src/sjsonnet/ExprTransform.scala index 1a666ea0..484a05dc 100644 --- a/sjsonnet/src/sjsonnet/ExprTransform.scala +++ b/sjsonnet/src/sjsonnet/ExprTransform.scala @@ -203,10 +203,10 @@ abstract class ExprTransform { } } - protected[this] def transformArr[T <: Expr](a: Array[T]): Array[T] = - transformGenericArr(a)((transform _).asInstanceOf[T => T]) + protected def transformArr[T <: Expr](a: Array[T]): Array[T] = + transformGenericArr(a)((transform(_)).asInstanceOf[T => T]) - protected[this] def transformParams(p: Params): Params = { + protected def transformParams(p: Params): Params = { if(p == null) return null val defs = p.defaultExprs if(defs == null) p @@ -217,16 +217,16 @@ abstract class ExprTransform { } } - protected[this] def transformBinds(a: Array[Bind]): Array[Bind] = + protected def transformBinds(a: Array[Bind]): Array[Bind] = transformGenericArr(a)(transformBind) - protected[this] def transformFields(a: Array[Member.Field]): Array[Member.Field] = + protected def transformFields(a: Array[Member.Field]): Array[Member.Field] = transformGenericArr(a)(transformField) - protected[this] def transformAsserts(a: Array[Member.AssertStmt]): Array[Member.AssertStmt] = + protected def transformAsserts(a: Array[Member.AssertStmt]): Array[Member.AssertStmt] = transformGenericArr(a)(transformAssert) - protected[this] def transformBind(b: Bind): Bind = { + protected def transformBind(b: Bind): Bind = { val args = b.args val rhs = b.rhs val args2 = transformParams(args) @@ -235,7 +235,7 @@ abstract class ExprTransform { else b.copy(args = args2, rhs = rhs2) } - protected[this] def transformField(f: Member.Field): Member.Field = { + protected def transformField(f: Member.Field): Member.Field = { val x = f.fieldName val y = f.args val z = f.rhs @@ -246,14 +246,14 @@ abstract class ExprTransform { else f.copy(fieldName = x2, args = y2, rhs = z2) } - protected[this] def transformFieldName(f: FieldName): FieldName = f match { + protected def transformFieldName(f: FieldName): FieldName = f match { case FieldName.Dyn(x) => val x2 = transform(x) if(x2 eq x) f else FieldName.Dyn(x2) case _ => f } - protected[this] def transformAssert(a: Member.AssertStmt): Member.AssertStmt = { + protected def transformAssert(a: Member.AssertStmt): Member.AssertStmt = { val x = a.value val y = a.msg val x2 = transform(x) @@ -262,14 +262,14 @@ abstract class ExprTransform { else a.copy(value = x2, msg = y2) } - protected[this] def transformOption(o: Option[Expr]): Option[Expr] = o match { + protected def transformOption(o: Option[Expr]): Option[Expr] = o match { case Some(e) => val e2 = transform(e) if(e2 eq e) o else Some(e2) case None => o } - protected[this] def transformList(l: List[Expr]): List[Expr] = { + protected def transformList(l: List[Expr]): List[Expr] = { val lb = List.newBuilder[Expr] var diff = false l.foreach { e => @@ -280,7 +280,7 @@ abstract class ExprTransform { if(diff) lb.result() else l } - protected[this] def transformGenericArr[T <: AnyRef](a: Array[T])(f: T => T): Array[T] = { + protected def transformGenericArr[T <: AnyRef](a: Array[T])(f: T => T): Array[T] = { if(a == null) return null var i = 0 while(i < a.length) { diff --git a/sjsonnet/src/sjsonnet/Format.scala b/sjsonnet/src/sjsonnet/Format.scala index 5b93c6e9..3caac98c 100644 --- a/sjsonnet/src/sjsonnet/Format.scala +++ b/sjsonnet/src/sjsonnet/Format.scala @@ -22,13 +22,13 @@ object Format{ precision: Option[Int], conversion: Char) import fastparse._, NoWhitespace._ - def integer[_: P] = P( CharIn("1-9") ~ CharsWhileIn("0-9", 0) | "0" ) - def label[_: P] = P( ("(" ~ CharsWhile(_ != ')').! ~ ")").? ) - def flags[_: P] = P( CharsWhileIn("#0\\- +", 0).! ) - def width[_: P] = P( (integer | "*").!.? ) - def precision[_: P] = P( ("." ~/ integer.!).? ) - def conversion[_: P] = P( CharIn("diouxXeEfFgGcrsa%").! ) - def formatSpec[_: P] = P( label ~ flags ~ width ~ precision ~ CharIn("hlL").? ~ conversion ).map{ + def integer(implicit p: P[?]): P[Unit] = P( CharIn("1-9") ~ CharsWhileIn("0-9", 0) | "0" ) + def label(implicit p: P[?]): P[Option[String]] = P( ("(" ~ CharsWhile(_ != ')').! ~ ")").? ) + def flags(implicit p: P[?]): P[String] = P( CharsWhileIn("#0\\- +", 0).! ) + def width(implicit p: P[?]): P[Option[String]] = P( (integer | "*").!.? ) + def precision(implicit p: P[?]): P[Option[String]] = P( ("." ~/ integer.!).? ) + def conversion(implicit p: P[?]): P[String] = P( CharIn("diouxXeEfFgGcrsa%").! ) + def formatSpec(implicit p: P[?]): P[FormatSpec] = P( label ~ flags ~ width ~ precision ~ CharIn("hlL").? ~ conversion ).map{ case (label, flags, width, precision, conversion) => FormatSpec( label, @@ -44,18 +44,18 @@ object Format{ } - def plain[_: P] = P( CharsWhile(_ != '%', 0).! ) - def format[_: P] = P( plain ~ (("%" ~/ formatSpec) ~ plain).rep ~ End) + def plain(implicit p: P[?]): P[String] = P( CharsWhile(_ != '%', 0).! ) + def format(implicit p: P[?]): P[(String, Seq[(FormatSpec, String)])] = P( plain ~ (("%" ~/ formatSpec) ~ plain).rep ~ End) - def widenRaw(formatted: FormatSpec, txt: String) = widen(formatted, "", "", txt, false, false) + def widenRaw(formatted: FormatSpec, txt: String): String = widen(formatted, "", "", txt, false, false) def widen(formatted: FormatSpec, lhs: String, mhs: String, rhs: String, numeric: Boolean, - signedConversion: Boolean) = { + signedConversion: Boolean): String = { val lhs2 = if(signedConversion && formatted.blankBeforePositive) " " + lhs @@ -167,7 +167,7 @@ object Format{ output.toString() } - def formatInteger(formatted: FormatSpec, s: Double) = { + def formatInteger(formatted: FormatSpec, s: Double): String = { val (lhs, rhs) = if (s < 0) { ("-", s.toLong.toString.substring(1)) } else { @@ -181,7 +181,7 @@ object Format{ ) } - def formatFloat(formatted: FormatSpec, s: Double) = { + def formatFloat(formatted: FormatSpec, s: Double): String = { widen( formatted, if (s < 0) "-" else "", "", @@ -197,7 +197,7 @@ object Format{ } - def formatOctal(formatted: FormatSpec, s: Double) = { + def formatOctal(formatted: FormatSpec, s: Double): String = { val (lhs, rhs) = if (s < 0) { ("-", s.toLong.abs.toOctalString) } else { @@ -211,7 +211,7 @@ object Format{ ) } - def formatHexadecimal(formatted: FormatSpec, s: Double) = { + def formatHexadecimal(formatted: FormatSpec, s: Double): String = { val (lhs, rhs) = if (s < 0) { ("-", s.toLong.abs.toHexString) } else { @@ -225,7 +225,7 @@ object Format{ ) } - def precisionPad(lhs: String, rhs: String, precision: Option[Int]) = { + def precisionPad(lhs: String, rhs: String, precision: Option[Int]): String = { precision match{ case None => rhs case Some(p) => @@ -234,7 +234,7 @@ object Format{ } } - def formatGeneric(formatted: FormatSpec, s: Double) = { + def formatGeneric(formatted: FormatSpec, s: Double): String = { val precision = formatted.precision.getOrElse(6) val leadingPrecision = math.floor(math.log10(s)).toInt + 1 val trailingPrecision = math.max(0, precision - leadingPrecision) @@ -267,7 +267,7 @@ object Format{ } - def formatExponent(formatted: FormatSpec, s: Double) = { + def formatExponent(formatted: FormatSpec, s: Double): String = { widen( formatted, if (s < 0) "-" else "", "", @@ -281,7 +281,7 @@ object Format{ ) } - def maybeDecimalPoint(formatted: FormatSpec, fracLengths: (Int, Int)) = { + def maybeDecimalPoint(formatted: FormatSpec, fracLengths: (Int, Int)): Option[(Int, Int)] = { if (formatted.precision.contains(0) && !formatted.alternate) None else Some(fracLengths) } diff --git a/sjsonnet/src/sjsonnet/Importer.scala b/sjsonnet/src/sjsonnet/Importer.scala index c6f3700d..1fd51b42 100644 --- a/sjsonnet/src/sjsonnet/Importer.scala +++ b/sjsonnet/src/sjsonnet/Importer.scala @@ -31,7 +31,7 @@ object Importer { case class FileParserInput(file: File) extends ParserInput { - private[this] val bufferedFile = new BufferedRandomAccessFile(file.getAbsolutePath, 1024 * 8) + private val bufferedFile = new BufferedRandomAccessFile(file.getAbsolutePath, 1024 * 8) private lazy val fileLength = file.length.toInt @@ -53,7 +53,7 @@ case class FileParserInput(file: File) extends ParserInput { override def checkTraceable(): Unit = {} - private[this] lazy val lineNumberLookup: Array[Int] = { + private lazy val lineNumberLookup: Array[Int] = { val lines = mutable.ArrayBuffer[Int]() val bufferedStream = new BufferedInputStream(new FileInputStream(file)) var byteRead: Int = 0 @@ -159,7 +159,7 @@ case class StaticResolvedFile(content: String) extends ResolvedFile { def readString(): String = content // We just cheat, the content hash can be the content itself for static imports - lazy val contentHash: String = content + def contentHash(): String = content override def readRawBytes(): Array[Byte] = content.getBytes(StandardCharsets.UTF_8) } @@ -170,13 +170,13 @@ case class StaticBinaryResolvedFile(content: Array[Byte]) extends ResolvedFile { def readString(): String = ??? // Not used for binary imports // We just cheat, the content hash can be the content itself for static imports - lazy val contentHash: String = content.hashCode().toString + def contentHash(): String = content.hashCode().toString override def readRawBytes(): Array[Byte] = content } class CachedImporter(parent: Importer) extends Importer { - val cache = mutable.HashMap.empty[Path, ResolvedFile] + val cache: mutable.HashMap[Path,ResolvedFile] = mutable.HashMap.empty[Path, ResolvedFile] def resolve(docBase: Path, importName: String): Option[Path] = parent.resolve(docBase, importName) diff --git a/sjsonnet/src/sjsonnet/Materializer.scala b/sjsonnet/src/sjsonnet/Materializer.scala index 0bbd39cb..3fb134c6 100644 --- a/sjsonnet/src/sjsonnet/Materializer.scala +++ b/sjsonnet/src/sjsonnet/Materializer.scala @@ -61,7 +61,7 @@ abstract class Materializer { Error.fail("Couldn't manifest function with params [" + s.params.names.mkString(",") + "]", v.pos) case vv: Val => Error.fail("Unknown value type " + vv.prettyName, vv.pos) - case _ => + case null => Error.fail("Unknown value type " + v) } } catch { diff --git a/sjsonnet/src/sjsonnet/Parser.scala b/sjsonnet/src/sjsonnet/Parser.scala index a1dcdbed..3a483126 100644 --- a/sjsonnet/src/sjsonnet/Parser.scala +++ b/sjsonnet/src/sjsonnet/Parser.scala @@ -15,7 +15,7 @@ import scala.collection.mutable */ object Parser { - val precedenceTable = Seq( + val precedenceTable: Seq[Seq[String]] = Seq( Seq("*", "/", "%"), Seq("+", "-"), Seq("<<", ">>"), @@ -28,18 +28,18 @@ object Parser { Seq("||") ) - val precedence = precedenceTable + val precedence: Map[String,Int] = precedenceTable .reverse .zipWithIndex .flatMap{case (ops, idx) => ops.map(_ -> idx)} .toMap - val keywords = Set( + val keywords: Set[String] = Set( "assert", "else", "error", "false", "for", "function", "if", "import", "importstr", "in", "local", "null", "tailstrict", "then", "self", "super", "true", "importbin" ) - def idStartChar(c: Char) = c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') + def idStartChar(c: Char): Boolean = c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') private val emptyLazyArray = new Array[Lazy](0) } @@ -52,15 +52,15 @@ class Parser(val currentFile: Path, private val fileScope = new FileScope(currentFile) - def Pos[_: P]: P[Position] = Index.map(offset => new Position(fileScope, offset)) + def Pos(implicit p: P[?]): P[Position] = Index.map(offset => new Position(fileScope, offset)) - def id[_: P] = P( + def id(implicit p: P[?]): P[String] = P( CharIn("_a-zA-Z") ~~ CharsWhileIn("_a-zA-Z0-9", 0) ).!.filter(s => !keywords.contains(s)) - def break[_: P] = P(!CharIn("_a-zA-Z0-9")) - def number[_: P]: P[Val.Num] = P( + def break(implicit p: P[?]): P[Unit] = P(!CharIn("_a-zA-Z0-9")) + def number(implicit p: P[?]): P[Val.Num] = P( Pos ~~ ( CharsWhileIn("0-9") ~~ ("." ~ CharsWhileIn("0-9")).? ~~ @@ -68,8 +68,8 @@ class Parser(val currentFile: Path, ).! ).map(s => Val.Num(s._1, s._2.toDouble)) - def escape[_: P] = P( escape0 | escape1 ) - def escape0[_: P] = P("\\" ~~ !"u" ~~ AnyChar.!).map{ + def escape(implicit p: P[?]): P[String] = P( escape0 | escape1 ) + def escape0(implicit p: P[?]): P[String] = P("\\" ~~ !"u" ~~ AnyChar.!).map{ case "\"" => "\"" case "'" => "\'" case "\\" => "\\" @@ -80,36 +80,29 @@ class Parser(val currentFile: Path, case "r" => "\r" case "t" => "\t" } - def escape1[_: P] = P( "\\u" ~~ CharIn("0-9a-fA-F").repX(min=4, max=4).! ).map{ + def escape1(implicit p: P[?]): P[String] = P( "\\u" ~~ CharIn("0-9a-fA-F").repX(min=4, max=4).! ).map{ s => Integer.parseInt(s, 16).toChar.toString } - def doubleString[_: P]: P[Seq[String]] = + def doubleString(implicit p: P[?]): P[Seq[String]] = P( (CharsWhile(x => x != '"' && x != '\\').! | escape).repX ~~ "\"" ) - def singleString[_: P]: P[Seq[String]] = + def singleString(implicit p: P[?]): P[Seq[String]] = P( (CharsWhile(x => x != '\'' && x != '\\').! | escape).repX ~~ "'" ) - def literalDoubleString[_: P]: P[Seq[String]] = + def literalDoubleString(implicit p: P[?]): P[Seq[String]] = P( (CharsWhile(_ != '"').! | "\"\"".!.map(_ => "\"")).repX ~~ "\"" ) - def literalSingleString[_: P]: P[Seq[String]] = + def literalSingleString(implicit p: P[?]): P[Seq[String]] = P( (CharsWhile(_ != '\'').! | "''".!.map(_ => "'")).repX ~~ "'" ) - def tripleBarStringLines[_: P]: P[Seq[String]] = P( + def tripleBarStringLines(implicit p: P[?]): P[Seq[String]] = P( tripleBarStringHead.flatMapX { case (pre, w, head) => tripleBarStringBody(w).map(pre ++ Seq(head, "\n") ++ _) } ) - def maybeChompedTripleBarString[_: P]: P[Seq[String]] = tripleBarString.map{ - case (true, lines) => - Seq(lines.mkString.stripLineEnd) - case (false, lines) => - lines - } - - def tripleBarString[_: P]: P[(Boolean, Seq[String])] = P( - ("||-" | "||").?.!.map(_.last == '-')./ ~~ CharsWhileIn(" \t", 0) ~~ + def tripleBarString(implicit p: P[?]): P[Seq[String]] = P( + "||"./ ~~ CharsWhileIn(" \t", 0) ~~ "\n" ~~ tripleBarStringLines ~~ "\n" ~~ CharsWhileIn(" \t", 0) ~~ "|||" ) - def string[_: P]: P[String] = P( + def string(implicit p: P[?]): P[String] = P( SingleChar.flatMapX{ case '\"' => doubleString case '\'' => singleString @@ -123,24 +116,24 @@ class Parser(val currentFile: Path, } ).map(_.mkString) - def tripleBarStringHead[_: P] = P( + def tripleBarStringHead(implicit p: P[?]): P[(Seq[String], String, String)] = P( (CharsWhileIn(" \t", 0) ~~ "\n".!).repX ~~ CharsWhileIn(" \t", 1).! ~~ CharsWhile(_ != '\n').! ) - def tripleBarBlankHead[_: P]: P[String] = + def tripleBarBlankHead(implicit p: P[?]): P[String] = P( CharsWhileIn(" \t", 0) ~~ &("\n").map(_ => "\n") ) - def tripleBarBlank[_: P]: P[String] = P( "\n" ~~ tripleBarBlankHead ) + def tripleBarBlank(implicit p: P[?]): P[String] = P( "\n" ~~ tripleBarBlankHead ) - def tripleBarStringBody[_: P](w: String): P[Seq[String]] = P( + def tripleBarStringBody(w: String)(implicit p: P[?]): P[Seq[String]] = P( (tripleBarBlank | "\n" ~~ w ~~ CharsWhile(_ != '\n').!.map(_ + "\n")).repX ) - def arr[_: P]: P[Expr] = P( (Pos ~~ &("]")).map(new Val.Arr(_, emptyLazyArray)) | arrBody ) - def compSuffix[_: P] = P( forspec ~ compspec ).map(Left(_)) - def arrBody[_: P]: P[Expr] = P( + def arr(implicit p: P[?]): P[Expr] = P( (Pos ~~ &("]")).map(new Val.Arr(_, emptyLazyArray)) | arrBody ) + def compSuffix(implicit p: P[?]): P[Left[(Expr.ForSpec, Seq[Expr.CompSpec]),Nothing]] = P( forspec ~ compspec ).map(Left(_)) + def arrBody(implicit p: P[?]): P[Expr] = P( Pos ~~ expr ~ (compSuffix | "," ~ (compSuffix | (expr.rep(0, sep = ",") ~ ",".?).map(Right(_)))).? ).map{ @@ -159,19 +152,19 @@ class Parser(val currentFile: Path, case (offset, first, Some(Right(rest))) => Expr.Arr(offset, Array(first) ++ rest) } - def assertExpr[_: P](pos: Position): P[Expr] = + def assertExpr(pos: Position)(implicit p: P[?]): P[Expr] = P( assertStmt ~ ";" ~ expr ).map(t => Expr.AssertExpr(pos, t._1, t._2)) - def function[_: P](pos: Position): P[Expr] = + def function(pos: Position)(implicit p: P[?]): P[Expr] = P( "(" ~/ params ~ ")" ~ expr ).map(t => Expr.Function(pos, t._1, t._2)) - def ifElse[_: P](pos: Position): P[Expr] = - P( Pos ~~ expr ~ "then" ~~ break ~ expr ~ ("else" ~~ break ~ expr).?.map(_.getOrElse(null)) ).map(Expr.IfElse.tupled) + def ifElse(pos: Position)(implicit p: P[?]): P[Expr] = + P( Pos ~~ expr ~ "then" ~~ break ~ expr ~ ("else" ~~ break ~ expr).?.map(_.getOrElse(null)) ).map{case (pos, cond, t, e) => Expr.IfElse(pos, cond, t, e)} - def localExpr[_: P]: P[Expr] = - P( Pos ~~ bind.rep(min=1, sep = ","./).map(s => if(s.isEmpty) null else s.toArray) ~ ";" ~ expr ).map(Expr.LocalExpr.tupled) + def localExpr(implicit p: P[?]): P[Expr] = + P( Pos ~~ bind.rep(min=1, sep = ","./).map(s => if(s.isEmpty) null else s.toArray) ~ ";" ~ expr ).map{case (pos, bind, ret) => Expr.LocalExpr(pos, bind, ret)} - def expr[_: P]: P[Expr] = + def expr(implicit p: P[?]): P[Expr] = P("" ~ expr1 ~ (Pos ~~ binaryop ~/ expr1).rep ~ "").map{ case (pre, fs) => var remaining = fs def climb(minPrec: Int, current: Expr): Expr = { @@ -221,11 +214,11 @@ class Parser(val currentFile: Path, climb(0, pre) } - def expr1[_: P]: P[Expr] = P(expr2 ~ exprSuffix2.rep).map{ + def expr1(implicit p: P[?]): P[Expr] = P(expr2 ~ exprSuffix2.rep).map{ case (pre, fs) => fs.foldLeft(pre){case (p, f) => f(p) } } - def exprSuffix2[_: P]: P[Expr => Expr] = P( + def exprSuffix2(implicit p: P[?]): P[Expr => Expr] = P( Pos.flatMapX{i => CharIn(".[({")./.!.map(_(0)).flatMapX{ c => (c: @switch) match{ @@ -244,13 +237,13 @@ class Parser(val currentFile: Path, } ) - def local[_: P] = P( localExpr ) - def importStr[_: P](pos: Position) = P( importExpr.map(Expr.ImportStr(pos, _)) ) - def importBin[_: P](pos: Position) = P( importExpr.map(Expr.ImportBin(pos, _)) ) - def `import`[_: P](pos: Position) = P( importExpr.map(Expr.Import(pos, _)) ) - def error[_: P](pos: Position) = P(expr.map(Expr.Error(pos, _)) ) + def local(implicit p: P[?]): P[Expr] = P( localExpr ) + def importStr(pos: Position)(implicit p: P[?]): P[Expr.ImportStr] = P( importExpr.map(Expr.ImportStr(pos, _)) ) + def importBin(pos: Position)(implicit p: P[?]): P[Expr.ImportBin] = P( importExpr.map(Expr.ImportBin(pos, _)) ) + def `import`(pos: Position)(implicit p: P[?]): P[Expr.Import] = P( importExpr.map(Expr.Import(pos, _)) ) + def error(pos: Position)(implicit p: P[?]): P[Expr.Error] = P(expr.map(Expr.Error(pos, _)) ) - def importExpr[_: P]: P[String] = P( + def importExpr(implicit p: P[?]): P[String] = P( if (!strictImportSyntax) string else expr.flatMap { case Val.Str(_, s) => Pass(s) @@ -258,7 +251,7 @@ class Parser(val currentFile: Path, } ) - def unaryOpExpr[_: P](pos: Position, op: Char) = P( + def unaryOpExpr(pos: Position, op: Char)(implicit p: P[?]): P[Expr.UnaryOp] = P( expr1.map{ e => def k2 = op match{ case '+' => Expr.UnaryOp.OP_+ @@ -270,17 +263,17 @@ class Parser(val currentFile: Path, } ) - def constructString(pos: Position, lines: Seq[String]) = { + def constructString(pos: Position, lines: Seq[String]): Val.Str = { val s = lines.mkString val unique = internedStrings.getOrElseUpdate(s, s) Val.Str(pos, unique) } // Any `expr` that isn't naively left-recursive - def expr2[_: P]: P[Expr] = P( + def expr2(implicit p: P[?]): P[Expr] = P( Pos.flatMapX{ pos => SingleChar.flatMapX{ c => - (c: @switch) match { + c match { case '{' => Pass ~ objinside ~ "}" case '+' | '-' | '~' | '!' => Pass ~ unaryOpExpr(pos, c) case '[' => Pass ~ arr ~ "]" @@ -297,7 +290,7 @@ class Parser(val currentFile: Path, case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => P.current.index = pos.offset; number case x if idStartChar(x) => CharsWhileIn("_a-zA-Z0-9", 0).!.flatMapX { y => - x + y match { + "" + x + y match { case "null" => Pass(Val.Null(pos)) case "true" => Pass(Val.True(pos)) case "false" => Pass(Val.False(pos)) @@ -320,7 +313,7 @@ class Parser(val currentFile: Path, } ) - def objinside[_: P]: P[Expr.ObjBody] = P( + def objinside(implicit p: P[?]): P[Expr.ObjBody] = P( Pos ~ member.rep(sep = ",") ~ ",".? ~ (forspec ~ compspec).? ).flatMap { case t @ (pos, exprs, _) => val seen = collection.mutable.Set.empty[String] @@ -343,7 +336,7 @@ class Parser(val currentFile: Path, case Expr.Bind(_, n, _, _) => if (seen(n)) overlap = n else seen.add(n) - case _ => + case null => } if (overlap != null) Fail.opaque("no duplicate local: " + overlap) if(b.isEmpty) null else b @@ -380,35 +373,35 @@ class Parser(val currentFile: Path, Expr.ObjBody.ObjComp(pos, preLocals.toArray, lhs, rhs, plus, postLocals.toArray, comps._1, comps._2.toList) } - def member[_: P]: P[Expr.Member] = P( objlocal | "assert" ~~ break ~ assertStmt | field ) - def field[_: P] = P( + def member(implicit p: P[?]): P[Expr.Member] = P( objlocal | "assert" ~~ break ~ assertStmt | field ) + def field(implicit p: P[?]): P[Expr.Member.Field] = P( (Pos ~~ fieldname ~/ "+".!.? ~ ("(" ~ params ~ ")").? ~ fieldKeySep ~/ expr).map{ case (pos, name, plus, p, h2, e) => Expr.Member.Field(pos, name, plus.nonEmpty, p.getOrElse(null), h2, e) } ) - def fieldKeySep[_: P] = P( StringIn(":::", "::", ":") ).!.map{ + def fieldKeySep(implicit p: P[?]): P[Visibility] = P( StringIn(":::", "::", ":") ).!.map{ case ":" => Visibility.Normal case "::" => Visibility.Hidden case ":::" => Visibility.Unhide } - def objlocal[_: P] = P( "local" ~~ break ~/ bind ) - def compspec[_: P]: P[Seq[Expr.CompSpec]] = P( (forspec | ifspec).rep ) - def forspec[_: P] = - P( Pos ~~ "for" ~~ break ~/ id ~ "in" ~~ break ~ expr ).map(Expr.ForSpec.tupled) - def ifspec[_: P] = P( Pos ~~ "if" ~~ break ~/ expr ).map(Expr.IfSpec.tupled) - def fieldname[_: P] = P( - id.map(Expr.FieldName.Fixed) | - string.map(Expr.FieldName.Fixed) | - "[" ~ expr.map(Expr.FieldName.Dyn) ~ "]" + def objlocal(implicit p: P[?]): P[Expr.Bind] = P( "local" ~~ break ~/ bind ) + def compspec(implicit p: P[?]): P[Seq[Expr.CompSpec]] = P( (forspec | ifspec).rep ) + def forspec(implicit p: P[?]): P[Expr.ForSpec] = + P( Pos ~~ "for" ~~ break ~/ id ~ "in" ~~ break ~ expr ).map{case (pos, name, cond) => Expr.ForSpec(pos, name, cond) } + def ifspec(implicit p: P[?]): P[Expr.IfSpec] = P( Pos ~~ "if" ~~ break ~/ expr ).map{case (pos, cond) => Expr.IfSpec(pos, cond) } + def fieldname(implicit p: P[?]): P[Expr.FieldName] = P( + id.map(Expr.FieldName.Fixed.apply) | + string.map(Expr.FieldName.Fixed.apply) | + "[" ~ expr.map(Expr.FieldName.Dyn.apply) ~ "]" ) - def assertStmt[_: P] = - P( expr ~ (":" ~ expr).?.map(_.getOrElse(null)) ).map(Expr.Member.AssertStmt.tupled) + def assertStmt(implicit p: P[?]): P[Expr.Member.AssertStmt] = + P( expr ~ (":" ~ expr).?.map(_.getOrElse(null)) ).map{case (value, msg) => Expr.Member.AssertStmt(value, msg) } - def bind[_: P] = - P( Pos ~~ id ~ ("(" ~/ params.? ~ ")").?.map(_.flatten).map(_.getOrElse(null)) ~ "=" ~ expr ).map(Expr.Bind.tupled) + def bind(implicit p: P[?]): P[Expr.Bind] = + P( Pos ~~ id ~ ("(" ~/ params.? ~ ")").?.map(_.flatten).map(_.getOrElse(null)) ~ "=" ~ expr ).map{case (pos, name, args, rhs )=> Expr.Bind(pos, name, args, rhs)} - def args[_: P] = P( ((id ~ "=" ~ !"=").? ~ expr).rep(sep = ",") ~ ",".? ).flatMapX{ x => + def args(implicit p: P[?]): P[(Array[Expr], Array[String])] = P( ((id ~ "=" ~ !"=").? ~ expr).rep(sep = ",") ~ ",".? ).flatMapX{ x => if (x.sliding(2).exists{case Seq(l, r) => l._1.isDefined && r._1.isEmpty case _ => false}) { Fail.opaque("no positional params after named params") } else { @@ -418,7 +411,7 @@ class Parser(val currentFile: Path, } } - def params[_: P]: P[Expr.Params] = P( (id ~ ("=" ~ expr).?).rep(sep = ",") ~ ",".? ).flatMapX{ x => + def params(implicit p: P[?]): P[Expr.Params] = P( (id ~ ("=" ~ expr).?).rep(sep = ",") ~ ",".? ).flatMapX{ x => val seen = collection.mutable.Set.empty[String] var overlap: String = null for((k, v) <- x){ @@ -434,7 +427,7 @@ class Parser(val currentFile: Path, } - def binaryop[_: P] = P( + def binaryop(implicit p: P[?]): P[String] = P( StringIn( "<<", ">>", "<=", ">=", "in", "==", "!=", "&&", "||", "*", "/", "%", "+", "-", "<", ">", "&", "^", "|" @@ -442,17 +435,17 @@ class Parser(val currentFile: Path, ).! - def document[_: P]: P[(Expr, FileScope)] = P( expr ~ Pass(fileScope) ~ End ) + def document(implicit p: P[?]): P[(Expr, FileScope)] = P( expr ~ Pass(fileScope) ~ End ) } final class Position(val fileScope: FileScope, val offset: Int) { def currentFile = fileScope.currentFile def noOffset = fileScope.noOffsetPos - override def equals(o: Any) = o match { + override def equals(o: Any): Boolean = o match { case o: Position => currentFile == o.currentFile && offset == o.offset case _ => false } - override def toString = { + override def toString: String = { val name = if(fileScope == null) "null" else fileScope.currentFileLastPathElement s"Position($name, $offset)" } @@ -463,6 +456,6 @@ final class Position(val fileScope: FileScope, val offset: Int) { * evaluation of a single Jsonnet file. Contains the current file path. */ class FileScope(val currentFile: Path) { - lazy val currentFileLastPathElement = if(currentFile == null) null else currentFile.last + lazy val currentFileLastPathElement: String = if(currentFile == null) null else currentFile.last val noOffsetPos: Position = new Position(this, -1) } diff --git a/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala b/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala index 33574025..687b519c 100644 --- a/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala +++ b/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala @@ -28,7 +28,10 @@ class PrettyYamlRenderer(out: Writer = new java.io.StringWriter(), var leftHandPrefixOffset = 0 var firstElementInArray = false var bufferedComment: String = null - override def visitString(s: CharSequence, index: Int) = { + + override def visitJsonableObject(length: Int, index: Int): ObjVisitor[Writer,Writer] = visitObject(length, index) + + override def visitString(s: CharSequence, index: Int): Writer = { addSpaceAfterColon() flushBuffer() @@ -84,13 +87,13 @@ class PrettyYamlRenderer(out: Writer = new java.io.StringWriter(), out } - def addSpaceAfterColon() = { + def addSpaceAfterColon(): Unit = { if (afterColon) { out.append(' ') afterColon = false } } - override def visitFloat64(d: Double, index: Int) = { + override def visitFloat64(d: Double, index: Int): Writer = { addSpaceAfterColon() flushBuffer() out.append(RenderUtils.renderDouble(d)) @@ -98,34 +101,34 @@ class PrettyYamlRenderer(out: Writer = new java.io.StringWriter(), out } - val loadedFileContents = mutable.HashMap.empty[Path, Array[Int]] - def saveCurrentPos() = { + val loadedFileContents: mutable.HashMap[Path,Array[Int]] = mutable.HashMap.empty[Path, Array[Int]] + def saveCurrentPos(): Unit = { val current = getCurrentPosition() if (current != null){ bufferedComment = " # " + current.currentFile.renderOffsetStr(current.offset, loadedFileContents) } } - override def visitTrue(index: Int) = { + override def visitTrue(index: Int): Writer = { addSpaceAfterColon() val out = super.visitTrue(index) saveCurrentPos() out } - override def visitFalse(index: Int) = { + override def visitFalse(index: Int): Writer = { addSpaceAfterColon() val out = super.visitFalse(index) saveCurrentPos() out } - override def visitNull(index: Int) = { + override def visitNull(index: Int): Writer = { addSpaceAfterColon() val out = super.visitNull(index) saveCurrentPos() out } - override def flushBuffer() = { + override def flushBuffer(): Unit = { if (newlineBuffered) { afterColon = false if (bufferedComment != null){ @@ -141,10 +144,10 @@ class PrettyYamlRenderer(out: Writer = new java.io.StringWriter(), newlineBuffered = false dashBuffered = false } - override def visitArray(length: Int, index: Int) = new ArrVisitor[Writer, Writer] { + override def visitArray(length: Int, index: Int): upickle.core.ArrVisitor[java.io.Writer,java.io.Writer]{def subVisitor: sjsonnet.PrettyYamlRenderer} = new ArrVisitor[Writer, Writer] { var empty = true val dedentInObject = afterKey && !indentArrayInObject - def subVisitor = { + def subVisitor: sjsonnet.PrettyYamlRenderer = { if (empty){ afterColon = false flushBuffer() @@ -185,14 +188,14 @@ class PrettyYamlRenderer(out: Writer = new java.io.StringWriter(), out } } - override def visitObject(length: Int, index: Int) = new ObjVisitor[Writer, Writer] { + override def visitObject(length: Int, index: Int): upickle.core.ObjVisitor[java.io.Writer,java.io.Writer]{def subVisitor: sjsonnet.PrettyYamlRenderer; def visitKey(index: Int): sjsonnet.PrettyYamlRenderer} = new ObjVisitor[Writer, Writer] { firstElementInArray = false var empty = true flushBuffer() if (!topLevel) depth += 1 topLevel = false - def subVisitor = PrettyYamlRenderer.this - def visitKey(index: Int) = { + def subVisitor: sjsonnet.PrettyYamlRenderer = PrettyYamlRenderer.this + def visitKey(index: Int): sjsonnet.PrettyYamlRenderer= { if (empty){ leftHandPrefixOffset = 0 @@ -241,7 +244,7 @@ object PrettyYamlRenderer{ /** * Renders a multi-line string with all indentation and whitespace preserved */ - def writeBlockString(str: String, out: Writer, depth: Int, indent: Int, lineComment: String) = { + def writeBlockString(str: String, out: Writer, depth: Int, indent: Int, lineComment: String): Unit = { val len = str.length() val splits = YamlRenderer.newlinePattern.split(str, -1) val blockOffsetNumeral = if (str.charAt(0) != ' ') "" else indent @@ -278,7 +281,7 @@ object PrettyYamlRenderer{ idealWidth: Int, text: String, split: Boolean = true, - allowUnicode: Boolean = false) = { + allowUnicode: Boolean = false): Unit = { out.write('"') var column = leftHandPrefixOffset + leftIndent + 1 // +1 to include the open quote var start = 0 @@ -351,7 +354,7 @@ object PrettyYamlRenderer{ * * Is used for both naked and single quoted strings. */ - def writeWrappedString(s: String, leftHandPrefixOffset: Int, out: Writer, leftIndent: Int, idealWidth: Int) = { + def writeWrappedString(s: String, leftHandPrefixOffset: Int, out: Writer, leftIndent: Int, idealWidth: Int): Unit = { val tokens0 = s.split(" ", -1) // Consolidate tokens which are separated by more than 1 space, as these @@ -402,10 +405,10 @@ object PrettyYamlRenderer{ * to check for booleans/numbers/nulls/dates/collections/etc., so we use * FastParse to do it in a reasonably manageable and performant manner. */ - def stringNeedsToBeQuoted(str: String) = { + def stringNeedsToBeQuoted(str: String): Boolean = { import fastparse._ import NoWhitespace._ - def yamlPunctuation[_: P] = P( + def yamlPunctuation(implicit p: P[?]) = P( // http://blogs.perl.org/users/tinita/2018/03/strings-in-yaml---to-quote-or-not-to-quote.html StringIn( "!", // ! Tag like !!null @@ -423,7 +426,7 @@ object PrettyYamlRenderer{ " " // leading or trailing empty spaces need quotes to define them ) ) - def yamlKeyword[_: P] = P( + def yamlKeyword(implicit p: P[?]) = P( StringIn( // https://makandracards.com/makandra/24809-yaml-keys-like-yes-or-no-evaluate-to-true-and-false // y|Y|yes|Yes|YES|n|N|no|No|NO @@ -440,17 +443,17 @@ object PrettyYamlRenderer{ ) ) - def digits[_: P] = P( CharsWhileIn("0-9") ) - def yamlFloat[_: P] = P( + def digits(implicit p: P[?]) = P( CharsWhileIn("0-9") ) + def yamlFloat(implicit p: P[?]) = P( (digits.? ~ "." ~ digits | digits ~ ".") ~ (("e" | "E") ~ ("+" | "-").? ~ digits).? ) - def yamlOctalSuffix[_: P] = P( "x" ~ CharIn("1-9a-fA-F") ~ CharsWhileIn("0-9a-fA-F").? ) - def yamlHexSuffix[_: P] = P( "o" ~ CharIn("1-7") ~ CharsWhileIn("0-7").? ) - def yamlOctalHex[_: P] = P( "0" ~ (yamlOctalSuffix | yamlHexSuffix) ) - def yamlNumber0[_: P] = P( ".inf" | yamlFloat | yamlOctalHex | digits ) + def yamlOctalSuffix(implicit p: P[?]) = P( "x" ~ CharIn("1-9a-fA-F") ~ CharsWhileIn("0-9a-fA-F").? ) + def yamlHexSuffix(implicit p: P[?]) = P( "o" ~ CharIn("1-7") ~ CharsWhileIn("0-7").? ) + def yamlOctalHex(implicit p: P[?]) = P( "0" ~ (yamlOctalSuffix | yamlHexSuffix) ) + def yamlNumber0(implicit p: P[?]) = P( ".inf" | yamlFloat | yamlOctalHex | digits ) // Add a `CharIn` lookahead to bail out quickly if something cannot possibly be a number - def yamlNumber[_: P] = P( "-".? ~ yamlNumber0 ) + def yamlNumber(implicit p: P[?]) = P( "-".? ~ yamlNumber0 ) // Strings and numbers aren't the only scalars that YAML can understand. // ISO-formatted date and datetime literals are also parsed. @@ -458,19 +461,19 @@ object PrettyYamlRenderer{ // datetime: 2001-12-15T02:59:43.1Z // datetime_with_spaces: 2001-12-14 21:59:43.10 -5 - def fourDigits[_: P] = P( CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ) - def oneTwoDigits[_: P] = P( CharIn("0-9") ~ CharIn("0-9").? ) - def twoDigits[_: P] = P( CharIn("0-9") ~ CharIn("0-9") ) - def dateTimeSuffix[_: P] = P( + def fourDigits(implicit p: P[?]) = P( CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ) + def oneTwoDigits(implicit p: P[?]) = P( CharIn("0-9") ~ CharIn("0-9").? ) + def twoDigits(implicit p: P[?]) = P( CharIn("0-9") ~ CharIn("0-9") ) + def dateTimeSuffix(implicit p: P[?]) = P( ("T" | " ") ~ twoDigits ~ ":" ~ twoDigits ~ ":" ~ twoDigits ~ ("." ~ digits.?).? ~ ((" " | "Z").? ~ ("-".? ~ oneTwoDigits).?).? ) - def yamlDate[_: P] = P( fourDigits ~ "-" ~ oneTwoDigits ~ "-" ~ oneTwoDigits ~ dateTimeSuffix.? ) + def yamlDate(implicit p: P[?]) = P( fourDigits ~ "-" ~ oneTwoDigits ~ "-" ~ oneTwoDigits ~ dateTimeSuffix.? ) // Not in the YAML, but included to match PyYAML behavior - def yamlTime[_: P] = P( twoDigits ~ ":" ~ twoDigits ) + def yamlTime(implicit p: P[?]) = P( twoDigits ~ ":" ~ twoDigits ) - def parser[_: P] = P( + def parser(implicit p: P[?]) = P( // Use a `&` lookahead to bail out early in the common case, so we don't // need to try parsing times/dates/numbers one by one yamlPunctuation | (&(CharIn(".0-9\\-")) ~ (yamlTime | yamlDate | yamlNumber) | yamlKeyword) ~ End @@ -483,7 +486,7 @@ object PrettyYamlRenderer{ str.charAt(str.length - 1) == ' ' // trailing space needs quotes } - def writeIndentation(out: Writer, n: Int) = { + def writeIndentation(out: Writer, n: Int): Unit = { out.append('\n') var i = n while(i > 0) { diff --git a/sjsonnet/src/sjsonnet/ReadWriter.scala b/sjsonnet/src/sjsonnet/ReadWriter.scala index 46dec93a..cc1a17c7 100644 --- a/sjsonnet/src/sjsonnet/ReadWriter.scala +++ b/sjsonnet/src/sjsonnet/ReadWriter.scala @@ -9,43 +9,43 @@ sealed abstract class ReadWriter[T] { } object ReadWriter{ implicit object StringRead extends ReadWriter[String]{ - def apply(t: Val) = t.asString - def write(pos: Position, t: String) = Val.Str(pos, t) + def apply(t: Val): String = t.asString + def write(pos: Position, t: String): sjsonnet.Val.Str = Val.Str(pos, t) } implicit object BooleanRead extends ReadWriter[Boolean]{ - def apply(t: Val) = t.asBoolean - def write(pos: Position, t: Boolean) = Val.bool(pos, t) + def apply(t: Val): Boolean = t.asBoolean + def write(pos: Position, t: Boolean): sjsonnet.Val.Bool = Val.bool(pos, t) } implicit object IntRead extends ReadWriter[Int]{ - def apply(t: Val) = t.asInt - def write(pos: Position, t: Int) = Val.Num(pos, t) + def apply(t: Val): Int = t.asInt + def write(pos: Position, t: Int): sjsonnet.Val.Num = Val.Num(pos, t) } implicit object LongRead extends ReadWriter[Long]{ - def apply(t: Val) = t.asLong - def write(pos: Position, t: Long) = Val.Num(pos, t) + def apply(t: Val): Long = t.asLong + def write(pos: Position, t: Long): sjsonnet.Val.Num= Val.Num(pos, t) } implicit object DoubleRead extends ReadWriter[Double]{ - def apply(t: Val) = t.asDouble - def write(pos: Position, t: Double) = Val.Num(pos, t) + def apply(t: Val): Double = t.asDouble + def write(pos: Position, t: Double): sjsonnet.Val.Num= Val.Num(pos, t) } implicit object ValRead extends ReadWriter[Val]{ - def apply(t: Val) = t - def write(pos: Position, t: Val) = t + def apply(t: Val): Val = t + def write(pos: Position, t: Val): Val = t } implicit object ObjRead extends ReadWriter[Val.Obj]{ - def apply(t: Val) = t.asObj - def write(pos: Position, t: Val.Obj) = t + def apply(t: Val): Val.Obj = t.asObj + def write(pos: Position, t: Val.Obj): sjsonnet.Val.Obj= t } implicit object ArrRead extends ReadWriter[Val.Arr]{ - def apply(t: Val) = t.asArr - def write(pos: Position, t: Val.Arr) = t + def apply(t: Val): Val.Arr = t.asArr + def write(pos: Position, t: Val.Arr): sjsonnet.Val.Arr= t } implicit object FuncRead extends ReadWriter[Val.Func]{ - def apply(t: Val) = t.asFunc - def write(pos: Position, t: Val.Func) = t + def apply(t: Val): Val.Func = t.asFunc + def write(pos: Position, t: Val.Func): sjsonnet.Val.Func= t } implicit object BuiltinRead extends ReadWriter[Val.Builtin] { - def apply(t: Val) = t.asInstanceOf[Val.Builtin] - def write(pos: Position, t: Val.Builtin) = t + def apply(t: Val): Val.Builtin = t.asInstanceOf[Val.Builtin] + def write(pos: Position, t: Val.Builtin): sjsonnet.Val.Builtin= t } } diff --git a/sjsonnet/src/sjsonnet/Renderer.scala b/sjsonnet/src/sjsonnet/Renderer.scala index 68bb58fe..c407fa01 100644 --- a/sjsonnet/src/sjsonnet/Renderer.scala +++ b/sjsonnet/src/sjsonnet/Renderer.scala @@ -15,7 +15,7 @@ import upickle.core.{ArrVisitor, ObjVisitor} class Renderer(out: Writer = new java.io.StringWriter(), indent: Int = -1) extends BaseCharRenderer(out, indent){ var newlineBuffered = false - override def visitFloat64(d: Double, index: Int) = { + override def visitFloat64(d: Double, index: Int): Writer = { val s = RenderUtils.renderDouble(d) flushBuffer() var i = 0 @@ -28,7 +28,7 @@ class Renderer(out: Writer = new java.io.StringWriter(), flushCharBuilder() out } - override def flushBuffer() = { + override def flushBuffer(): Unit = { if (commaBuffered) { elemBuilder.append(',') if (indent == -1) elemBuilder.append(' ') @@ -46,14 +46,14 @@ class Renderer(out: Writer = new java.io.StringWriter(), newlineBuffered = false commaBuffered = false } - override def visitArray(length: Int, index: Int) = new ArrVisitor[Writer, Writer] { + override def visitArray(length: Int, index: Int): upickle.core.ArrVisitor[java.io.Writer,java.io.Writer]{def subVisitor: sjsonnet.Renderer} = new ArrVisitor[Writer, Writer] { var empty = true flushBuffer() elemBuilder.append('[') newlineBuffered = true depth += 1 - def subVisitor = Renderer.this + def subVisitor: sjsonnet.Renderer = Renderer.this def visitValue(v: Writer, index: Int): Unit = { empty = false flushBuffer() @@ -72,14 +72,14 @@ class Renderer(out: Writer = new java.io.StringWriter(), } } - override def visitObject(length: Int, index: Int) = new ObjVisitor[Writer, Writer] { + override def visitObject(length: Int, index: Int): upickle.core.ObjVisitor[java.io.Writer,java.io.Writer]{def subVisitor: sjsonnet.Renderer; def visitKey(index: Int): sjsonnet.Renderer} = new ObjVisitor[Writer, Writer] { var empty = true flushBuffer() elemBuilder.append('{') newlineBuffered = true depth += 1 - def subVisitor = Renderer.this - def visitKey(index: Int) = Renderer.this + def subVisitor: sjsonnet.Renderer= Renderer.this + def visitKey(index: Int): sjsonnet.Renderer = Renderer.this def visitKeyValue(v: Any): Unit = { empty = false //flushBuffer() @@ -107,7 +107,7 @@ class Renderer(out: Writer = new java.io.StringWriter(), class PythonRenderer(out: Writer = new java.io.StringWriter(), indent: Int = -1) extends BaseCharRenderer(out, indent){ - override def visitNull(index: Int) = { + override def visitNull(index: Int): Writer = { flushBuffer() elemBuilder.ensureLength(4) elemBuilder.appendUnsafe('N') @@ -118,7 +118,7 @@ class PythonRenderer(out: Writer = new java.io.StringWriter(), out } - override def visitFalse(index: Int) = { + override def visitFalse(index: Int): Writer = { flushBuffer() elemBuilder.ensureLength(5) elemBuilder.appendUnsafe('F') @@ -130,7 +130,7 @@ class PythonRenderer(out: Writer = new java.io.StringWriter(), out } - override def visitTrue(index: Int) = { + override def visitTrue(index: Int): Writer = { flushBuffer() elemBuilder.ensureLength(4) elemBuilder.appendUnsafe('T') @@ -141,13 +141,13 @@ class PythonRenderer(out: Writer = new java.io.StringWriter(), out } - override def visitObject(length: Int, index: Int) = new ObjVisitor[Writer, Writer] { + override def visitObject(length: Int, index: Int): upickle.core.ObjVisitor[java.io.Writer,java.io.Writer]{def subVisitor: sjsonnet.PythonRenderer; def visitKey(index: Int): sjsonnet.PythonRenderer} = new ObjVisitor[Writer, Writer] { flushBuffer() elemBuilder.append('{') depth += 1 renderIndent() - def subVisitor = PythonRenderer.this - def visitKey(index: Int) = PythonRenderer.this + def subVisitor: sjsonnet.PythonRenderer = PythonRenderer.this + def visitKey(index: Int): sjsonnet.PythonRenderer = PythonRenderer.this def visitKeyValue(s: Any): Unit = { elemBuilder.ensureLength(2) elemBuilder.append(':') @@ -166,7 +166,7 @@ class PythonRenderer(out: Writer = new java.io.StringWriter(), } } - override def flushBuffer() = { + override def flushBuffer(): Unit = { if (commaBuffered) { commaBuffered = false elemBuilder.ensureLength(2) @@ -183,14 +183,14 @@ case class MaterializeJsonRenderer(indent: Int = 4, escapeUnicode: Boolean = fal private val newLineCharArray = newline.toCharArray private val keyValueSeparatorCharArray = keyValueSeparator.toCharArray - override def visitArray(length: Int, index: Int) = new ArrVisitor[StringWriter, StringWriter] { + override def visitArray(length: Int, index: Int): upickle.core.ArrVisitor[java.io.StringWriter,java.io.StringWriter]{def subVisitor: sjsonnet.MaterializeJsonRenderer} = new ArrVisitor[StringWriter, StringWriter] { flushBuffer() elemBuilder.append('[') depth += 1 // account for rendering differences of whitespaces in ujson and jsonnet manifestJson if (length == 0 && indent != -1) elemBuilder.appendAll(newLineCharArray, newLineCharArray.length) else renderIndent() - def subVisitor = MaterializeJsonRenderer.this + def subVisitor: sjsonnet.MaterializeJsonRenderer = MaterializeJsonRenderer.this def visitValue(v: StringWriter, index: Int): Unit = { flushBuffer() commaBuffered = true @@ -205,14 +205,14 @@ case class MaterializeJsonRenderer(indent: Int = 4, escapeUnicode: Boolean = fal } } - override def visitObject(length: Int, index: Int) = new ObjVisitor[StringWriter, StringWriter] { + override def visitObject(length: Int, index: Int): upickle.core.ObjVisitor[java.io.StringWriter,java.io.StringWriter]{def subVisitor: sjsonnet.MaterializeJsonRenderer; def visitKey(index: Int): sjsonnet.MaterializeJsonRenderer} = new ObjVisitor[StringWriter, StringWriter] { flushBuffer() elemBuilder.append('{') depth += 1 // account for rendering differences of whitespaces in ujson and jsonnet manifestJson if (length == 0 && indent != -1) elemBuilder.appendAll(newLineCharArray, newLineCharArray.length) else renderIndent() - def subVisitor = MaterializeJsonRenderer.this - def visitKey(index: Int) = MaterializeJsonRenderer.this + def subVisitor: sjsonnet.MaterializeJsonRenderer = MaterializeJsonRenderer.this + def visitKey(index: Int): sjsonnet.MaterializeJsonRenderer = MaterializeJsonRenderer.this def visitKeyValue(s: Any): Unit = { elemBuilder.appendAll(keyValueSeparatorCharArray, keyValueSeparatorCharArray.length) } diff --git a/sjsonnet/src/sjsonnet/ScopedExprTransform.scala b/sjsonnet/src/sjsonnet/ScopedExprTransform.scala index 54a6f730..a5cf34a1 100644 --- a/sjsonnet/src/sjsonnet/ScopedExprTransform.scala +++ b/sjsonnet/src/sjsonnet/ScopedExprTransform.scala @@ -11,7 +11,7 @@ class ScopedExprTransform extends ExprTransform { var scope: Scope = emptyScope // Marker for Exprs in the scope that should not be used because they need to be evaluated in a different scope - val dynamicExpr = new Expr { def pos: Position = ???; override def toString = "dynamicExpr" } + val dynamicExpr: Expr = new Expr { def pos: Position = ???; override def toString = "dynamicExpr" } def transform(e: Expr): Expr = e match { case LocalExpr(pos, bindings, returned) => @@ -62,13 +62,13 @@ class ScopedExprTransform extends ExprTransform { } } - protected[this] def transformFieldNameOnly(f: Member.Field): Member.Field = { + protected def transformFieldNameOnly(f: Member.Field): Member.Field = { val x = f.fieldName val x2 = transformFieldName(x) if(x2 eq x) f else f.copy(fieldName = x2) } - protected[this] def transformFieldNoName(f: Member.Field): Member.Field = { + protected def transformFieldNoName(f: Member.Field): Member.Field = { def g = { val y = f.args val z = f.rhs @@ -80,9 +80,9 @@ class ScopedExprTransform extends ExprTransform { else nestedNames(f.args.names)(g) } - override protected[this] def transformField(f: Member.Field): Member.Field = ??? + override protected def transformField(f: Member.Field): Member.Field = ??? - protected[this] def compSpecs[T](a: List[CompSpec], value: () => T): (List[CompSpec], T) = a match { + protected def compSpecs[T](a: List[CompSpec], value: () => T): (List[CompSpec], T) = a match { case (c @ ForSpec(pos, name, cond)) :: cs => val c2 = rec(c).asInstanceOf[ForSpec] nestedWith(c2.name, dynamicExpr) { @@ -97,19 +97,19 @@ class ScopedExprTransform extends ExprTransform { (Nil, value()) } - protected[this] def nestedNew[T](sc: Scope)(f: => T): T = { + protected def nestedNew[T](sc: Scope)(f: => T): T = { val oldScope = scope scope = sc try f finally { scope = oldScope } } - protected[this] def nestedWith[T](n: String, e: Expr)(f: => T): T = + protected def nestedWith[T](n: String, e: Expr)(f: => T): T = nestedNew(new Scope(scope.mappings.updated(n, new ScopedVal(e, scope, scope.size)), scope.size+1))(f) - protected[this] def nestedFileScope[T](fs: FileScope)(f: => T): T = + protected def nestedFileScope[T](fs: FileScope)(f: => T): T = nestedNew(emptyScope)(f) - protected[this] def nestedConsecutiveBindings[T](a: Array[Bind])(f: => Bind => Bind)(g: => T): (Array[Bind], T) = { + protected def nestedConsecutiveBindings[T](a: Array[Bind])(f: => Bind => Bind)(g: => T): (Array[Bind], T) = { if(a == null || a.length == 0) (a, g) else { val oldScope = scope @@ -131,7 +131,7 @@ class ScopedExprTransform extends ExprTransform { } } - protected[this] def nestedBindings[T](a: Array[Bind])(f: => T): T = { + protected def nestedBindings[T](a: Array[Bind])(f: => T): T = { if(a == null || a.length == 0) f else { val newm = a.zipWithIndex.map { case (b, idx) => @@ -142,7 +142,7 @@ class ScopedExprTransform extends ExprTransform { } } - protected[this] def nestedObject[T](self0: Expr, super0: Expr)(f: => T): T = { + protected def nestedObject[T](self0: Expr, super0: Expr)(f: => T): T = { val self = new ScopedVal(self0, scope, scope.size) val sup = new ScopedVal(super0, scope, scope.size+1) val newm = { @@ -152,10 +152,10 @@ class ScopedExprTransform extends ExprTransform { nestedNew(new Scope(newm, scope.size + 2))(f) } - protected[this] def nestedBindings[T](self0: Expr, super0: Expr, a: Array[Bind])(f: => T): T = + protected def nestedBindings[T](self0: Expr, super0: Expr, a: Array[Bind])(f: => T): T = nestedObject(self0, super0)(nestedBindings(a)(f)) - protected[this] def nestedNames[T](a: Array[String])(f: => T): T = { + protected def nestedNames[T](a: Array[String])(f: => T): T = { if(a == null || a.length == 0) f else { val newm = a.zipWithIndex.map { case (n, idx) => (n, new ScopedVal(dynamicExpr, scope, scope.size + idx)) } diff --git a/sjsonnet/src/sjsonnet/StaticOptimizer.scala b/sjsonnet/src/sjsonnet/StaticOptimizer.scala index aa2ecc99..28d86cbb 100644 --- a/sjsonnet/src/sjsonnet/StaticOptimizer.scala +++ b/sjsonnet/src/sjsonnet/StaticOptimizer.scala @@ -42,11 +42,11 @@ class StaticOptimizer( case e @ Id(pos, name) => scope.get(name) match { - case ScopedVal(v: Val with Expr, _, _) => v + case ScopedVal(v: (Val with Expr), _, _) => v case ScopedVal(_, _, idx) => ValidId(pos, name, idx) case null if name == "$std" => std case null if name == "std" => std - case _ => failOrWarn("Unknown variable: "+name, e) + case null => failOrWarn("Unknown variable: "+name, e) } case e @ Self(pos) => @@ -99,7 +99,7 @@ class StaticOptimizer( case _ => false } - override protected[this] def transformFieldName(f: FieldName): FieldName = f match { + override protected def transformFieldName(f: FieldName): FieldName = f match { case FieldName.Dyn(x) => transform(x) match { case x2: Val.Str => @@ -204,7 +204,7 @@ class StaticOptimizer( while(i < target.length) { if(target(i) == null) { params.defaultExprs(i) match { - case v: Val with Expr => target(i) = v + case v: (Val with Expr) => target(i) = v case _ => return null // no default or non-constant } } diff --git a/sjsonnet/src/sjsonnet/Std.scala b/sjsonnet/src/sjsonnet/Std.scala index 3e0f8517..1c4a0c47 100644 --- a/sjsonnet/src/sjsonnet/Std.scala +++ b/sjsonnet/src/sjsonnet/Std.scala @@ -160,7 +160,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. private object Get extends Val.Builtin("get", Array("o", "f", "default", "inc_hidden"), Array(null, null, Val.Null(dummyPos), Val.True(dummyPos))) { - override def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = { + override def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = { val obj = args(0).force.asObj val k = args(1).force.asString val incHidden = args(3).force.asBoolean @@ -175,7 +175,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. } private object MinArray extends Val.Builtin("minArray", Array("arr", "keyF", "onEmpty"), Array(null, Val.False(dummyPos), Val.False(dummyPos))) { - override def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = { + override def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = { val arr = args(0).force.asArr val keyF = args(1).force val onEmpty = args(2) @@ -197,7 +197,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. } private object MaxArray extends Val.Builtin("maxArray", Array("arr", "keyF", "onEmpty"), Array(null, Val.False(dummyPos), Val.False(dummyPos))) { - override def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = { + override def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = { val arr = args(0).force.asArr val keyF = args(1).force val onEmpty = args(2) @@ -482,7 +482,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. case _ => null } private class SpecFrom(from: String) extends Val.Builtin2("strReplaceAll", "str", "to") { - private[this] val pattern = Platform.getPatternFromCache(from) + private val pattern = Platform.getPatternFromCache(from) def evalRhs(str: Lazy, to: Lazy, ev: EvalScope, pos: Position): Val = Val.Str(pos, pattern.matcher(str.force.asString).replaceAll(to.force.asString)) } @@ -506,8 +506,8 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. right: Boolean, functionName: String ) extends Val.Builtin1(functionName, "str") { - private[this] val leftPattern = Platform.getPatternFromCache(getLeadingPattern(chars)) - private[this] val rightPattern = Platform.getPatternFromCache(getTrailingPattern(chars)) + private val leftPattern = Platform.getPatternFromCache(getLeadingPattern(chars)) + private val rightPattern = Platform.getPatternFromCache(getTrailingPattern(chars)) def evalRhs(str: Lazy, ev: EvalScope, pos: Position): Val = { var s = str.force.asString @@ -1652,7 +1652,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. } } - private def existsInSet(ev: EvalScope, pos: Position, keyF: Val, arr: mutable.IndexedSeq[_ <: Lazy], toFind: Val): Boolean = { + private def existsInSet(ev: EvalScope, pos: Position, keyF: Val, arr: mutable.IndexedSeq[? <: Lazy], toFind: Val): Boolean = { val appliedX = keyF match { case keyFFunc: Val.Func => keyFFunc.apply1(toFind, pos.noOffset)(ev) case _ => toFind @@ -1764,7 +1764,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. def builtinWithDefaults[R: ReadWriter](name: String, params: (String, Val.Literal)*) (eval: (Array[Val], Position, EvalScope) => R): (String, Val.Func) = { name -> new Val.Builtin(name, params.map(_._1).toArray, params.map(_._2).toArray) { - def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = + def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = implicitly[ReadWriter[R]].write(pos, eval(args.map(_.force), pos, ev)) } } @@ -1860,7 +1860,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. def getAllKeys(ev: EvalScope, v1: Val.Obj): Array[String] = maybeSortKeys(ev, v1.allKeyNames) - @inline private[this] def maybeSortKeys(ev: EvalScope, keys: Array[String]): Array[String] = + @inline private def maybeSortKeys(ev: EvalScope, keys: Array[String]): Array[String] = if(ev.settings.preserveOrder) keys else keys.sorted def getObjValuesFromKeys(pos: Position, ev: EvalScope, v1: Val.Obj, keys: Array[String]): Val.Arr = diff --git a/sjsonnet/src/sjsonnet/TomlRenderer.scala b/sjsonnet/src/sjsonnet/TomlRenderer.scala index d6cae070..2453208a 100644 --- a/sjsonnet/src/sjsonnet/TomlRenderer.scala +++ b/sjsonnet/src/sjsonnet/TomlRenderer.scala @@ -66,9 +66,9 @@ class TomlRenderer(out: StringWriter = new java.io.StringWriter(), cumulatedInde } override def visitArray(length: Int, index: Int): ArrVisitor[StringWriter, StringWriter] = new ArrVisitor[StringWriter, StringWriter] { - private val inline = length == 0 || depth > 0 - private val newElementIndent = if (inline) "" else cumulatedIndent + indent - private val separator = if (inline && length > 0) " " else if (inline && length == 0) "" else "\n" + private val isInLine = length == 0 || depth > 0 + private val newElementIndent = if (isInLine) "" else cumulatedIndent + indent + private val separator = if (isInLine && length > 0) " " else if (isInLine && length == 0) "" else "\n" private var addComma = false depth += 1 @@ -85,7 +85,7 @@ class TomlRenderer(out: StringWriter = new java.io.StringWriter(), cumulatedInde addComma = false depth -= 1 out.write(separator) - if (!inline) out.write(cumulatedIndent) + if (!isInLine) out.write(cumulatedIndent) out.write("]") flush } diff --git a/sjsonnet/src/sjsonnet/Val.scala b/sjsonnet/src/sjsonnet/Val.scala index 14a7e67e..71dfb184 100644 --- a/sjsonnet/src/sjsonnet/Val.scala +++ b/sjsonnet/src/sjsonnet/Val.scala @@ -16,7 +16,7 @@ import scala.reflect.ClassTag * are all wrapped in [[Lazy]] and only truly evaluated on-demand */ abstract class Lazy { - protected[this] var cached: Val = null + protected var cached: Val = null def compute(): Val final def force: Val = { if(cached == null) cached = compute() @@ -27,7 +27,7 @@ abstract class Lazy { /** * Thread-safe implementation that discards the compute function after initialization. */ -final class LazyWithComputeFunc(@volatile private[this] var computeFunc: () => Val) extends Lazy { +final class LazyWithComputeFunc(@volatile private var computeFunc: () => Val) extends Lazy { def compute(): Val = { val f = computeFunc if (f != null) { // we won the race to initialize @@ -50,16 +50,16 @@ final class LazyWithComputeFunc(@volatile private[this] var computeFunc: () => V */ sealed abstract class Val extends Lazy { cached = this // avoid a megamorphic call to compute() when forcing - final def compute() = this + final def compute(): Val = this def pos: Position def prettyName: String - def cast[T: ClassTag: PrettyNamed] = + def cast[T: ClassTag: PrettyNamed]: T = if (implicitly[ClassTag[T]].runtimeClass.isInstance(this)) this.asInstanceOf[T] else Error.fail("Expected " + implicitly[PrettyNamed[T]].s + ", found " + prettyName) - private[this] def failAs(err: String): Nothing = + private def failAs(err: String): Nothing = Error.fail("Wrong parameter type: expected " + err + ", got " + prettyName) def asString: String = failAs("String") @@ -111,7 +111,7 @@ object Val{ override def asDouble: Double = value } - class Arr(val pos: Position, private val value: Array[_ <: Lazy]) extends Literal { + class Arr(val pos: Position, private val value: Array[? <: Lazy]) extends Literal { def prettyName = "array" override def asArr: Arr = this @@ -212,17 +212,17 @@ object Val{ * computed only if the object has a `super` */ final class Obj(val pos: Position, - private[this] var value0: util.LinkedHashMap[String, Obj.Member], + private var value0: util.LinkedHashMap[String, Obj.Member], static: Boolean, triggerAsserts: Val.Obj => Unit, `super`: Obj, valueCache: util.HashMap[Any, Val] = new util.HashMap[Any, Val](), - private[this] var allKeys: util.LinkedHashMap[String, java.lang.Boolean] = null) extends Literal with Expr.ObjBody { + private var allKeys: util.LinkedHashMap[String, java.lang.Boolean] = null) extends Literal with Expr.ObjBody { var asserting: Boolean = false def getSuper = `super` - private[this] def getValue0: util.LinkedHashMap[String, Obj.Member] = { + private def getValue0: util.LinkedHashMap[String, Obj.Member] = { // value0 is always defined for non-static objects, so if we're computing it here // then that implies that the object is static and therefore valueCache should be // pre-populated and all members should be visible and constant. @@ -349,7 +349,7 @@ object Val{ def mergeMember(l: Val, r: Val, pos: Position) - (implicit evaluator: EvalScope) = { + (implicit evaluator: EvalScope): Literal = { val lStr = l.isInstanceOf[Val.Str] val rStr = r.isInstanceOf[Val.Str] if(lStr || rStr) { @@ -461,7 +461,7 @@ object Val{ override def asFunc: Func = this - def apply(argsL: Array[_ <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = { + def apply(argsL: Array[? <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = { val simple = namedNames == null && params.names.length == argsL.length val funDefFileScope: FileScope = pos match { case null => outerPos.fileScope case p => p.fileScope } //println(s"apply: argsL: ${argsL.length}, namedNames: $namedNames, paramNames: ${params.names.mkString(",")}") @@ -580,7 +580,7 @@ object Val{ evalRhs(scope.bindings, ev, pos) } - def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val + def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val override def apply1(argVal: Lazy, outerPos: Position)(implicit ev: EvalScope): Val = if(params.names.length != 1) apply(Array(argVal), null, outerPos) @@ -624,23 +624,23 @@ object Val{ } abstract class Builtin1(functionName: String, pn1: String, def1: Expr = null) extends Builtin(functionName: String, Array(pn1), if(def1 == null) null else Array(def1)) { - final def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = + final def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = evalRhs(args(0).force, ev, pos) def evalRhs(arg1: Lazy, ev: EvalScope, pos: Position): Val - override def apply(argVals: Array[_ <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = + override def apply(argVals: Array[? <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = if(namedNames == null && argVals.length == 1) evalRhs(argVals(0).force, ev, outerPos) else super.apply(argVals, namedNames, outerPos) } abstract class Builtin2(functionName: String, pn1: String, pn2: String, defs: Array[Expr] = null) extends Builtin(functionName: String, Array(pn1, pn2), defs) { - final def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = + final def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = evalRhs(args(0).force, args(1).force, ev, pos) def evalRhs(arg1: Lazy, arg2: Lazy, ev: EvalScope, pos: Position): Val - override def apply(argVals: Array[_ <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = + override def apply(argVals: Array[? <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = if(namedNames == null && argVals.length == 2) evalRhs(argVals(0).force, argVals(1).force, ev, outerPos) else super.apply(argVals, namedNames, outerPos) @@ -651,24 +651,24 @@ object Val{ } abstract class Builtin3(functionName: String, pn1: String, pn2: String, pn3: String, defs: Array[Expr] = null) extends Builtin(functionName: String, Array(pn1, pn2, pn3), defs) { - final def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = + final def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = evalRhs(args(0).force, args(1).force, args(2).force, ev, pos) def evalRhs(arg1: Lazy, arg2: Lazy, arg3: Lazy, ev: EvalScope, pos: Position): Val - override def apply(argVals: Array[_ <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = + override def apply(argVals: Array[? <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = if(namedNames == null && argVals.length == 3) evalRhs(argVals(0).force, argVals(1).force, argVals(2).force, ev, outerPos) else super.apply(argVals, namedNames, outerPos) } abstract class Builtin4(functionName: String, pn1: String, pn2: String, pn3: String, pn4: String, defs: Array[Expr] = null) extends Builtin(functionName: String, Array(pn1, pn2, pn3, pn4), defs) { - final def evalRhs(args: Array[_ <: Lazy], ev: EvalScope, pos: Position): Val = + final def evalRhs(args: Array[? <: Lazy], ev: EvalScope, pos: Position): Val = evalRhs(args(0).force, args(1).force, args(2).force, args(3).force, ev, pos) def evalRhs(arg1: Lazy, arg2: Lazy, arg3: Lazy, arg4: Lazy, ev: EvalScope, pos: Position): Val - override def apply(argVals: Array[_ <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = + override def apply(argVals: Array[? <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = if(namedNames == null && argVals.length == 4) evalRhs(argVals(0).force, argVals(1).force, argVals(2).force, argVals(3).force, ev, outerPos) else super.apply(argVals, namedNames, outerPos) diff --git a/sjsonnet/src/sjsonnet/ValScope.scala b/sjsonnet/src/sjsonnet/ValScope.scala index d930cbaf..defe8cdd 100644 --- a/sjsonnet/src/sjsonnet/ValScope.scala +++ b/sjsonnet/src/sjsonnet/ValScope.scala @@ -22,7 +22,7 @@ final class ValScope private (val bindings: Array[Lazy]) extends AnyVal { def length: Int = bindings.length def extend(newBindingsF: Array[(Val.Obj, Val.Obj) => Lazy] = null, - newSelf: Val.Obj, newSuper: Val.Obj) = { + newSelf: Val.Obj, newSuper: Val.Obj): ValScope = { val by = if(newBindingsF == null) 2 else newBindingsF.length + 2 val b = Arrays.copyOf(bindings, bindings.length + by) b(bindings.length) = newSelf @@ -35,12 +35,11 @@ final class ValScope private (val bindings: Array[Lazy]) extends AnyVal { i += 1 j += 1 } - b } new ValScope(b) } - def extendSimple(newBindingsV: Array[_ <: Lazy]) = { + def extendSimple(newBindingsV: Array[? <: Lazy]): ValScope = { if(newBindingsV == null || newBindingsV.length == 0) this else { val b = Arrays.copyOf(bindings, bindings.length + newBindingsV.length) @@ -49,24 +48,24 @@ final class ValScope private (val bindings: Array[Lazy]) extends AnyVal { } } - def extendBy(num: Int) = + def extendBy(num: Int): ValScope = if(num == 0) this else new ValScope(Arrays.copyOf(bindings, bindings.length + num)) - def extendSimple(l1: Lazy) = { + def extendSimple(l1: Lazy): ValScope = { val b = Arrays.copyOf(bindings, bindings.length+1) b(bindings.length) = l1 new ValScope(b) } - def extendSimple(l1: Lazy, l2: Lazy) = { + def extendSimple(l1: Lazy, l2: Lazy): ValScope = { val b = Arrays.copyOf(bindings, bindings.length+2) b(bindings.length) = l1 b(bindings.length+1) = l2 new ValScope(b) } - def extendSimple(l1: Lazy, l2: Lazy, l3: Lazy) = { + def extendSimple(l1: Lazy, l2: Lazy, l3: Lazy): ValScope = { val b = Arrays.copyOf(bindings, bindings.length+3) b(bindings.length) = l1 b(bindings.length+1) = l2 @@ -76,6 +75,6 @@ final class ValScope private (val bindings: Array[Lazy]) extends AnyVal { } object ValScope{ - private[this] val emptyArr = new Array[Lazy](0) + private val emptyArr = new Array[Lazy](0) def empty = new ValScope(emptyArr) } diff --git a/sjsonnet/src/sjsonnet/ValVisitor.scala b/sjsonnet/src/sjsonnet/ValVisitor.scala index c732ed22..56cfaa56 100644 --- a/sjsonnet/src/sjsonnet/ValVisitor.scala +++ b/sjsonnet/src/sjsonnet/ValVisitor.scala @@ -14,7 +14,7 @@ class ValVisitor(pos: Position) extends JsVisitor[Val, Val] { self => def visitArray(length: Int, index: Int): ArrVisitor[Val, Val] = new ArrVisitor[Val, Val] { val a = new mutable.ArrayBuilder.ofRef[Lazy] - def subVisitor: Visitor[_, _] = self + def subVisitor: Visitor[?, ?] = self def visitValue(v: Val, index: Int): Unit = a.+=(v) def visitEnd(index: Int): Val = new Val.Arr(pos, a.result()) } @@ -23,8 +23,8 @@ class ValVisitor(pos: Position) extends JsVisitor[Val, Val] { self => val cache = new java.util.HashMap[Any, Val]() val allKeys = new util.LinkedHashMap[String, java.lang.Boolean] var key: String = null - def subVisitor: Visitor[_, _] = self - def visitKey(index: Int) = upickle.core.StringVisitor + def subVisitor: Visitor[?, ?] = self + def visitKey(index: Int): upickle.core.StringVisitor.type = upickle.core.StringVisitor def visitKeyValue(s: Any): Unit = key = s.toString def visitValue(v: Val, index: Int): Unit = { cache.put(key, v) diff --git a/sjsonnet/src/sjsonnet/YamlRenderer.scala b/sjsonnet/src/sjsonnet/YamlRenderer.scala index c074579c..a801fb95 100644 --- a/sjsonnet/src/sjsonnet/YamlRenderer.scala +++ b/sjsonnet/src/sjsonnet/YamlRenderer.scala @@ -30,7 +30,7 @@ class YamlRenderer(_out: StringWriter = new java.io.StringWriter(), indentArrayI elemBuilder.writeOutToIfLongerThan(_out, if (depth <= 0 || topLevel) 0 else 1000) } - private[this] def appendString(s: String): Unit = { + private def appendString(s: String): Unit = { val len = s.length var i = 0 elemBuilder.ensureLength(len) @@ -175,10 +175,10 @@ object YamlRenderer{ private val yamlReserved = Set("true", "false", "null", "yes", "no", "on", "off", "y", "n", ".nan", "+.inf", "-.inf", ".inf", "null", "-", "---", "''") private val yamlTimestampPattern = Platform.getPatternFromCache("^(?:[0-9]*-){2}[0-9]*$") - private val yamlBinaryPattern = Platform.getPatternFromCache("^[-+]?0b[0-1_]+$") - private val yamlHexPattern = Platform.getPatternFromCache("[-+]?0x[0-9a-fA-F_]+") - private val yamlFloatPattern = Platform.getPatternFromCache( "^-?([0-9_]*)*(\\.[0-9_]*)?(e[-+][0-9_]+)?$" ) - private val yamlIntPattern = Platform.getPatternFromCache("^[-+]?[0-9_]+$") + private val yamlBinaryPattern = Platform.getPatternFromCache("^[-+]?0b[0-1?]+$") + private val yamlHexPattern = Platform.getPatternFromCache("[-+]?0x[0-9a-fA-F?]+") + private val yamlFloatPattern = Platform.getPatternFromCache( "^-?([0-9?]*)*(\\.[0-9?]*)?(e[-+][0-9?]+)?$" ) + private val yamlIntPattern = Platform.getPatternFromCache("^[-+]?[0-9?]+$") private def isSafeBareKey(k: String) = { val l = k.toLowerCase diff --git a/sjsonnet/test/src-jvm-native/ErrorTests.scala b/sjsonnet/test/src-jvm-native/ErrorTests.scala index 2f521750..30c401e3 100644 --- a/sjsonnet/test/src-jvm-native/ErrorTests.scala +++ b/sjsonnet/test/src-jvm-native/ErrorTests.scala @@ -1,9 +1,10 @@ import sjsonnet._ import utest._ +import ujson.Value object ErrorTests extends TestSuite{ - val testSuiteRoot = os.pwd / "sjsonnet" / "test" / "resources" - def eval(p: os.Path, noStaticErrors: Boolean) = { + val testSuiteRoot: os.Path = os.pwd / "sjsonnet" / "test" / "resources" + def eval(p: os.Path, noStaticErrors: Boolean): Either[String,Value] = { val out = new StringBuffer() val interp = new Interpreter( Map(), @@ -16,13 +17,13 @@ object ErrorTests extends TestSuite{ ) interp.interpret(os.read(p), OsPath(p)).left.map(s => out.toString + s) } - def check(expected: String, noStaticErrors: Boolean = false, suite: String = "test_suite")(implicit tp: utest.framework.TestPath) = { + def check(expected: String, noStaticErrors: Boolean = false, suite: String = "test_suite")(implicit tp: utest.framework.TestPath): Unit = { val res = eval(testSuiteRoot / suite / s"error.${tp.value.mkString(".")}.jsonnet", noStaticErrors) assert(res == Left(expected)) } - val tests = Tests{ + val tests: Tests = Tests{ test("01") - check( """sjsonnet.Error: foo | at [Error].(sjsonnet/test/resources/test_suite/error.01.jsonnet:17:29) diff --git a/sjsonnet/test/src-jvm-native/PrettyYamlRendererTests.scala b/sjsonnet/test/src-jvm-native/PrettyYamlRendererTests.scala index b1f5a855..3f315552 100644 --- a/sjsonnet/test/src-jvm-native/PrettyYamlRendererTests.scala +++ b/sjsonnet/test/src-jvm-native/PrettyYamlRendererTests.scala @@ -2,8 +2,8 @@ import sjsonnet._ import utest._ object PrettyYamlRendererTests extends TestSuite{ - val testSuiteRoot = os.pwd / "sjsonnet" / "test" / "resources" / "test_suite" - def eval(path: os.Path, comments: Boolean) = { + val testSuiteRoot: os.Path = os.pwd / "sjsonnet" / "test" / "resources" / "test_suite" + def eval(path: os.Path, comments: Boolean): String = { var currentPos: Position = null val interp = new Interpreter( Map(), @@ -23,8 +23,8 @@ object PrettyYamlRendererTests extends TestSuite{ ) res.right.get.toString } - val nontrivial = os.pwd / "sjsonnet" / "test" / "resources" / "nontrivial" - def tests = Tests{ + val nontrivial: os.Path = os.pwd / "sjsonnet" / "test" / "resources" / "nontrivial" + def tests: Tests = Tests{ test("nocomments"){ eval(nontrivial / "mixins.jsonnet", comments = false) ==> os.read(nontrivial / "mixins.golden.yaml") diff --git a/sjsonnet/test/src-jvm/sjsonnet/BufferedRandomAccessFileTests.scala b/sjsonnet/test/src-jvm/sjsonnet/BufferedRandomAccessFileTests.scala index b1ff0322..2952d350 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/BufferedRandomAccessFileTests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/BufferedRandomAccessFileTests.scala @@ -21,11 +21,11 @@ object BufferedRandomAccessFileTests extends TestSuite { // Test content and large test content val testContent = "Hello, World! This is a test file with various content to thoroughly test the BufferedRandomAccessFile." - val largeTestContent = Random.alphanumeric.take(100000).mkString // 100k characters - val tempFile = createTempFile(testContent) - val largeTempFile = createTempFile(largeTestContent) + val largeTestContent: String = Random.alphanumeric.take(100000).mkString // 100k characters + val tempFile: File = createTempFile(testContent) + val largeTempFile: File = createTempFile(largeTestContent) - val tests = Tests { + val tests: Tests = Tests { test("readChar") { val bufferedFile = new BufferedRandomAccessFile(tempFile.getAbsolutePath, 10) diff --git a/sjsonnet/test/src-jvm/sjsonnet/ErrorTestsJvmOnly.scala b/sjsonnet/test/src-jvm/sjsonnet/ErrorTestsJvmOnly.scala index 4242198c..ae895124 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/ErrorTestsJvmOnly.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/ErrorTestsJvmOnly.scala @@ -1,10 +1,11 @@ package sjsonnet import utest._ +import ujson.Value object ErrorTestsJvmOnly extends TestSuite { - val testSuiteRoot = os.pwd / "sjsonnet" / "test" / "resources" / "test_suite" - def eval(p: os.Path) = { + val testSuiteRoot: os.Path = os.pwd / "sjsonnet" / "test" / "resources" / "test_suite" + def eval(p: os.Path): Either[String,Value] = { val interp = new Interpreter( Map(), Map(), @@ -14,13 +15,13 @@ object ErrorTestsJvmOnly extends TestSuite { ) interp.interpret(os.read(p), OsPath(p)) } - def check(expected: String)(implicit tp: utest.framework.TestPath) = { + def check(expected: String)(implicit tp: utest.framework.TestPath): Unit = { val res = eval(testSuiteRoot / s"error.${tp.value.mkString(".")}.jsonnet") assert(res == Left(expected)) } - val tests = Tests{ + val tests: Tests = Tests{ test("array_recursive_manifest") - check( """sjsonnet.Error: Stackoverflow while materializing, possibly due to recursive value | at .(sjsonnet/test/resources/test_suite/error.array_recursive_manifest.jsonnet:17:12) diff --git a/sjsonnet/test/src-jvm/sjsonnet/FileTests.scala b/sjsonnet/test/src-jvm/sjsonnet/FileTests.scala index 85bac137..b9611609 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/FileTests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/FileTests.scala @@ -1,10 +1,11 @@ package sjsonnet import utest._ +import ujson.Value object FileTests extends TestSuite{ - val testSuiteRoot = os.pwd / "sjsonnet" / "test" / "resources" / "test_suite" - def eval(p: os.Path) = { + val testSuiteRoot: os.Path = os.pwd / "sjsonnet" / "test" / "resources" / "test_suite" + def eval(p: os.Path): Either[String,Value] = { val interp = new Interpreter( Map("var1" -> "\"test\"", "var2" -> """local f(a, b) = {[a]: b, "y": 2}; f("x", 1)"""), Map("var1" -> "\"test\"", "var2" -> """{"x": 1, "y": 2}"""), @@ -14,20 +15,20 @@ object FileTests extends TestSuite{ ) interp.interpret(os.read(p), OsPath(p)) } - def check(expected: ujson.Value = ujson.True)(implicit tp: utest.framework.TestPath) = { + def check(expected: ujson.Value = ujson.True)(implicit tp: utest.framework.TestPath): Either[String,Value] = { val res = eval(testSuiteRoot / s"${tp.value.last}.jsonnet") assert(res == Right(expected)) res } - def checkFail(expected: String)(implicit tp: utest.framework.TestPath) = { + def checkFail(expected: String)(implicit tp: utest.framework.TestPath): Either[String,Value] = { val res = eval(testSuiteRoot / s"${tp.value.last}.jsonnet") assert(res == Left(expected)) res } - def checkGolden()(implicit tp: utest.framework.TestPath) = { + def checkGolden()(implicit tp: utest.framework.TestPath): Either[String,Value] = { check(ujson.read(os.read(testSuiteRoot / s"${tp.value.last}.jsonnet.golden"))) } - def tests = Tests{ + def tests: Tests = Tests{ test("arith_bool") - check() test("arith_float") - check() test("arith_string") - check() diff --git a/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala b/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala index 08ec7c0b..85e4f1dc 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala @@ -7,9 +7,9 @@ import java.util.Arrays object MainTests extends TestSuite { - val testSuiteRoot = os.pwd / "sjsonnet" / "test" / "resources" + val testSuiteRoot: os.Path = os.pwd / "sjsonnet" / "test" / "resources" // stdout mode uses println so it has an extra platform-specific line separator at the end - val eol = System.getProperty("line.separator") + val eol: String = System.getProperty("line.separator") val tests = Tests { // Compare writing to stdout with writing to a file diff --git a/sjsonnet/test/src-jvm/sjsonnet/StdGzipTests.scala b/sjsonnet/test/src-jvm/sjsonnet/StdGzipTests.scala index c08d890a..c617dbb4 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/StdGzipTests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/StdGzipTests.scala @@ -4,7 +4,7 @@ import sjsonnet.TestUtils.eval import utest._ object StdGzipTests extends TestSuite { - val tests = Tests { + val tests: Tests = Tests { test("gzip"){ eval("""std.gzip([1, 2])""") ==> ujson.Str(Runtime.version().feature() match { // https://bugs.openjdk.org/browse/JDK-8244706 diff --git a/sjsonnet/test/src-jvm/sjsonnet/StdMd5Tests.scala b/sjsonnet/test/src-jvm/sjsonnet/StdMd5Tests.scala index f6ade904..8caa1c7b 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/StdMd5Tests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/StdMd5Tests.scala @@ -5,7 +5,7 @@ import utest._ object StdMd5Tests extends TestSuite { - def tests = Tests { + def tests: Tests = Tests { test { eval("std.md5('')") ==> ujson.Str("d41d8cd98f00b204e9800998ecf8427e") } diff --git a/sjsonnet/test/src-jvm/sjsonnet/StdXzTests.scala b/sjsonnet/test/src-jvm/sjsonnet/StdXzTests.scala index 75fa7e1e..784a66fc 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/StdXzTests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/StdXzTests.scala @@ -4,7 +4,7 @@ import utest._ import TestUtils.eval object StdXzTests extends TestSuite { - val tests = Tests { + val tests: Tests = Tests { test("xz"){ eval("""std.xz([1, 2])""") ==> ujson.Str("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABAQIAAADRC9qlUgJ94gABGgLcLqV+H7bzfQEAAAAABFla") eval("""std.xz("hi")""") ==> ujson.Str("/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABaGkAAAD+qTgRvMqlSAABGgLcLqV+H7bzfQEAAAAABFla") diff --git a/sjsonnet/test/src-jvm/sjsonnet/XxHash64Tests.scala b/sjsonnet/test/src-jvm/sjsonnet/XxHash64Tests.scala index 60201a95..924c15a3 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/XxHash64Tests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/XxHash64Tests.scala @@ -10,7 +10,7 @@ import utest._ import TestUtils.eval object XxHash64Tests extends TestSuite { - val tests = Tests { + val tests: Tests = Tests { test("xxhash") { for (sizeInKb <- List(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024)) { @@ -24,7 +24,7 @@ object XxHash64Tests extends TestSuite { memoryLimitBytes = Int.MaxValue, cacheThresholdBytes = 0) // They should agree - val hash = cachedFile.contentHash + val hash = cachedFile.contentHash() assert(xxHash64Result == hash) } } diff --git a/sjsonnet/test/src/sjsonnet/DecimalFormatTests.scala b/sjsonnet/test/src/sjsonnet/DecimalFormatTests.scala index b6191ffb..e5d53e51 100644 --- a/sjsonnet/test/src/sjsonnet/DecimalFormatTests.scala +++ b/sjsonnet/test/src/sjsonnet/DecimalFormatTests.scala @@ -2,7 +2,7 @@ package sjsonnet import utest._ object DecimalFormatTests extends TestSuite{ - def format(pattern: String, n: Double) = { + def format(pattern: String, n: Double): String = { val (wholeStr, fracStrOpt, expStrOpt) = pattern.split("\\.", -1).map(_.split('E')) match{ case Array(Array(wholeStr: String)) => (wholeStr, None, None) @@ -19,7 +19,7 @@ object DecimalFormatTests extends TestSuite{ val expLengthOpt = expStrOpt.map(_.length) sjsonnet.DecimalFormat.format(fracLengthOpt, expLengthOpt, n) } - def tests = Tests{ + def tests: Tests = Tests{ test - {format("0.000000E00",910) ==> "9.100000E02"} test - {format("0E00",910) ==> "9E02"} diff --git a/sjsonnet/test/src/sjsonnet/EvaluatorTests.scala b/sjsonnet/test/src/sjsonnet/EvaluatorTests.scala index 8c8958f5..f394fe12 100644 --- a/sjsonnet/test/src/sjsonnet/EvaluatorTests.scala +++ b/sjsonnet/test/src/sjsonnet/EvaluatorTests.scala @@ -5,7 +5,7 @@ import TestUtils.{eval, eval0, evalErr} object EvaluatorTests extends TestSuite{ - def tests = Tests{ + def tests: Tests = Tests{ test("arithmetic") { eval("1 + 2 + 3") ==> ujson.Num(6) eval("1 + 2 * 3") ==> ujson.Num(7) diff --git a/sjsonnet/test/src/sjsonnet/FormatTests.scala b/sjsonnet/test/src/sjsonnet/FormatTests.scala index 1ba6357d..5a2e3bb4 100644 --- a/sjsonnet/test/src/sjsonnet/FormatTests.scala +++ b/sjsonnet/test/src/sjsonnet/FormatTests.scala @@ -6,12 +6,12 @@ import utest._ object FormatTests extends TestSuite{ val dummyPos = new Position(new FileScope(DummyPath("(unknown)")), -1) - def check(fmt: String, jsonStr: String, expected: String) = { + def check(fmt: String, jsonStr: String, expected: String): Unit = { val json = ujson.read(jsonStr) val formatted = Format.format(fmt, Materializer.reverse(null, json), dummyPos)( new EvalScope{ def tailstrict: Boolean = false - def extVars = _ => None + def extVars: String => Option[sjsonnet.Expr] = _ => None def wd: Path = DummyPath() def visitExpr(expr: Expr)(implicit scope: ValScope): Val = ??? def materialize(v: Val): Value = ??? @@ -25,7 +25,7 @@ object FormatTests extends TestSuite{ assert(formatted == expected) } - def checkErr(fmt: String, jsonStr: String, expectedErr: String) = { + def checkErr(fmt: String, jsonStr: String, expectedErr: String): Unit = { try { check(fmt, jsonStr, "") } catch { @@ -34,7 +34,7 @@ object FormatTests extends TestSuite{ } } - def tests = Tests{ + def tests: Tests = Tests{ test("hash"){ // # check("No format chars\n", """[]""", "No format chars\n") diff --git a/sjsonnet/test/src/sjsonnet/NonBooleanExprTests.scala b/sjsonnet/test/src/sjsonnet/NonBooleanExprTests.scala index cf0b012b..07a40bc0 100644 --- a/sjsonnet/test/src/sjsonnet/NonBooleanExprTests.scala +++ b/sjsonnet/test/src/sjsonnet/NonBooleanExprTests.scala @@ -3,7 +3,7 @@ package sjsonnet import utest._ import TestUtils.eval object NonBooleanExprTests extends TestSuite{ - def tests = Tests{ + def tests: Tests = Tests{ test("nonBooleanExpr") { eval("local boo(x) = true; [x for x in [1,2,3] if boo(x)]").toString() ==> "[1,2,3]" eval("[x for x in [1,2,3] if x < 0]").toString() ==> "[]" diff --git a/sjsonnet/test/src/sjsonnet/OldRenderer.scala b/sjsonnet/test/src/sjsonnet/OldRenderer.scala index 33de0d9d..a08c151c 100644 --- a/sjsonnet/test/src/sjsonnet/OldRenderer.scala +++ b/sjsonnet/test/src/sjsonnet/OldRenderer.scala @@ -14,13 +14,13 @@ import upickle.core.{ArrVisitor, ObjVisitor} class OldRenderer(out: Writer = new java.io.StringWriter(), indent: Int = -1) extends BaseRenderer(out, indent){ var newlineBuffered = false - override def visitFloat64(d: Double, index: Int) = { + override def visitFloat64(d: Double, index: Int): Writer = { flushBuffer() out.append(RenderUtils.renderDouble(d)) out } override val colonSnippet = ": " - override def flushBuffer() = { + override def flushBuffer(): Unit = { if (commaBuffered) { if (indent == -1) out.append(", ") else out.append(',') @@ -38,14 +38,14 @@ class OldRenderer(out: Writer = new java.io.StringWriter(), newlineBuffered = false commaBuffered = false } - override def visitArray(length: Int, index: Int) = new ArrVisitor[Writer, Writer] { + override def visitArray(length: Int, index: Int): upickle.core.ArrVisitor[java.io.Writer,java.io.Writer]{def subVisitor: sjsonnet.OldRenderer} = new ArrVisitor[Writer, Writer] { var empty = true flushBuffer() out.append('[') newlineBuffered = true depth += 1 - def subVisitor = OldRenderer.this + def subVisitor: sjsonnet.OldRenderer = OldRenderer.this def visitValue(v: Writer, index: Int): Unit = { empty = false flushBuffer() @@ -63,14 +63,14 @@ class OldRenderer(out: Writer = new java.io.StringWriter(), } } - override def visitObject(length: Int, index: Int) = new ObjVisitor[Writer, Writer] { + override def visitObject(length: Int, index: Int): upickle.core.ObjVisitor[java.io.Writer,java.io.Writer]{def subVisitor: sjsonnet.OldRenderer; def visitKey(index: Int): sjsonnet.OldRenderer} = new ObjVisitor[Writer, Writer] { var empty = true flushBuffer() out.append('{') newlineBuffered = true depth += 1 - def subVisitor = OldRenderer.this - def visitKey(index: Int) = OldRenderer.this + def subVisitor: sjsonnet.OldRenderer = OldRenderer.this + def visitKey(index: Int): sjsonnet.OldRenderer= OldRenderer.this def visitKeyValue(v: Any): Unit = { empty = false flushBuffer() @@ -96,26 +96,26 @@ class OldRenderer(out: Writer = new java.io.StringWriter(), class OldPythonRenderer(out: Writer = new java.io.StringWriter(), indent: Int = -1) extends BaseRenderer(out, indent){ - override def visitNull(index: Int) = { + override def visitNull(index: Int): Writer = { flushBuffer() out.append("None") out } - override def visitFalse(index: Int) = { + override def visitFalse(index: Int): Writer = { flushBuffer() out.append("False") out } - override def visitTrue(index: Int) = { + override def visitTrue(index: Int): Writer = { flushBuffer() out.append("True") out } override val colonSnippet = ": " - override def flushBuffer() = { + override def flushBuffer(): Unit = { if (commaBuffered) { commaBuffered = false out.append(", ") diff --git a/sjsonnet/test/src/sjsonnet/OldYamlRenderer.scala b/sjsonnet/test/src/sjsonnet/OldYamlRenderer.scala index e698d8b3..6adf19a9 100644 --- a/sjsonnet/test/src/sjsonnet/OldYamlRenderer.scala +++ b/sjsonnet/test/src/sjsonnet/OldYamlRenderer.scala @@ -13,7 +13,7 @@ class OldYamlRenderer(out: StringWriter = new java.io.StringWriter(), indentArra var topLevel = true - val outBuffer = out.getBuffer() + val outBuffer: StringBuffer = out.getBuffer() override def visitString(s: CharSequence, index: Int): StringWriter = { flushBuffer() @@ -35,13 +35,13 @@ class OldYamlRenderer(out: StringWriter = new java.io.StringWriter(), indentArra out } } - override def visitFloat64(d: Double, index: Int) = { + override def visitFloat64(d: Double, index: Int): StringWriter = { flushBuffer() out.append(RenderUtils.renderDouble(d)) out } override val colonSnippet = ": " - override def flushBuffer() = { + override def flushBuffer(): Unit = { if (newlineBuffered) { // drop space between colon and newline if (outBuffer.length() > 1 && outBuffer.charAt(outBuffer.length() - 1) == ' ') { @@ -54,7 +54,7 @@ class OldYamlRenderer(out: StringWriter = new java.io.StringWriter(), indentArra newlineBuffered = false dashBuffered = false } - override def visitArray(length: Int, index: Int) = new ArrVisitor[StringWriter, StringWriter] { + override def visitArray(length: Int, index: Int): upickle.core.ArrVisitor[java.io.StringWriter,java.io.StringWriter]{def subVisitor: sjsonnet.OldYamlRenderer} = new ArrVisitor[StringWriter, StringWriter] { var empty = true flushBuffer() @@ -69,7 +69,7 @@ class OldYamlRenderer(out: StringWriter = new java.io.StringWriter(), indentArra if (dedentInObject) depth -= 1 dashBuffered = true - def subVisitor = OldYamlRenderer.this + def subVisitor: sjsonnet.OldYamlRenderer = OldYamlRenderer.this def visitValue(v: StringWriter, index: Int): Unit = { empty = false flushBuffer() @@ -84,7 +84,7 @@ class OldYamlRenderer(out: StringWriter = new java.io.StringWriter(), indentArra out } } - override def visitObject(length: Int, index: Int) = new ObjVisitor[StringWriter, StringWriter] { + override def visitObject(length: Int, index: Int): upickle.core.ObjVisitor[java.io.StringWriter,java.io.StringWriter]{def subVisitor: sjsonnet.OldYamlRenderer; def visitKey(index: Int): sjsonnet.OldYamlRenderer} = new ObjVisitor[StringWriter, StringWriter] { var empty = true flushBuffer() if (!topLevel) depth += 1 @@ -92,8 +92,8 @@ class OldYamlRenderer(out: StringWriter = new java.io.StringWriter(), indentArra if (afterKey) newlineBuffered = true - def subVisitor = OldYamlRenderer.this - def visitKey(index: Int) = OldYamlRenderer.this + def subVisitor: sjsonnet.OldYamlRenderer = OldYamlRenderer.this + def visitKey(index: Int): sjsonnet.OldYamlRenderer = OldYamlRenderer.this def visitKeyValue(s: Any): Unit = { empty = false flushBuffer() diff --git a/sjsonnet/test/src/sjsonnet/ParserTests.scala b/sjsonnet/test/src/sjsonnet/ParserTests.scala index 5fb5668b..260e17d6 100644 --- a/sjsonnet/test/src/sjsonnet/ParserTests.scala +++ b/sjsonnet/test/src/sjsonnet/ParserTests.scala @@ -7,11 +7,11 @@ import fastparse.Parsed import Val.{Num, True} import sjsonnet.Expr.FieldName.Fixed object ParserTests extends TestSuite{ - def parse(s: String, strictImportSyntax: Boolean = false) = fastparse.parse(s, new Parser(null, strictImportSyntax, mutable.HashMap.empty, mutable.HashMap.empty).document(_)).get.value._1 - def parseErr(s: String, strictImportSyntax: Boolean = false) = fastparse.parse(s, new Parser(null, strictImportSyntax, mutable.HashMap.empty, mutable.HashMap.empty).document(_), verboseFailures = true).asInstanceOf[Parsed.Failure].msg + def parse(s: String, strictImportSyntax: Boolean = false): Expr = fastparse.parse(s, new Parser(null, strictImportSyntax, mutable.HashMap.empty, mutable.HashMap.empty).document(_)).get.value._1 + def parseErr(s: String, strictImportSyntax: Boolean = false): String = fastparse.parse(s, new Parser(null, strictImportSyntax, mutable.HashMap.empty, mutable.HashMap.empty).document(_), verboseFailures = true).asInstanceOf[Parsed.Failure].msg val dummyFS = new FileScope(null) def pos(i: Int) = new Position(dummyFS, i) - def tests = Tests{ + def tests: Tests = Tests{ test("hello") { parse("true") ==> True(pos(0)) diff --git a/sjsonnet/test/src/sjsonnet/PreserveOrderTests.scala b/sjsonnet/test/src/sjsonnet/PreserveOrderTests.scala index 4439adf4..c659fb93 100644 --- a/sjsonnet/test/src/sjsonnet/PreserveOrderTests.scala +++ b/sjsonnet/test/src/sjsonnet/PreserveOrderTests.scala @@ -4,7 +4,7 @@ import utest._ import TestUtils.{eval, evalErr} object PreserveOrderTests extends TestSuite { - def tests = Tests { + def tests: Tests = Tests { test("preserveOrder") { eval( """{ diff --git a/sjsonnet/test/src/sjsonnet/RendererTests.scala b/sjsonnet/test/src/sjsonnet/RendererTests.scala index 64a6a401..71002be1 100644 --- a/sjsonnet/test/src/sjsonnet/RendererTests.scala +++ b/sjsonnet/test/src/sjsonnet/RendererTests.scala @@ -4,7 +4,7 @@ import sjsonnet.Expr._ import utest._ object RendererTests extends TestSuite{ - def tests = Tests { + def tests: Tests = Tests { test("hello") { ujson.transform(ujson.Arr(ujson.Num(1), ujson.Num(2)), new Renderer()).toString ==> "[1, 2]" diff --git a/sjsonnet/test/src/sjsonnet/Std0150FunctionsTests.scala b/sjsonnet/test/src/sjsonnet/Std0150FunctionsTests.scala index 025e4fb2..1a33251b 100644 --- a/sjsonnet/test/src/sjsonnet/Std0150FunctionsTests.scala +++ b/sjsonnet/test/src/sjsonnet/Std0150FunctionsTests.scala @@ -4,7 +4,7 @@ import utest._ import TestUtils.{eval, evalErr} object Std0150FunctionsTests extends TestSuite { - def tests = Tests { + def tests: Tests = Tests { test("stdClamp") { eval("std.clamp(-3, 0, 5)") ==> ujson.Num(0) eval("std.clamp(4, 0, 5)") ==> ujson.Num(4) diff --git a/sjsonnet/test/src/sjsonnet/StdFlatMapTests.scala b/sjsonnet/test/src/sjsonnet/StdFlatMapTests.scala index 9667fe07..65f428ad 100644 --- a/sjsonnet/test/src/sjsonnet/StdFlatMapTests.scala +++ b/sjsonnet/test/src/sjsonnet/StdFlatMapTests.scala @@ -4,7 +4,7 @@ import utest._ import TestUtils.{eval, evalErr} object StdFlatMapTests extends TestSuite { - def tests = Tests { + def tests: Tests = Tests { test("stdFlatMap") { eval("std.flatMap(function(x) [x, x], [1, 2, 3])") ==> ujson.Arr(1, 1, 2, 2, 3, 3) eval("std.flatMap(function(x) if x == 2 then [] else [x], [1, 2, 3])") ==> ujson.Arr(1, 3) diff --git a/sjsonnet/test/src/sjsonnet/StdMergePatchTests.scala b/sjsonnet/test/src/sjsonnet/StdMergePatchTests.scala index 69426535..ef837902 100644 --- a/sjsonnet/test/src/sjsonnet/StdMergePatchTests.scala +++ b/sjsonnet/test/src/sjsonnet/StdMergePatchTests.scala @@ -6,7 +6,7 @@ object StdMergePatchTests extends TestSuite { // These test cases' behavior matches v0.20.0 of google/jsonnet and google/go-jsonnet. - def tests = Tests { + def tests: Tests = Tests { test("top-level merging of non-objects") { // Both target and patch are non-objects, so patch wins: diff --git a/sjsonnet/test/src/sjsonnet/StdStripCharsTests.scala b/sjsonnet/test/src/sjsonnet/StdStripCharsTests.scala index 8cc7be7e..00851094 100644 --- a/sjsonnet/test/src/sjsonnet/StdStripCharsTests.scala +++ b/sjsonnet/test/src/sjsonnet/StdStripCharsTests.scala @@ -4,7 +4,7 @@ import sjsonnet.TestUtils.eval import utest._ object StdStripCharsTests extends TestSuite { - def tests = Tests { + def tests: Tests = Tests { test("stdRStripChars") { eval("std.rstripChars(\" test test test \", \" \")").toString() ==> """" test test test"""" eval("std.rstripChars(\"aaabbbbcccc\", \"ac\")").toString() ==> """"aaabbbb"""" diff --git a/sjsonnet/test/src/sjsonnet/StdWithKeyFTests.scala b/sjsonnet/test/src/sjsonnet/StdWithKeyFTests.scala index 4a53f3ac..5c69fba4 100644 --- a/sjsonnet/test/src/sjsonnet/StdWithKeyFTests.scala +++ b/sjsonnet/test/src/sjsonnet/StdWithKeyFTests.scala @@ -4,7 +4,7 @@ import utest._ import TestUtils.{eval, evalErr} object StdWithKeyFTests extends TestSuite { - def tests = Tests { + def tests: Tests = Tests { test("stdSetMemberWithKeyF") { eval("std.setMember(\"a\", std.set([\"a\", \"b\", \"c\"], function(x) x), function(x) x)") ==> ujson.True eval("std.setMember(\"a\", std.set([\"a\", \"b\", \"c\"]))") ==> ujson.True diff --git a/sjsonnet/test/src/sjsonnet/YamlRendererTests.scala b/sjsonnet/test/src/sjsonnet/YamlRendererTests.scala index ad6aab07..9a25f12c 100644 --- a/sjsonnet/test/src/sjsonnet/YamlRendererTests.scala +++ b/sjsonnet/test/src/sjsonnet/YamlRendererTests.scala @@ -3,7 +3,7 @@ package sjsonnet import utest._ object YamlRendererTests extends TestSuite{ - def tests = Tests { + def tests: Tests = Tests { test("empty") { ujson.transform(ujson.Arr(), new YamlRenderer()).toString ==> "[]" ujson.transform(ujson.Obj(), new YamlRenderer()).toString ==> "{}" From b167eaf319256d7ba9fc9a2e5145bce218078af2 Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Sat, 5 Apr 2025 16:57:26 +0200 Subject: [PATCH 02/13] Fix scala migration thingy - tests passes --- sjsonnet/src/sjsonnet/YamlRenderer.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sjsonnet/src/sjsonnet/YamlRenderer.scala b/sjsonnet/src/sjsonnet/YamlRenderer.scala index a801fb95..9d2b13eb 100644 --- a/sjsonnet/src/sjsonnet/YamlRenderer.scala +++ b/sjsonnet/src/sjsonnet/YamlRenderer.scala @@ -175,10 +175,10 @@ object YamlRenderer{ private val yamlReserved = Set("true", "false", "null", "yes", "no", "on", "off", "y", "n", ".nan", "+.inf", "-.inf", ".inf", "null", "-", "---", "''") private val yamlTimestampPattern = Platform.getPatternFromCache("^(?:[0-9]*-){2}[0-9]*$") - private val yamlBinaryPattern = Platform.getPatternFromCache("^[-+]?0b[0-1?]+$") - private val yamlHexPattern = Platform.getPatternFromCache("[-+]?0x[0-9a-fA-F?]+") - private val yamlFloatPattern = Platform.getPatternFromCache( "^-?([0-9?]*)*(\\.[0-9?]*)?(e[-+][0-9?]+)?$" ) - private val yamlIntPattern = Platform.getPatternFromCache("^[-+]?[0-9?]+$") + private val yamlBinaryPattern = Platform.getPatternFromCache("^[-+]?0b[0-1_]+$") + private val yamlHexPattern = Platform.getPatternFromCache("[-+]?0x[0-9a-fA-F_]+") + private val yamlFloatPattern = Platform.getPatternFromCache( "^-?([0-9_]*)*(\\.[0-9_]*)?(e[-+][0-9_]+)?$" ) + private val yamlIntPattern = Platform.getPatternFromCache("^[-+]?[0-9_]+$") private def isSafeBareKey(k: String) = { val l = k.toLowerCase From ffc5226bc1d5151b886a458f2f632e7e8611bef1 Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Wed, 9 Apr 2025 12:58:04 +0200 Subject: [PATCH 03/13] adjustment after merge --- sjsonnet/src/sjsonnet/Parser.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sjsonnet/src/sjsonnet/Parser.scala b/sjsonnet/src/sjsonnet/Parser.scala index 3a483126..f8c800ce 100644 --- a/sjsonnet/src/sjsonnet/Parser.scala +++ b/sjsonnet/src/sjsonnet/Parser.scala @@ -97,11 +97,20 @@ class Parser(val currentFile: Path, tripleBarStringBody(w).map(pre ++ Seq(head, "\n") ++ _) } ) - def tripleBarString(implicit p: P[?]): P[Seq[String]] = P( - "||"./ ~~ CharsWhileIn(" \t", 0) ~~ + + def maybeChompedTripleBarString(implicit p: P[?]): P[Seq[String]] = tripleBarString.map{ + case (true, lines) => + Seq(lines.mkString.stripLineEnd) + case (false, lines) => + lines + } + + def tripleBarString(implicit p: P[?]): P[(Boolean, Seq[String])] = P( + ("||-" | "||").?.!.map(_.last == '-')./ ~~ CharsWhileIn(" \t", 0) ~~ "\n" ~~ tripleBarStringLines ~~ "\n" ~~ CharsWhileIn(" \t", 0) ~~ "|||" ) + def string(implicit p: P[?]): P[String] = P( SingleChar.flatMapX{ case '\"' => doubleString From 4c6b20a03dbee9f33bbc68f59b6da63331b75ff1 Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Fri, 18 Apr 2025 15:14:34 +0200 Subject: [PATCH 04/13] fix merge --- sjsonnet/src/sjsonnet/BaseRenderer.scala | 2 -- sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala | 2 -- 2 files changed, 4 deletions(-) diff --git a/sjsonnet/src/sjsonnet/BaseRenderer.scala b/sjsonnet/src/sjsonnet/BaseRenderer.scala index 7109097f..d071b061 100644 --- a/sjsonnet/src/sjsonnet/BaseRenderer.scala +++ b/sjsonnet/src/sjsonnet/BaseRenderer.scala @@ -16,8 +16,6 @@ class BaseRenderer[T <: java.io.Writer] indent: Int = -1, escapeUnicode: Boolean = false) extends ujson.JsVisitor[T, T]{ - override def visitJsonableObject(length: Int, index: Int): ObjVisitor[T,T] = visitObject(length, index) - var depth: Int = 0 val colonSnippet: String = if (indent == -1) ":" else ": " diff --git a/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala b/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala index 687b519c..6a6f58d5 100644 --- a/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala +++ b/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala @@ -18,8 +18,6 @@ class PrettyYamlRenderer(out: Writer = new java.io.StringWriter(), idealWidth: Int = 80, getCurrentPosition: () => Position) extends BaseRenderer[Writer](out, indent){ - override def visitJsonableObject(length: Int, index: Int) = visitObject(length, index) - var newlineBuffered = false var dashBuffered = false var afterColon = false From 32c99040432eb9e82fbc9d9457d754a7f4e6b2e6 Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Fri, 18 Apr 2025 15:16:51 +0200 Subject: [PATCH 05/13] scla 3.3.5' --- build.sbt | 2 +- build.sc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 79b75cc2..b07b2a57 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,7 @@ val sjsonnetVersion = "0.4.15.1" val scala213 = "2.13.16" -val scala3 = "3.6.4" +val scala3 = "3.3.5" cancelable in Global := true diff --git a/build.sc b/build.sc index 264787f9..ec0912ed 100644 --- a/build.sc +++ b/build.sc @@ -5,7 +5,7 @@ import java.util.Base64 val sjsonnetVersion = "0.4.15.1" -val scalaVersions = Seq("2.12.20", "2.13.16", "3.6.4") +val scalaVersions = Seq("2.12.20", "2.13.16", "3.3.5") trait SjsonnetCrossModule extends CrossScalaModule with PublishModule { def crossValue: String From 5ef53bcb7aa756c97ea493386dbfaa19d4d12343 Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Fri, 18 Apr 2025 15:51:32 +0200 Subject: [PATCH 06/13] fix build.sbt --- build.sbt | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/build.sbt b/build.sbt index b07b2a57..76ba3289 100644 --- a/build.sbt +++ b/build.sbt @@ -8,14 +8,18 @@ cancelable in Global := true val scala3Options = Seq() val scala2Options = Seq("-opt:l:inline", "-opt-inline-from:sjsonnet.*,sjsonnet.**", "-Xsource:3") +lazy val commonSettings = Seq( + scalaVersion := scala3, + crossScalaVersions := Seq(scala213, scala3), + scalacOptions ++= {CrossVersion.partialVersion(scalaVersion.value) match { + case Some((3, _)) => scala3Options + case _ => scala2Options + }} +) + lazy val main = (project in file("sjsonnet")) + .settings(commonSettings: _*) .settings( - scalaVersion := scala3, - crossScalaVersions := Seq(scala213, scala3), - scalacOptions ++= {CrossVersion.partialVersion(scalaVersion.value) match { - case Some((3, _)) => scala3Options - case _ => scala2Options - }}, Test / fork := true, Test / javaOptions += "-Xss100m", Test / baseDirectory := (ThisBuild / baseDirectory).value, @@ -65,12 +69,7 @@ lazy val main = (project in file("sjsonnet")) lazy val bench = (project in file("bench")) .dependsOn(main % "compile->test") .enablePlugins(JmhPlugin) + .settings(commonSettings: _*) .settings( - run / fork := true - ) - - lazy val root = (project in file(".")) - .aggregate(main) - .settings( - publishArtifact := false + run / fork := true, ) \ No newline at end of file From 46b60b6d6a2146630f2ab8f7694783f2ed6e78a6 Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Fri, 18 Apr 2025 17:00:14 +0200 Subject: [PATCH 07/13] bump scala native stack size --- .github/workflows/pr-build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-build.yaml b/.github/workflows/pr-build.yaml index 778ffde2..0fb11d2f 100644 --- a/.github/workflows/pr-build.yaml +++ b/.github/workflows/pr-build.yaml @@ -17,6 +17,7 @@ jobs: env: # Set LANG=C to simulate least-common-denominator target deployment environments: LANG: C + SCALANATIVE_THREAD_STACK_SIZE: 10m name: Sjsonnet build for ${{ matrix.lang }} on JDK ${{ matrix.java }} steps: - uses: actions/checkout@v4 From 036421e2c8acd77dbe6d5be59c246b977b5346b2 Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Fri, 18 Apr 2025 18:51:42 +0200 Subject: [PATCH 08/13] toSeq on Map to do flatMap --- sjsonnet/src/sjsonnet/Std.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sjsonnet/src/sjsonnet/Std.scala b/sjsonnet/src/sjsonnet/Std.scala index 1c4a0c47..7d733cb8 100644 --- a/sjsonnet/src/sjsonnet/Std.scala +++ b/sjsonnet/src/sjsonnet/Std.scala @@ -1260,14 +1260,14 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. case _ => x.transform(new sjsonnet.Renderer()) } def sect(x: ujson.Obj) = { - x.value.flatMap{ + x.value.toSeq.flatMap{ case (k, ujson.Arr(vs)) => vs.map(x => k + " = " + render(x)) case (k, v) => Seq(k + " = " + render(v)) } } val lines = materialized.obj.get("main").fold(Iterable[String]())(x => sect(x.asInstanceOf[ujson.Obj])) ++ materialized.obj.get("sections").fold(Iterable[String]())(x => - x.obj.flatMap{case (k, v) => Seq("[" + k + "]") ++ sect(v.asInstanceOf[ujson.Obj])} + x.obj.toSeq.flatMap{case (k, v) => Seq("[" + k + "]") ++ sect(v.asInstanceOf[ujson.Obj])} ) lines.flatMap(Seq(_, "\n")).mkString }, @@ -1361,7 +1361,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. } }, builtin("manifestPythonVars", "v"){ (pos, ev, v: Val.Obj) => - Materializer(v)(ev).obj + Materializer(v)(ev).obj.toSeq .map{case (k, v) => k + " = " + v.transform(new PythonRenderer()).toString + "\n"} .mkString }, @@ -1372,7 +1372,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. case ujson.Str(s) => s case ujson.Arr(mutable.Seq(ujson.Str(t), attrs: ujson.Obj, children@_*)) => tag(t)( - attrs.value.map { + attrs.value.toSeq.map { case (k, ujson.Str(v)) => attr(k) := v // use ujson.write to make sure output number format is same as From 750d054815d7140288c9d74140e4fcc1a837a0dd Mon Sep 17 00:00:00 2001 From: Rafal Sierkiewicz Date: Sun, 20 Apr 2025 20:57:38 +0200 Subject: [PATCH 09/13] remove implicit in favour of $ --- .../sjsonnet/SjsonnetMain.scala | 2 +- sjsonnet/src/sjsonnet/Format.scala | 18 +-- sjsonnet/src/sjsonnet/Parser.scala | 104 +++++++++--------- .../src/sjsonnet/PrettyYamlRenderer.scala | 32 +++--- 4 files changed, 78 insertions(+), 78 deletions(-) diff --git a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala index c45dae4e..10d8d4cb 100644 --- a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala +++ b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala @@ -217,7 +217,7 @@ object SjsonnetMain { strictSetOperations = config.strictSetOperations.value, throwErrorForInvalidSets = config.throwErrorForInvalidSets.value, ), - storePos = (position: Position) => if (config.yamlDebug.value) currentPos = position else null, + storePos = (position: Position) => if (config.yamlDebug.value) currentPos = position else (), warnLogger = warnLogger, std = std ) diff --git a/sjsonnet/src/sjsonnet/Format.scala b/sjsonnet/src/sjsonnet/Format.scala index 3caac98c..8585028b 100644 --- a/sjsonnet/src/sjsonnet/Format.scala +++ b/sjsonnet/src/sjsonnet/Format.scala @@ -22,13 +22,13 @@ object Format{ precision: Option[Int], conversion: Char) import fastparse._, NoWhitespace._ - def integer(implicit p: P[?]): P[Unit] = P( CharIn("1-9") ~ CharsWhileIn("0-9", 0) | "0" ) - def label(implicit p: P[?]): P[Option[String]] = P( ("(" ~ CharsWhile(_ != ')').! ~ ")").? ) - def flags(implicit p: P[?]): P[String] = P( CharsWhileIn("#0\\- +", 0).! ) - def width(implicit p: P[?]): P[Option[String]] = P( (integer | "*").!.? ) - def precision(implicit p: P[?]): P[Option[String]] = P( ("." ~/ integer.!).? ) - def conversion(implicit p: P[?]): P[String] = P( CharIn("diouxXeEfFgGcrsa%").! ) - def formatSpec(implicit p: P[?]): P[FormatSpec] = P( label ~ flags ~ width ~ precision ~ CharIn("hlL").? ~ conversion ).map{ + def integer[$: P]: P[Unit] = P( CharIn("1-9") ~ CharsWhileIn("0-9", 0) | "0" ) + def label[$: P]: P[Option[String]] = P( ("(" ~ CharsWhile(_ != ')').! ~ ")").? ) + def flags[$: P]: P[String] = P( CharsWhileIn("#0\\- +", 0).! ) + def width[$: P]: P[Option[String]] = P( (integer | "*").!.? ) + def precision[$: P]: P[Option[String]] = P( ("." ~/ integer.!).? ) + def conversion[$: P]: P[String] = P( CharIn("diouxXeEfFgGcrsa%").! ) + def formatSpec[$: P]: P[FormatSpec] = P( label ~ flags ~ width ~ precision ~ CharIn("hlL").? ~ conversion ).map{ case (label, flags, width, precision, conversion) => FormatSpec( label, @@ -44,8 +44,8 @@ object Format{ } - def plain(implicit p: P[?]): P[String] = P( CharsWhile(_ != '%', 0).! ) - def format(implicit p: P[?]): P[(String, Seq[(FormatSpec, String)])] = P( plain ~ (("%" ~/ formatSpec) ~ plain).rep ~ End) + def plain[$: P]: P[String] = P( CharsWhile(_ != '%', 0).! ) + def format[$: P]: P[(String, Seq[(FormatSpec, String)])] = P( plain ~ (("%" ~/ formatSpec) ~ plain).rep ~ End) diff --git a/sjsonnet/src/sjsonnet/Parser.scala b/sjsonnet/src/sjsonnet/Parser.scala index f8c800ce..34f6e483 100644 --- a/sjsonnet/src/sjsonnet/Parser.scala +++ b/sjsonnet/src/sjsonnet/Parser.scala @@ -52,15 +52,15 @@ class Parser(val currentFile: Path, private val fileScope = new FileScope(currentFile) - def Pos(implicit p: P[?]): P[Position] = Index.map(offset => new Position(fileScope, offset)) + def Pos[$: P]: P[Position] = Index.map(offset => new Position(fileScope, offset)) - def id(implicit p: P[?]): P[String] = P( + def id[$: P]: P[String] = P( CharIn("_a-zA-Z") ~~ CharsWhileIn("_a-zA-Z0-9", 0) ).!.filter(s => !keywords.contains(s)) - def break(implicit p: P[?]): P[Unit] = P(!CharIn("_a-zA-Z0-9")) - def number(implicit p: P[?]): P[Val.Num] = P( + def break[$: P]: P[Unit] = P(!CharIn("_a-zA-Z0-9")) + def number[$: P]: P[Val.Num] = P( Pos ~~ ( CharsWhileIn("0-9") ~~ ("." ~ CharsWhileIn("0-9")).? ~~ @@ -68,8 +68,8 @@ class Parser(val currentFile: Path, ).! ).map(s => Val.Num(s._1, s._2.toDouble)) - def escape(implicit p: P[?]): P[String] = P( escape0 | escape1 ) - def escape0(implicit p: P[?]): P[String] = P("\\" ~~ !"u" ~~ AnyChar.!).map{ + def escape[$: P]: P[String] = P( escape0 | escape1 ) + def escape0[$: P]: P[String] = P("\\" ~~ !"u" ~~ AnyChar.!).map{ case "\"" => "\"" case "'" => "\'" case "\\" => "\\" @@ -80,38 +80,38 @@ class Parser(val currentFile: Path, case "r" => "\r" case "t" => "\t" } - def escape1(implicit p: P[?]): P[String] = P( "\\u" ~~ CharIn("0-9a-fA-F").repX(min=4, max=4).! ).map{ + def escape1[$: P]: P[String] = P( "\\u" ~~ CharIn("0-9a-fA-F").repX(min=4, max=4).! ).map{ s => Integer.parseInt(s, 16).toChar.toString } - def doubleString(implicit p: P[?]): P[Seq[String]] = + def doubleString[$: P]: P[Seq[String]] = P( (CharsWhile(x => x != '"' && x != '\\').! | escape).repX ~~ "\"" ) - def singleString(implicit p: P[?]): P[Seq[String]] = + def singleString[$: P]: P[Seq[String]] = P( (CharsWhile(x => x != '\'' && x != '\\').! | escape).repX ~~ "'" ) - def literalDoubleString(implicit p: P[?]): P[Seq[String]] = + def literalDoubleString[$: P]: P[Seq[String]] = P( (CharsWhile(_ != '"').! | "\"\"".!.map(_ => "\"")).repX ~~ "\"" ) - def literalSingleString(implicit p: P[?]): P[Seq[String]] = + def literalSingleString[$: P]: P[Seq[String]] = P( (CharsWhile(_ != '\'').! | "''".!.map(_ => "'")).repX ~~ "'" ) - def tripleBarStringLines(implicit p: P[?]): P[Seq[String]] = P( + def tripleBarStringLines[$: P]: P[Seq[String]] = P( tripleBarStringHead.flatMapX { case (pre, w, head) => tripleBarStringBody(w).map(pre ++ Seq(head, "\n") ++ _) } ) - def maybeChompedTripleBarString(implicit p: P[?]): P[Seq[String]] = tripleBarString.map{ + def maybeChompedTripleBarString[$: P]: P[Seq[String]] = tripleBarString.map{ case (true, lines) => Seq(lines.mkString.stripLineEnd) case (false, lines) => lines } - def tripleBarString(implicit p: P[?]): P[(Boolean, Seq[String])] = P( + def tripleBarString[$: P]: P[(Boolean, Seq[String])] = P( ("||-" | "||").?.!.map(_.last == '-')./ ~~ CharsWhileIn(" \t", 0) ~~ "\n" ~~ tripleBarStringLines ~~ "\n" ~~ CharsWhileIn(" \t", 0) ~~ "|||" ) - def string(implicit p: P[?]): P[String] = P( + def string[$: P]: P[String] = P( SingleChar.flatMapX{ case '\"' => doubleString case '\'' => singleString @@ -125,24 +125,24 @@ class Parser(val currentFile: Path, } ).map(_.mkString) - def tripleBarStringHead(implicit p: P[?]): P[(Seq[String], String, String)] = P( + def tripleBarStringHead[$: P]: P[(Seq[String], String, String)] = P( (CharsWhileIn(" \t", 0) ~~ "\n".!).repX ~~ CharsWhileIn(" \t", 1).! ~~ CharsWhile(_ != '\n').! ) - def tripleBarBlankHead(implicit p: P[?]): P[String] = + def tripleBarBlankHead[$: P]: P[String] = P( CharsWhileIn(" \t", 0) ~~ &("\n").map(_ => "\n") ) - def tripleBarBlank(implicit p: P[?]): P[String] = P( "\n" ~~ tripleBarBlankHead ) + def tripleBarBlank[$: P]: P[String] = P( "\n" ~~ tripleBarBlankHead ) - def tripleBarStringBody(w: String)(implicit p: P[?]): P[Seq[String]] = P( + def tripleBarStringBody[$: P](w: String): P[Seq[String]] = P( (tripleBarBlank | "\n" ~~ w ~~ CharsWhile(_ != '\n').!.map(_ + "\n")).repX ) - def arr(implicit p: P[?]): P[Expr] = P( (Pos ~~ &("]")).map(new Val.Arr(_, emptyLazyArray)) | arrBody ) - def compSuffix(implicit p: P[?]): P[Left[(Expr.ForSpec, Seq[Expr.CompSpec]),Nothing]] = P( forspec ~ compspec ).map(Left(_)) - def arrBody(implicit p: P[?]): P[Expr] = P( + def arr[$: P]: P[Expr] = P( (Pos ~~ &("]")).map(new Val.Arr(_, emptyLazyArray)) | arrBody ) + def compSuffix[$: P]: P[Left[(Expr.ForSpec, Seq[Expr.CompSpec]),Nothing]] = P( forspec ~ compspec ).map(Left(_)) + def arrBody[$: P]: P[Expr] = P( Pos ~~ expr ~ (compSuffix | "," ~ (compSuffix | (expr.rep(0, sep = ",") ~ ",".?).map(Right(_)))).? ).map{ @@ -161,19 +161,19 @@ class Parser(val currentFile: Path, case (offset, first, Some(Right(rest))) => Expr.Arr(offset, Array(first) ++ rest) } - def assertExpr(pos: Position)(implicit p: P[?]): P[Expr] = + def assertExpr[$: P](pos: Position): P[Expr] = P( assertStmt ~ ";" ~ expr ).map(t => Expr.AssertExpr(pos, t._1, t._2)) - def function(pos: Position)(implicit p: P[?]): P[Expr] = + def function[$: P](pos: Position): P[Expr] = P( "(" ~/ params ~ ")" ~ expr ).map(t => Expr.Function(pos, t._1, t._2)) - def ifElse(pos: Position)(implicit p: P[?]): P[Expr] = + def ifElse[$: P](pos: Position): P[Expr] = P( Pos ~~ expr ~ "then" ~~ break ~ expr ~ ("else" ~~ break ~ expr).?.map(_.getOrElse(null)) ).map{case (pos, cond, t, e) => Expr.IfElse(pos, cond, t, e)} - def localExpr(implicit p: P[?]): P[Expr] = + def localExpr[$: P]: P[Expr] = P( Pos ~~ bind.rep(min=1, sep = ","./).map(s => if(s.isEmpty) null else s.toArray) ~ ";" ~ expr ).map{case (pos, bind, ret) => Expr.LocalExpr(pos, bind, ret)} - def expr(implicit p: P[?]): P[Expr] = + def expr[$: P]: P[Expr] = P("" ~ expr1 ~ (Pos ~~ binaryop ~/ expr1).rep ~ "").map{ case (pre, fs) => var remaining = fs def climb(minPrec: Int, current: Expr): Expr = { @@ -223,11 +223,11 @@ class Parser(val currentFile: Path, climb(0, pre) } - def expr1(implicit p: P[?]): P[Expr] = P(expr2 ~ exprSuffix2.rep).map{ + def expr1[$: P]: P[Expr] = P(expr2 ~ exprSuffix2.rep).map{ case (pre, fs) => fs.foldLeft(pre){case (p, f) => f(p) } } - def exprSuffix2(implicit p: P[?]): P[Expr => Expr] = P( + def exprSuffix2[$: P]: P[Expr => Expr] = P( Pos.flatMapX{i => CharIn(".[({")./.!.map(_(0)).flatMapX{ c => (c: @switch) match{ @@ -246,13 +246,13 @@ class Parser(val currentFile: Path, } ) - def local(implicit p: P[?]): P[Expr] = P( localExpr ) - def importStr(pos: Position)(implicit p: P[?]): P[Expr.ImportStr] = P( importExpr.map(Expr.ImportStr(pos, _)) ) - def importBin(pos: Position)(implicit p: P[?]): P[Expr.ImportBin] = P( importExpr.map(Expr.ImportBin(pos, _)) ) - def `import`(pos: Position)(implicit p: P[?]): P[Expr.Import] = P( importExpr.map(Expr.Import(pos, _)) ) - def error(pos: Position)(implicit p: P[?]): P[Expr.Error] = P(expr.map(Expr.Error(pos, _)) ) + def local[$: P]: P[Expr] = P( localExpr ) + def importStr[$: P](pos: Position): P[Expr.ImportStr] = P( importExpr.map(Expr.ImportStr(pos, _)) ) + def importBin[$: P](pos: Position): P[Expr.ImportBin] = P( importExpr.map(Expr.ImportBin(pos, _)) ) + def `import`[$: P](pos: Position): P[Expr.Import] = P( importExpr.map(Expr.Import(pos, _)) ) + def error[$: P](pos: Position): P[Expr.Error] = P(expr.map(Expr.Error(pos, _)) ) - def importExpr(implicit p: P[?]): P[String] = P( + def importExpr[$: P]: P[String] = P( if (!strictImportSyntax) string else expr.flatMap { case Val.Str(_, s) => Pass(s) @@ -260,7 +260,7 @@ class Parser(val currentFile: Path, } ) - def unaryOpExpr(pos: Position, op: Char)(implicit p: P[?]): P[Expr.UnaryOp] = P( + def unaryOpExpr[$: P](pos: Position, op: Char): P[Expr.UnaryOp] = P( expr1.map{ e => def k2 = op match{ case '+' => Expr.UnaryOp.OP_+ @@ -279,7 +279,7 @@ class Parser(val currentFile: Path, } // Any `expr` that isn't naively left-recursive - def expr2(implicit p: P[?]): P[Expr] = P( + def expr2[$: P]: P[Expr] = P( Pos.flatMapX{ pos => SingleChar.flatMapX{ c => c match { @@ -322,7 +322,7 @@ class Parser(val currentFile: Path, } ) - def objinside(implicit p: P[?]): P[Expr.ObjBody] = P( + def objinside[$: P]: P[Expr.ObjBody] = P( Pos ~ member.rep(sep = ",") ~ ",".? ~ (forspec ~ compspec).? ).flatMap { case t @ (pos, exprs, _) => val seen = collection.mutable.Set.empty[String] @@ -382,35 +382,35 @@ class Parser(val currentFile: Path, Expr.ObjBody.ObjComp(pos, preLocals.toArray, lhs, rhs, plus, postLocals.toArray, comps._1, comps._2.toList) } - def member(implicit p: P[?]): P[Expr.Member] = P( objlocal | "assert" ~~ break ~ assertStmt | field ) - def field(implicit p: P[?]): P[Expr.Member.Field] = P( + def member[$: P]: P[Expr.Member] = P( objlocal | "assert" ~~ break ~ assertStmt | field ) + def field[$: P]: P[Expr.Member.Field] = P( (Pos ~~ fieldname ~/ "+".!.? ~ ("(" ~ params ~ ")").? ~ fieldKeySep ~/ expr).map{ case (pos, name, plus, p, h2, e) => Expr.Member.Field(pos, name, plus.nonEmpty, p.getOrElse(null), h2, e) } ) - def fieldKeySep(implicit p: P[?]): P[Visibility] = P( StringIn(":::", "::", ":") ).!.map{ + def fieldKeySep[$: P]: P[Visibility] = P( StringIn(":::", "::", ":") ).!.map{ case ":" => Visibility.Normal case "::" => Visibility.Hidden case ":::" => Visibility.Unhide } - def objlocal(implicit p: P[?]): P[Expr.Bind] = P( "local" ~~ break ~/ bind ) - def compspec(implicit p: P[?]): P[Seq[Expr.CompSpec]] = P( (forspec | ifspec).rep ) - def forspec(implicit p: P[?]): P[Expr.ForSpec] = + def objlocal[$: P]: P[Expr.Bind] = P( "local" ~~ break ~/ bind ) + def compspec[$: P]: P[Seq[Expr.CompSpec]] = P( (forspec | ifspec).rep ) + def forspec[$: P]: P[Expr.ForSpec] = P( Pos ~~ "for" ~~ break ~/ id ~ "in" ~~ break ~ expr ).map{case (pos, name, cond) => Expr.ForSpec(pos, name, cond) } - def ifspec(implicit p: P[?]): P[Expr.IfSpec] = P( Pos ~~ "if" ~~ break ~/ expr ).map{case (pos, cond) => Expr.IfSpec(pos, cond) } - def fieldname(implicit p: P[?]): P[Expr.FieldName] = P( + def ifspec[$: P]: P[Expr.IfSpec] = P( Pos ~~ "if" ~~ break ~/ expr ).map{case (pos, cond) => Expr.IfSpec(pos, cond) } + def fieldname[$: P]: P[Expr.FieldName] = P( id.map(Expr.FieldName.Fixed.apply) | string.map(Expr.FieldName.Fixed.apply) | "[" ~ expr.map(Expr.FieldName.Dyn.apply) ~ "]" ) - def assertStmt(implicit p: P[?]): P[Expr.Member.AssertStmt] = + def assertStmt[$: P]: P[Expr.Member.AssertStmt] = P( expr ~ (":" ~ expr).?.map(_.getOrElse(null)) ).map{case (value, msg) => Expr.Member.AssertStmt(value, msg) } - def bind(implicit p: P[?]): P[Expr.Bind] = + def bind[$: P]: P[Expr.Bind] = P( Pos ~~ id ~ ("(" ~/ params.? ~ ")").?.map(_.flatten).map(_.getOrElse(null)) ~ "=" ~ expr ).map{case (pos, name, args, rhs )=> Expr.Bind(pos, name, args, rhs)} - def args(implicit p: P[?]): P[(Array[Expr], Array[String])] = P( ((id ~ "=" ~ !"=").? ~ expr).rep(sep = ",") ~ ",".? ).flatMapX{ x => + def args[$: P]: P[(Array[Expr], Array[String])] = P( ((id ~ "=" ~ !"=").? ~ expr).rep(sep = ",") ~ ",".? ).flatMapX{ x => if (x.sliding(2).exists{case Seq(l, r) => l._1.isDefined && r._1.isEmpty case _ => false}) { Fail.opaque("no positional params after named params") } else { @@ -420,7 +420,7 @@ class Parser(val currentFile: Path, } } - def params(implicit p: P[?]): P[Expr.Params] = P( (id ~ ("=" ~ expr).?).rep(sep = ",") ~ ",".? ).flatMapX{ x => + def params[$: P]: P[Expr.Params] = P( (id ~ ("=" ~ expr).?).rep(sep = ",") ~ ",".? ).flatMapX{ x => val seen = collection.mutable.Set.empty[String] var overlap: String = null for((k, v) <- x){ @@ -436,7 +436,7 @@ class Parser(val currentFile: Path, } - def binaryop(implicit p: P[?]): P[String] = P( + def binaryop[$: P]: P[String] = P( StringIn( "<<", ">>", "<=", ">=", "in", "==", "!=", "&&", "||", "*", "/", "%", "+", "-", "<", ">", "&", "^", "|" @@ -444,7 +444,7 @@ class Parser(val currentFile: Path, ).! - def document(implicit p: P[?]): P[(Expr, FileScope)] = P( expr ~ Pass(fileScope) ~ End ) + def document[$: P]: P[(Expr, FileScope)] = P( expr ~ Pass(fileScope) ~ End ) } final class Position(val fileScope: FileScope, val offset: Int) { diff --git a/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala b/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala index 6a6f58d5..23aacca1 100644 --- a/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala +++ b/sjsonnet/src/sjsonnet/PrettyYamlRenderer.scala @@ -406,7 +406,7 @@ object PrettyYamlRenderer{ def stringNeedsToBeQuoted(str: String): Boolean = { import fastparse._ import NoWhitespace._ - def yamlPunctuation(implicit p: P[?]) = P( + def yamlPunctuation[$: P] = P( // http://blogs.perl.org/users/tinita/2018/03/strings-in-yaml---to-quote-or-not-to-quote.html StringIn( "!", // ! Tag like !!null @@ -424,7 +424,7 @@ object PrettyYamlRenderer{ " " // leading or trailing empty spaces need quotes to define them ) ) - def yamlKeyword(implicit p: P[?]) = P( + def yamlKeyword[$: P] = P( StringIn( // https://makandracards.com/makandra/24809-yaml-keys-like-yes-or-no-evaluate-to-true-and-false // y|Y|yes|Yes|YES|n|N|no|No|NO @@ -441,17 +441,17 @@ object PrettyYamlRenderer{ ) ) - def digits(implicit p: P[?]) = P( CharsWhileIn("0-9") ) - def yamlFloat(implicit p: P[?]) = P( + def digits[$: P] = P( CharsWhileIn("0-9") ) + def yamlFloat[$: P] = P( (digits.? ~ "." ~ digits | digits ~ ".") ~ (("e" | "E") ~ ("+" | "-").? ~ digits).? ) - def yamlOctalSuffix(implicit p: P[?]) = P( "x" ~ CharIn("1-9a-fA-F") ~ CharsWhileIn("0-9a-fA-F").? ) - def yamlHexSuffix(implicit p: P[?]) = P( "o" ~ CharIn("1-7") ~ CharsWhileIn("0-7").? ) - def yamlOctalHex(implicit p: P[?]) = P( "0" ~ (yamlOctalSuffix | yamlHexSuffix) ) - def yamlNumber0(implicit p: P[?]) = P( ".inf" | yamlFloat | yamlOctalHex | digits ) + def yamlOctalSuffix[$: P] = P( "x" ~ CharIn("1-9a-fA-F") ~ CharsWhileIn("0-9a-fA-F").? ) + def yamlHexSuffix[$: P] = P( "o" ~ CharIn("1-7") ~ CharsWhileIn("0-7").? ) + def yamlOctalHex[$: P] = P( "0" ~ (yamlOctalSuffix | yamlHexSuffix) ) + def yamlNumber0[$: P] = P( ".inf" | yamlFloat | yamlOctalHex | digits ) // Add a `CharIn` lookahead to bail out quickly if something cannot possibly be a number - def yamlNumber(implicit p: P[?]) = P( "-".? ~ yamlNumber0 ) + def yamlNumber[$: P] = P( "-".? ~ yamlNumber0 ) // Strings and numbers aren't the only scalars that YAML can understand. // ISO-formatted date and datetime literals are also parsed. @@ -459,19 +459,19 @@ object PrettyYamlRenderer{ // datetime: 2001-12-15T02:59:43.1Z // datetime_with_spaces: 2001-12-14 21:59:43.10 -5 - def fourDigits(implicit p: P[?]) = P( CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ) - def oneTwoDigits(implicit p: P[?]) = P( CharIn("0-9") ~ CharIn("0-9").? ) - def twoDigits(implicit p: P[?]) = P( CharIn("0-9") ~ CharIn("0-9") ) - def dateTimeSuffix(implicit p: P[?]) = P( + def fourDigits[$: P] = P( CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ~ CharIn("0-9") ) + def oneTwoDigits[$: P] = P( CharIn("0-9") ~ CharIn("0-9").? ) + def twoDigits[$: P] = P( CharIn("0-9") ~ CharIn("0-9") ) + def dateTimeSuffix[$: P] = P( ("T" | " ") ~ twoDigits ~ ":" ~ twoDigits ~ ":" ~ twoDigits ~ ("." ~ digits.?).? ~ ((" " | "Z").? ~ ("-".? ~ oneTwoDigits).?).? ) - def yamlDate(implicit p: P[?]) = P( fourDigits ~ "-" ~ oneTwoDigits ~ "-" ~ oneTwoDigits ~ dateTimeSuffix.? ) + def yamlDate[$: P] = P( fourDigits ~ "-" ~ oneTwoDigits ~ "-" ~ oneTwoDigits ~ dateTimeSuffix.? ) // Not in the YAML, but included to match PyYAML behavior - def yamlTime(implicit p: P[?]) = P( twoDigits ~ ":" ~ twoDigits ) + def yamlTime[$: P] = P( twoDigits ~ ":" ~ twoDigits ) - def parser(implicit p: P[?]) = P( + def parser[$: P] = P( // Use a `&` lookahead to bail out early in the common case, so we don't // need to try parsing times/dates/numbers one by one yamlPunctuation | (&(CharIn(".0-9\\-")) ~ (yamlTime | yamlDate | yamlNumber) | yamlKeyword) ~ End From 658fb430c5a3aab4e2101ea843c9ab5563665924 Mon Sep 17 00:00:00 2001 From: Stephen Amar Date: Sun, 20 Apr 2025 21:19:22 -0700 Subject: [PATCH 10/13] Update sjsonnet/src/sjsonnet/Std.scala Co-authored-by: He-Pin(kerr) --- sjsonnet/src/sjsonnet/Std.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/sjsonnet/src/sjsonnet/Std.scala b/sjsonnet/src/sjsonnet/Std.scala index 7d733cb8..e41225a5 100644 --- a/sjsonnet/src/sjsonnet/Std.scala +++ b/sjsonnet/src/sjsonnet/Std.scala @@ -1372,6 +1372,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. case ujson.Str(s) => s case ujson.Arr(mutable.Seq(ujson.Str(t), attrs: ujson.Obj, children@_*)) => tag(t)( + //TODO remove the `toSeq` once this is fixed in scala3 attrs.value.toSeq.map { case (k, ujson.Str(v)) => attr(k) := v From d5dc4f4abad69d75fa4d2b63a5bfef245db314ed Mon Sep 17 00:00:00 2001 From: Stephen Amar Date: Sun, 20 Apr 2025 21:19:46 -0700 Subject: [PATCH 11/13] Update sjsonnet/src/sjsonnet/Std.scala Co-authored-by: He-Pin(kerr) --- sjsonnet/src/sjsonnet/Std.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/sjsonnet/src/sjsonnet/Std.scala b/sjsonnet/src/sjsonnet/Std.scala index e41225a5..3ceea89a 100644 --- a/sjsonnet/src/sjsonnet/Std.scala +++ b/sjsonnet/src/sjsonnet/Std.scala @@ -1260,6 +1260,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. case _ => x.transform(new sjsonnet.Renderer()) } def sect(x: ujson.Obj) = { + //TODO remove the `toSeq` once this is fixed in scala3 x.value.toSeq.flatMap{ case (k, ujson.Arr(vs)) => vs.map(x => k + " = " + render(x)) case (k, v) => Seq(k + " = " + render(v)) From 648dc7e0178f27ad8783f1134c7026a06c238ac3 Mon Sep 17 00:00:00 2001 From: Stephen Amar Date: Sun, 20 Apr 2025 21:19:53 -0700 Subject: [PATCH 12/13] Update sjsonnet/src/sjsonnet/Std.scala Co-authored-by: He-Pin(kerr) --- sjsonnet/src/sjsonnet/Std.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/sjsonnet/src/sjsonnet/Std.scala b/sjsonnet/src/sjsonnet/Std.scala index 3ceea89a..9f4b3ff3 100644 --- a/sjsonnet/src/sjsonnet/Std.scala +++ b/sjsonnet/src/sjsonnet/Std.scala @@ -1362,6 +1362,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. } }, builtin("manifestPythonVars", "v"){ (pos, ev, v: Val.Obj) => + //TODO remove the `toSeq` once this is fixed in scala3 Materializer(v)(ev).obj.toSeq .map{case (k, v) => k + " = " + v.transform(new PythonRenderer()).toString + "\n"} .mkString From e21742933338d8c21c83b375fe4ae329780f96e2 Mon Sep 17 00:00:00 2001 From: Stephen Amar Date: Sun, 20 Apr 2025 21:20:17 -0700 Subject: [PATCH 13/13] Update sjsonnet/src/sjsonnet/Std.scala Co-authored-by: He-Pin(kerr) --- sjsonnet/src/sjsonnet/Std.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/sjsonnet/src/sjsonnet/Std.scala b/sjsonnet/src/sjsonnet/Std.scala index 9f4b3ff3..8cb67267 100644 --- a/sjsonnet/src/sjsonnet/Std.scala +++ b/sjsonnet/src/sjsonnet/Std.scala @@ -1268,6 +1268,7 @@ class Std(private val additionalNativeFunctions: Map[String, Val.Builtin] = Map. } val lines = materialized.obj.get("main").fold(Iterable[String]())(x => sect(x.asInstanceOf[ujson.Obj])) ++ materialized.obj.get("sections").fold(Iterable[String]())(x => + //TODO remove the `toSeq` once this is fixed in scala3 x.obj.toSeq.flatMap{case (k, v) => Seq("[" + k + "]") ++ sect(v.asInstanceOf[ujson.Obj])} ) lines.flatMap(Seq(_, "\n")).mkString