Skip to content

Commit

Permalink
graalvm 22, fixed minor bugs, branch-level adt wrapping in JSON codecs
Browse files Browse the repository at this point in the history
  • Loading branch information
pshirshov committed Aug 29, 2024
1 parent 0be5071 commit 7ac72a5
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 21 deletions.
8 changes: 6 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sbtrelease.ReleasePlugin.autoImport.ReleaseTransformations.*

ThisBuild / scalaVersion := "2.13.13"
ThisBuild / scalaVersion := "2.13.14"

lazy val root = (project in file("."))
.settings(
Expand All @@ -21,8 +21,11 @@ lazy val root = (project in file("."))
"org.scalatest" %% "scalatest" % "3.2.18" % Test,
),
libraryDependencies ++= Seq(
"com.github.alexarchambault" %% "case-app" % "2.1.0-M26"
"com.github.alexarchambault" %% "case-app" % "2.1.0-M29"
),
// libraryDependencies ++= Seq(
// "org.graalvm.buildtools" % "graalvm-reachability-metadata" % "0.10.2"
// ),
libraryDependencies ++= Seq(
"io.circe" %% "circe-core",
"io.circe" %% "circe-generic",
Expand Down Expand Up @@ -63,6 +66,7 @@ lazy val root = (project in file("."))
graalVMNativeImageOptions ++= Seq(
"--no-fallback",
"-H:+ReportExceptionStackTraces",
"-H:+UnlockExperimentalVMOptions",
"--report-unsupported-elements-at-runtime",
"--enable-https",
"--enable-http",
Expand Down
3 changes: 3 additions & 0 deletions nixtest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

nix-shell --pure ./shell.nix --run ./test.sh
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version = 1.9.2
sbt.version = 1.10.1
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//addSbtPlugin("org.jetbrains.scala" % "sbt-ide-settings" % "1.1.1")
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.10.0")
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.10.4")
addSbtPlugin("io.7mind.izumi.sbt" % "sbt-izumi" % "0.0.101")
5 changes: 5 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/24.05.tar.gz") { } }:

pkgs.mkShell {
nativeBuildInputs = with pkgs.buildPackages; [ ncurses graalvm-ce sbt dotnet-sdk_7 ];
}
42 changes: 42 additions & 0 deletions src/main/resources/META-INF/native-image/reflect-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"name":"[Lizumi.distage.model.plan.ExecutableOp;"
},
{
"name":"[Ljava.lang.String;"
},
{
"name":"com.intellij.rt.execution.application.AppMainV2$Agent",
"methods":[{"name":"premain","parameterTypes":["java.lang.String","java.lang.instrument.Instrumentation"] }]
},
{
"name":"izumi.distage.provisioning.strategies.dynamicproxy.DynamicProxyProvider$",
"fields":[{"name":"MODULE$"}]
},
{
"name":"java.lang.ClassValue"
},
{
"name":"java.lang.String"
},
{
"name":"java.lang.invoke.VarHandle",
"methods":[{"name":"releaseFence","parameterTypes":[] }]
},
{
"name":"java.util.concurrent.atomic.AtomicBoolean",
"fields":[{"name":"value"}]
},
{
"name":"java.util.concurrent.atomic.AtomicReference",
"fields":[{"name":"value"}]
},
{
"name":"scala.Symbol",
"methods":[{"name":"apply","parameterTypes":["java.lang.String"] }]
},
{
"name":"sun.security.provider.SHA2$SHA256",
"methods":[{"name":"<init>","parameterTypes":[] }]
}
]
3 changes: 2 additions & 1 deletion src/main/scala/io/septimalmind/baboon/Baboon.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ case class Options(
csExcludeGlobalUsings: Option[Boolean],
omitMostRecentVersionSuffixFromPaths: Option[Boolean],
omitMostRecentVersionSuffixFromNamespaces: Option[Boolean],
csUseCompactAdtForm: Option[Boolean],
)

sealed trait RuntimeGenOpt
Expand Down Expand Up @@ -71,7 +72,7 @@ object Baboon {
!opts.csExcludeGlobalUsings.getOrElse(false),
opts.omitMostRecentVersionSuffixFromPaths.getOrElse(true),
opts.omitMostRecentVersionSuffixFromNamespaces.getOrElse(true),
csUseCompactAdtForm = true,
opts.csUseCompactAdtForm.getOrElse(true),
)
Injector
.NoCycles()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import izumi.fundamentals.platform.strings.TextTree.*

