diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e83242e3..c8bced71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.12.16, 2.13.8, 3.1.3] + scala: [2.12.17, 2.13.10, 3.2.0] java: [temurin@11] project: [rootJS, rootJVM] runs-on: ${{ matrix.os }} @@ -99,8 +99,8 @@ jobs: if: matrix.java == 'temurin@11' run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' doc - - name: Check Doc Site (2.13.8 JVM only) - if: matrix.scala == '2.13.8' && matrix.project == 'rootJVM' + - name: Check Doc Site (2.13.10 JVM only) + if: matrix.scala == '2.13.10' && matrix.project == 'rootJVM' run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' docs/makeSite - name: Make target directories @@ -125,7 +125,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.8] + scala: [2.13.10] java: [temurin@11] runs-on: ${{ matrix.os }} steps: @@ -162,62 +162,62 @@ jobs: ~/Library/Caches/Coursier/v1 key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - - name: Download target directories (2.12.16, rootJS) + - name: Download target directories (2.12.17, rootJS) uses: actions/download-artifact@v2 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.16-rootJS + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.17-rootJS - - name: Inflate target directories (2.12.16, rootJS) + - name: Inflate target directories (2.12.17, rootJS) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (2.12.16, rootJVM) + - name: Download target directories (2.12.17, rootJVM) uses: actions/download-artifact@v2 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.16-rootJVM + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.17-rootJVM - - name: Inflate target directories (2.12.16, rootJVM) + - name: Inflate target directories (2.12.17, rootJVM) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (2.13.8, rootJS) + - name: Download target directories (2.13.10, rootJS) uses: actions/download-artifact@v2 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.8-rootJS + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.10-rootJS - - name: Inflate target directories (2.13.8, rootJS) + - name: Inflate target directories (2.13.10, rootJS) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (2.13.8, rootJVM) + - name: Download target directories (2.13.10, rootJVM) uses: actions/download-artifact@v2 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.8-rootJVM + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.10-rootJVM - - name: Inflate target directories (2.13.8, rootJVM) + - name: Inflate target directories (2.13.10, rootJVM) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (3.1.3, rootJS) + - name: Download target directories (3.2.0, rootJS) uses: actions/download-artifact@v2 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-3.1.3-rootJS + name: target-${{ matrix.os }}-${{ matrix.java }}-3.2.0-rootJS - - name: Inflate target directories (3.1.3, rootJS) + - name: Inflate target directories (3.2.0, rootJS) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (3.1.3, rootJVM) + - name: Download target directories (3.2.0, rootJVM) uses: actions/download-artifact@v2 with: - name: target-${{ matrix.os }}-${{ matrix.java }}-3.1.3-rootJVM + name: target-${{ matrix.os }}-${{ matrix.java }}-3.2.0-rootJVM - - name: Inflate target directories (3.1.3, rootJVM) + - name: Inflate target directories (3.2.0, rootJVM) run: | tar xf targets.tar rm targets.tar @@ -237,11 +237,11 @@ jobs: run: sbt '++${{ matrix.scala }}' tlRelease coverage: - name: Generate coverage report (2.13.8 JVM only) + name: Generate coverage report (2.13.10 JVM only) strategy: matrix: os: [ubuntu-latest] - scala: [2.13.8] + scala: [2.13.10] java: [temurin@11] runs-on: ${{ matrix.os }} steps: diff --git a/.scalafmt.conf b/.scalafmt.conf index 5fbe01d2..2ee8f302 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,3 +1,3 @@ -version = "3.5.9" +version = "3.6.1" runner.dialect = Scala213Source3 project.includePaths = [] # disables formatting diff --git a/build.sbt b/build.sbt index 2fd43303..cfadb908 100644 --- a/build.sbt +++ b/build.sbt @@ -1,9 +1,9 @@ ThisBuild / tlBaseVersion := "0.4" // Our Scala versions. -lazy val `scala-2.12` = "2.12.16" -lazy val `scala-2.13` = "2.13.8" -lazy val `scala-3.0` = "3.1.3" +lazy val `scala-2.12` = "2.12.17" +lazy val `scala-2.13` = "2.13.10" +lazy val `scala-3.0` = "3.2.0" ThisBuild / scalaVersion := `scala-2.13` ThisBuild / crossScalaVersions := @@ -69,7 +69,7 @@ ThisBuild / libraryDependencySchemes ++= Seq( ) // This is used in a couple places -lazy val fs2Version = "3.2.14" +lazy val fs2Version = "3.3.0" lazy val natchezVersion = "0.1.6" // Global Settings @@ -176,7 +176,7 @@ lazy val refined = crossProject(JVMPlatform, JSPlatform) .settings(commonSettings) .settings( libraryDependencies ++= Seq( - "eu.timepit" %%% "refined" % "0.9.29", + "eu.timepit" %%% "refined" % "0.10.1", ) ) @@ -189,8 +189,8 @@ lazy val circe = crossProject(JVMPlatform, JSPlatform) .settings( name := "skunk-circe", libraryDependencies ++= Seq( - "io.circe" %%% "circe-core" % "0.14.2", - "io.circe" %%% "circe-parser" % "0.14.2" + "io.circe" %%% "circe-core" % "0.14.3", + "io.circe" %%% "circe-parser" % "0.14.3" ) ) diff --git a/modules/core/shared/src/main/scala-3/syntax/StringContextOps.scala b/modules/core/shared/src/main/scala-3/syntax/StringContextOps.scala index f8e42136..b6c741bf 100644 --- a/modules/core/shared/src/main/scala-3/syntax/StringContextOps.scala +++ b/modules/core/shared/src/main/scala-3/syntax/StringContextOps.scala @@ -61,77 +61,79 @@ object StringContextOps { // Our prefix looks like this, and the stringy parts of the interpolation will be a non-empty // list of string expressions. We just know this because of the way interpolator desugaring // works. If it doesn't work something bad has happened. - val strings: List[String] = + val strings: Either[Expr[Any], List[String]] = sc match { - case '{ StringContext(${Varargs(Exprs(parts))}: _*) } => parts.toList + case '{ StringContext(${Varargs(Exprs(parts))}: _*) } => Right(parts.toList) case _ => - report.error(s"StringContext arguments must be literals.") - return '{???} + Left('{ compiletime.error(s"StringContext arguments must be literals.") }) } // The interpolated args are a list of size `parts.length - 1`. We also just know this. val args: List[Expr[Any]] = { - val Varargs(args) = argsExpr + val Varargs(args) = argsExpr: @unchecked // we just know this. right? args.toList } // Weave the strings and args together, and accumulate a single encoder. - val lastPart: Expr[Part] = '{Str(${Expr(strings.last)})} - val (parts, encoders): (List[Expr[Part]], List[Expr[Any]]) = - (strings zip args).foldRight((List[Expr[Part]](lastPart), List.empty[Expr[Any]])) { + val partsEncoders: Either[Expr[Any], (List[Expr[Part]], List[Expr[Any]])] = strings.flatMap { strings => + val lastPart: Expr[Part] = '{Str(${Expr(strings.last)})} + (strings zip args).reverse.foldLeftM((List[Expr[Part]](lastPart), List.empty[Expr[Any]])) { - case ((str, arg), (parts, es)) => + case ((parts, es), (str, arg)) => - if (str.endsWith("#")) { + if (str.endsWith("#")) { - // Interpolations like "...#$foo ..." require `foo` to be a String. - arg match { - case '{ $s: String } => ('{Str(${Expr(str.dropRight(1))})} :: '{Str($s)} :: parts, es) - case '{ $a: t } => + // Interpolations like "...#$foo ..." require `foo` to be a String. + arg match { + case '{ $s: String } => Right(('{Str(${Expr(str.dropRight(1))})} :: '{Str($s)} :: parts, es)) + case '{ $a: t } => report.error(s"Found ${Type.show[t]}, expected String.}", a) - return '{???} /// + Left('{ compiletime.error("Expected String") }) /// } - } else { + } else { - arg match { + arg match { - // The interpolated thing is an Encoder. - case '{ $e: Encoder[t] } => - val newParts = '{Str(${Expr(str)})} :: '{Par($e.sql)} :: parts - val newEncoders = '{ $e : Encoder[t] } :: es - (newParts, newEncoders) + // The interpolated thing is an Encoder. + case '{ $e: Encoder[t] } => + val newParts = '{Str(${Expr(str)})} :: '{Par($e.sql)} :: parts + val newEncoders = '{ $e : Encoder[t] } :: es + Right((newParts, newEncoders)) - // The interpolated thing is a Fragment[Void] - case '{ $f: Fragment[Void] } => - val newParts = '{Str(${Expr(str)})} :: '{Emb($f.parts)} :: parts - (newParts, es) + // The interpolated thing is a Fragment[Void] + case '{ $f: Fragment[Void] } => + val newParts = '{Str(${Expr(str)})} :: '{Emb($f.parts)} :: parts + Right((newParts, es)) - // The interpolated thing is a Fragment[A] for some A other than Void - case '{ $f: Fragment[a] } => - val newParts = '{Str(${Expr(str)})} :: '{Emb($f.parts)} :: parts - val newEncoders = '{ $f.encoder : Encoder[a] } :: es - (newParts, newEncoders) + // The interpolated thing is a Fragment[A] for some A other than Void + case '{ $f: Fragment[a] } => + val newParts = '{Str(${Expr(str)})} :: '{Emb($f.parts)} :: parts + val newEncoders = '{ $f.encoder : Encoder[a] } :: es + Right((newParts, newEncoders)) - case '{ $a: t } => + case '{ $a: t } => report.error(s"Found ${Type.show[t]}, expected String, Encoder, or Fragment.", a) - return '{???} + Left('{compiletime.error("Expected String, Encoder, or Fragment.")}) - } + } - } + } + } } - val finalEnc: Expr[Any] = - if (encoders.isEmpty) '{ Void.codec } - else encoders.reduceLeft { - case ('{$a : Encoder[a]}, '{ $b : Encoder[b] }) => '{$a ~ $b} - } + partsEncoders.map { (parts, encoders) => + val finalEnc: Expr[Any] = + if (encoders.isEmpty) '{ Void.codec } + else encoders.reduceLeft { + case ('{$a : Encoder[a]}, '{ $b : Encoder[b] }) => '{$a ~ $b} + } - finalEnc match { - case '{ $e : Encoder[t] } => '{ fragmentFromParts[t](${Expr.ofList(parts)}, $e, $origin) } - } + finalEnc match { + case '{ $e : Encoder[t] } => '{ fragmentFromParts[t](${Expr.ofList(parts)}, $e, $origin) } + } + }.merge } diff --git a/project/build.properties b/project/build.properties index 22af2628..6a9f0388 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.7.1 +sbt.version=1.7.3 diff --git a/project/plugins.sbt b/project/plugins.sbt index 7aafe11e..e9e19f09 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,11 +3,11 @@ ThisBuild / libraryDependencySchemes ++= Seq( "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always ) -addSbtPlugin("org.typelevel" % "sbt-typelevel" % "0.4.15") -addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.10.2") +addSbtPlugin("org.typelevel" % "sbt-typelevel" % "0.4.16") +addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.10.3") addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.4.1") addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.3") -addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.6.3") -addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.3") -addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.2") +addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.6.4") +addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.6") +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.6") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.11.0")