Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions bench/src/main/scala/sjsonnet/MainBenchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ object MainBenchmark {
Map.empty[String, String],
Map.empty[String, String],
OsPath(wd),
importer = SjsonnetMain
importer = SjsonnetMainBase
.resolveImport(config.getOrderedJpaths.map(os.Path(_, wd)).map(OsPath(_)), None),
parseCache = parseCache
)
Expand Down Expand Up @@ -65,7 +65,7 @@ class MainBenchmark {
@Benchmark
def main(bh: Blackhole): Unit = {
bh.consume(
SjsonnetMain.main0(
SjsonnetMainBase.main0(
MainBenchmark.mainArgs,
new DefaultParseCache,
System.in,
Expand Down Expand Up @@ -102,7 +102,7 @@ object MemoryBenchmark {
} else {
false
}
SjsonnetMain.main0(
SjsonnetMainBase.main0(
MainBenchmark.mainArgs,
cache,
System.in,
Expand Down
2 changes: 1 addition & 1 deletion bench/src/main/scala/sjsonnet/MaterializerBenchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MaterializerBenchmark {
Map.empty[String, String],
Map.empty[String, String],
OsPath(wd),
importer = SjsonnetMain
importer = SjsonnetMainBase
.resolveImport(
config.getOrderedJpaths.map(os.Path(_, wd)).map(OsPath(_)).toIndexedSeq,
None
Expand Down
2 changes: 1 addition & 1 deletion bench/src/main/scala/sjsonnet/MultiThreadedBenchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MultiThreadedBenchmark {
pool.submit {
(() =>
if (
SjsonnetMain.main0(
SjsonnetMainBase.main0(
MainBenchmark.mainArgs,
cache, // new DefaultParseCache
System.in,
Expand Down
2 changes: 1 addition & 1 deletion bench/src/main/scala/sjsonnet/RunProfiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object RunProfiler extends App {
Map.empty[String, String],
Map.empty[String, String],
OsPath(wd),
importer = SjsonnetMain
importer = SjsonnetMainBase
.resolveImport(config.getOrderedJpaths.map(os.Path(_, wd)).map(OsPath(_)).toIndexedSeq, None),
parseCache = parseCache
) {
Expand Down
3 changes: 2 additions & 1 deletion build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ object sjsonnet extends VersionFileModule {
def jsEnvConfig = JsEnvConfig.NodeJs(args = List("--stack-size=" + stackSizekBytes))
def resources = T.sources(
this.millSourcePath / "resources" / "test_suite",
this.millSourcePath / "resources" / "go_test_suite"
this.millSourcePath / "resources" / "go_test_suite",
this.millSourcePath / "resources" / "new_test_suite",
)
def generatedSources = T {
resources().map(_.path).flatMap { testSuite =>
Expand Down
2 changes: 1 addition & 1 deletion sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ object SjsonnetServerMain extends SjsonnetServerMain[DefaultParseCache] {
scala.Console.withIn(stdin) {
scala.Console.withOut(stdout) {
scala.Console.withErr(stderr) {
sjsonnet.SjsonnetMain.main0(args, stateCache2, stdin, stdout, stderr, wd) == 0
sjsonnet.SjsonnetMainBase.main0(args, stateCache2, stdin, stdout, stderr, wd) == 0
}
}
}
Expand Down
17 changes: 0 additions & 17 deletions sjsonnet/src-js/sjsonnet/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,11 @@ package sjsonnet

import org.virtuslab.yaml.*

import java.io.File
import java.util
import java.util.regex.Pattern
import scala.collection.mutable

object Platform {
def gzipBytes(s: Array[Byte]): String = {
throw new Exception("GZip not implemented in Scala.js")
}
def gzipString(s: String): String = {
throw new Exception("GZip not implemented in Scala.js")
}
def xzBytes(s: Array[Byte], compressionLevel: Option[Int]): String = {
throw new Exception("XZ not implemented in Scala.js")
}
def xzString(s: String, compressionLevel: Option[Int]): String = {
throw new Exception("XZ not implemented in Scala.js")
}

private def nodeToJson(node: Node): ujson.Value = node match {
case _: Node.ScalarNode =>
YamlDecoder.forAny.construct(node).getOrElse("") match {
Expand Down Expand Up @@ -98,9 +84,6 @@ object Platform {
def sha3(s: String): String = {
throw new Exception("SHA3 not implemented in Scala.js")
}
def hashFile(file: File): String = {
throw new Exception("hashFile not implemented in Scala.js")
}

private val regexCache = new util.concurrent.ConcurrentHashMap[String, Pattern]
private val namedGroupPattern = Pattern.compile("\\(\\?<(.+?)>.*?\\)")
Expand Down
5 changes: 4 additions & 1 deletion sjsonnet/src-js/sjsonnet/SjsonnetMain.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package sjsonnet

import sjsonnet.stdlib.NativeRegex

import scala.collection.mutable
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
Expand Down Expand Up @@ -39,7 +41,8 @@ object SjsonnetMain {
}
},
parseCache = new DefaultParseCache,
new Settings(preserveOrder = preserveOrder)
settings = new Settings(preserveOrder = preserveOrder),
std = new Std(nativeFunctions = NativeRegex.functions).Std
)
interp.interpret0(text, JsVirtualPath("(memory)"), ujson.WebJson.Builder) match {
case Left(msg) => throw new js.JavaScriptException(msg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import java.nio.file.NoSuchFileException
import scala.annotation.unused
import scala.util.Try

object SjsonnetMain {
object SjsonnetMainBase {
def resolveImport(
searchRoots0: Seq[Path], // Evaluated in order, first occurrence wins
allowedInputs: Option[Set[os.Path]] = None,
Expand Down Expand Up @@ -60,19 +60,6 @@ object SjsonnetMain {
}
}

def main(args: Array[String]): Unit = {
val exitCode = main0(
args,
new DefaultParseCache,
System.in,
System.out,
System.err,
os.pwd,
None
)
System.exit(exitCode)
}

def main0(
args: Array[String],
parseCache: ParseCache,
Expand Down
16 changes: 16 additions & 0 deletions sjsonnet/src-jvm-native/sjsonnet/stdlib/NativeGzip.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package sjsonnet.stdlib

import sjsonnet.{Error, EvalScope, Lazy, Platform, Position, Val}

object NativeGzip {
Comment thread
stephenamar-db marked this conversation as resolved.
Outdated
def functions: Map[String, Val.Builtin] = Map(
"gzip" -> new Val.Builtin1("gzip", "v") {
override def evalRhs(v: Lazy, ev: EvalScope, pos: Position): Val = v.force match {
case Val.Str(_, value) => Val.Str(pos, Platform.gzipString(value))
case arr: Val.Arr =>
Val.Str(pos, Platform.gzipBytes(arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray))
case x => Error.fail("Cannot gzip encode " + x.prettyName)
}
}
)
}
21 changes: 21 additions & 0 deletions sjsonnet/src-jvm/sjsonnet/SjsonnetMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package sjsonnet

import sjsonnet.stdlib.{NativeGzip, NativeRegex, NativeXz}

object SjsonnetMain {
def main(args: Array[String]): Unit = {
val exitCode = SjsonnetMainBase.main0(
args,
new DefaultParseCache,
System.in,
System.out,
System.err,
os.pwd,
None,
std = new Std(nativeFunctions =
NativeXz.functions ++ NativeGzip.functions ++ NativeRegex.functions
).Std
)
System.exit(exitCode)
}
}
40 changes: 40 additions & 0 deletions sjsonnet/src-jvm/sjsonnet/stdlib/NativeXz.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package sjsonnet.stdlib

import sjsonnet.{Error, EvalScope, Lazy, Platform, Position, Val}

object NativeXz {
private val dummyPos: Position = new Position(null, 0)

def functions: Map[String, Val.Builtin] = Map(
"xz" -> new Val.Builtin2(
"xz",
"v",
"compressionLevel",
Array(Val.Null(dummyPos), Val.Null(dummyPos))
) {
override def evalRhs(arg1: Lazy, arg2: Lazy, ev: EvalScope, pos: Position): Val = {
val compressionLevel: Option[Int] = arg2.force match {
case Val.Null(_) =>
// Use default compression level if the user didn't set one
None
case Val.Num(_, n) =>
Some(n.toInt)
case x =>
Error.fail("Cannot xz encode with compression level " + x.prettyName)
}
arg1.force match {
case Val.Str(_, value) => Val.Str(pos, Platform.xzString(value, compressionLevel))
case arr: Val.Arr =>
Val.Str(
pos,
Platform.xzBytes(
arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray,
compressionLevel
)
)
case x => Error.fail("Cannot xz encode " + x.prettyName)
}
}
}
)
}
19 changes: 19 additions & 0 deletions sjsonnet/src-native/sjsonnet/SjsonnetMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package sjsonnet

import sjsonnet.stdlib.{NativeGzip, NativeRegex}

object SjsonnetMain {
def main(args: Array[String]): Unit = {
val exitCode = SjsonnetMainBase.main0(
args,
new DefaultParseCache,
System.in,
System.out,
System.err,
os.pwd,
None,
std = new Std(nativeFunctions = NativeGzip.functions ++ NativeRegex.functions).Std
)
System.exit(exitCode)
}
}
47 changes: 3 additions & 44 deletions sjsonnet/src/sjsonnet/Std.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,17 @@ import scala.collection.mutable
* `builtin` and other helpers to handle the common wrapper logic automatically
*/
class Std(
private val additionalNativeFunctions: Map[String, Val.Func] = Map.empty,
private val nativeFunctions: Map[String, Val.Func] = Map.empty,
private val additionalStdFunctions: Map[String, Val.Func] = Map.empty)
extends FunctionBuilder {
// keep for binary compatibility
def this(additionalNativeFunctions: Map[String, Val.Func]) =
this(additionalNativeFunctions, Map.empty)
def this(nativeFunctions: Map[String, Val.Func]) =
this(nativeFunctions, Map.empty)

private val dummyPos: Position = new Position(null, 0)
private val emptyLazyArray = new Array[Lazy](0)
private val leadingWhiteSpacePattern = Platform.getPatternFromCache("^[ \t\n\f\r\u0085\u00A0']+")
private val trailingWhiteSpacePattern = Platform.getPatternFromCache("[ \t\n\f\r\u0085\u00A0']+$")
private val builtinNativeFunctions = Map(
builtin("gzip", "v") { (_, _, v: Val) =>
v match {
case Val.Str(_, value) => Platform.gzipString(value)
case arr: Val.Arr =>
Platform.gzipBytes(arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray)
case x => Error.fail("Cannot gzip encode " + x.prettyName)
}
},
builtinWithDefaults("xz", "v" -> null, "compressionLevel" -> Val.Null(dummyPos)) {
(args, _, _) =>
val compressionLevel: Option[Int] = args(1) match {
case Val.Null(_) =>
// Use default compression level if the user didn't set one
None
case Val.Num(_, n) =>
Some(n.toInt)
case x =>
Error.fail("Cannot xz encode with compression level " + x.prettyName)
}
args(0) match {
case Val.Str(_, value) => Platform.xzString(value, compressionLevel)
case arr: Val.Arr =>
Platform.xzBytes(
arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray,
compressionLevel
)
case x => Error.fail("Cannot xz encode " + x.prettyName)
}
}
) ++ StdRegex.functions
require(
builtinNativeFunctions.forall(k => !additionalNativeFunctions.contains(k._1)),
"Conflicting native functions"
)
private val nativeFunctions = builtinNativeFunctions ++ additionalNativeFunctions

private object AssertEqual extends Val.Builtin2("assertEqual", "a", "b") {
def evalRhs(v1: Lazy, v2: Lazy, ev: EvalScope, pos: Position): Val = {
Expand Down Expand Up @@ -2000,11 +1964,6 @@ class Std(
}
},
builtin(Native)
) ++ builtinNativeFunctions

require(
functions.forall(k => !additionalStdFunctions.contains(k._1)),
"Conflicting std functions"
)

private def toSetArr(args: Array[Val], idx: Int, pos: Position, ev: EvalScope) = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package sjsonnet
package sjsonnet.stdlib

import sjsonnet.Expr.Member.Visibility
import sjsonnet.Val.Obj
import sjsonnet._

object StdRegex {
object NativeRegex {
private final def regexPartialMatch(pos: Position, pattern: String, str: String): Val = {
val compiledPattern = Platform.getPatternFromCache(pattern)
val matcher = compiledPattern.matcher(str)
Expand Down
8 changes: 5 additions & 3 deletions sjsonnet/test/src-js/sjsonnet/BaseFileTests.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package sjsonnet

import sjsonnet.stdlib.NativeRegex

import java.nio.charset.StandardCharsets
import scala.scalajs.js
import utest._

abstract class BaseFileTests extends TestSuite {
private val stderr = new StringBuffer()
private val std = new Std(
additionalNativeFunctions = Map(
nativeFunctions = Map(
"jsonToString" -> new Val.Builtin1("jsonToString", "x") {
override def evalRhs(arg1: Lazy, ev: EvalScope, pos: Position): Val = {
Val.Str(
Expand All @@ -29,7 +31,7 @@ abstract class BaseFileTests extends TestSuite {
override def evalRhs(ev: EvalScope, pos: Position): Val =
throw new RuntimeException("native function panic")
}
)
) ++ NativeRegex.functions
)

def importResolver(
Expand Down Expand Up @@ -103,7 +105,7 @@ abstract class BaseFileTests extends TestSuite {
}

def check(files: Map[String, () => Array[Byte]], fileName: String, testSuite: String): Unit = {
println(s"Checking $fileName")
println(s"Checking $testSuite/$fileName")
val goldenContent = if (files.contains(fileName + ".golden_js")) {
new String(files(fileName + ".golden_js")(), StandardCharsets.UTF_8)
} else {
Expand Down
11 changes: 10 additions & 1 deletion sjsonnet/test/src-js/sjsonnet/FileTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import utest._
object FileTests extends BaseFileTests {
val skippedTests = Set(
"stdlib.jsonnet",
"regex.jsonnet",

// Stack size issues with the JS runner
"recursive_function.jsonnet",
Expand Down Expand Up @@ -55,5 +54,15 @@ object FileTests extends BaseFileTests {
check(TestResources_go_test_suite.files, file, "go_test_suite")
}
}

test("new_test_suite") - {
val t = TestResources_new_test_suite.files.keys.toSeq
.filter(f => f.matches("[^/]+-js\\.jsonnet"))
.sorted
assert(t.nonEmpty)
t.foreach { file =>
check(TestResources_new_test_suite.files, file, "new_test_suite")
}
}
}
}
Loading