class CSNSJsonCodecGenerator(trans: CSTypeTranslator, tools: CSDefnTools)
extends CSCodecTranslator {
val csWrappedAdtBranchCodecs = true

override def translate(defn: DomainMember.User,
csRef: CSValue.CSType,
srcRef: CSValue.CSType,
domain: Domain,
evo: BaboonEvolution,
): TextTree[CSValue] = {

val version = domain.version
val (enc, dec) = defn.defn match {
case d: Typedef.Dto =>
Expand Down Expand Up @@ -135,21 +138,43 @@ class CSNSJsonCodecGenerator(trans: CSTypeTranslator, tools: CSDefnTools)
)
}

private def wrapAdtBranchEncoder(
branchName: String,
tree: TextTree[CSValue]
): TextTree[CSValue] = {
q"""new $nsJObject(new $nsJProperty("$branchName", $tree))"""
}

private def genAdtBodies(
name: CSValue.CSType,
a: Typedef.Adt
): (TextTree[CSValue.CSType], TextTree[Nothing]) = {
): (TextTree[CSValue], TextTree[Nothing]) = {

val branches = a.members.toList.map { m =>
val branchNs = q"${trans.adtNsName(a.id)}"
val branchName = m.name.name
val fqBranch = q"$branchNs.$branchName"
val routedBranchEncoder =
q"${fqBranch}_JsonCodec.Instance.Encode(($fqBranch)value)"

val branchEncoder = if (csWrappedAdtBranchCodecs) {
routedBranchEncoder
} else {
wrapAdtBranchEncoder(branchName, routedBranchEncoder)
}

val branchValue = if (csWrappedAdtBranchCodecs) {
q"wire"
} else {
q"head.Value"
}

(q"""if (value is $fqBranch)
|{
| return new $nsJObject(new $nsJProperty("$branchName", ${fqBranch}_JsonCodec.Instance.Encode(($fqBranch)value)));
| return $branchEncoder;
|}""".stripMargin, q"""if (head.Name == "$branchName")
|{
| return ${fqBranch}_JsonCodec.Instance.Decode(head.Value);
| return ${fqBranch}_JsonCodec.Instance.Decode($branchValue);
|}""".stripMargin)

}
Expand Down Expand Up @@ -206,19 +231,37 @@ class CSNSJsonCodecGenerator(trans: CSTypeTranslator, tools: CSDefnTools)
)
}

(q"""return new $nsJObject(
|${fields.map(_._1).join(",\n").shift(4)}
|);""".stripMargin, q"""var asObject = wire.Value<JObject>();
|
|if (asObject == null)
|{
| throw new ArgumentException($$"Cannot decode {wire} to ${name.name}: object expected");
|}
|
|return new $name(
|${fields.map(_._2).join(",\n").shift(4)}
|);
""".stripMargin)
val mainEnc = q"""new $nsJObject(
|${fields.map(_._1).join(",\n").shift(4)}
|)""".stripMargin

val fullEnc = d.id.owner match {
case Owner.Adt(_) if csWrappedAdtBranchCodecs =>
wrapAdtBranchEncoder(d.id.name.name, mainEnc)
case _ => mainEnc
}

val encBody = q"""return $fullEnc;"""

val fullDec = d.id.owner match {
case Owner.Adt(_) if csWrappedAdtBranchCodecs =>
q"wire.Value<JObject>().Properties().First().Value.Value<JObject>()"
case _ => q"wire.Value<JObject>()"
}

val decBody = q"""var asObject = $fullDec;
|
|if (asObject == null)
|{
| throw new ArgumentException($$"Cannot decode {wire} to ${name.name}: object expected");
|}
|
|return new $name(
|${fields.map(_._2).join(",\n").shift(4)}
|);
""".stripMargin

(encBody, decBody)
}

private def mkEncoder(tpe: TypeRef,
Expand Down
18 changes: 18 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash

set -x
set -e

sbt GraalVMNativeImage/packageBin

target/graalvm-native-image/baboon \
--model-dir ./src/test/resources/baboon/ \
--output ./test/cs-stub/ConversionsTest/Generated \
--test-output ./test/cs-stub/ConversionsTest/Generated
pushd .

cd ./test/cs-stub
dotnet build
dotnet test ConversionsTest/ConversionsTest.csproj

popd
2 changes: 2 additions & 0 deletions test/cs-stub/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Generated/

global.json

bin/
obj/
/packages/
Expand Down

0 comments on commit 7ac72a5

Please sign in to comment.