From 11e6d7ef76830b2e55b83aa6bfc3f52e80521f8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Wed, 8 Oct 2025 11:47:44 +0200 Subject: [PATCH 1/2] update Scala version to 2.13.17 and adjust the codebase --- .github/workflows/ci.yml | 4 ++-- .../scala/com/avsystem/commons/macros/MacroCommons.scala | 3 ++- .../avsystem/commons/mongo/typed/TypedMongoClient.scala | 9 ++++++--- .../commons/mongo/typed/TypedMongoDatabase.scala | 9 ++++++--- project/Commons.scala | 2 +- .../avsystem/commons/redis/commands/ReplyDecoders.scala | 6 +++--- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e74607ccd..d66f930e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.16] + scala: [2.13.17] java: [temurin@17, temurin@21] runs-on: ${{ matrix.os }} steps: @@ -75,7 +75,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.16] + scala: [2.13.17] java: [temurin@17] runs-on: ${{ matrix.os }} steps: diff --git a/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala b/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala index e4d106014..af286815d 100644 --- a/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala +++ b/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala @@ -283,6 +283,7 @@ trait MacroCommons extends CompatMacroCommons { bundle => .collectFirst { case (param, arg) if param.name == subSym.name => arg match { case Literal(Constant(value: T)) => value + case Literal(Constant(null)) => whenDefault case t if param.asTerm.isParamWithDefault && t.symbol.isSynthetic && t.symbol.name.decodedName.toString.contains("$default$") => whenDefault case t if classTag[T] == classTag[Tree] => t.asInstanceOf[T] @@ -1394,7 +1395,7 @@ trait MacroCommons extends CompatMacroCommons { bundle => // while typechecking case body and not after that. Therefore we need a macro which will inject itself exactly // into that moment. val fakeMatch = - q""" + q""" import scala.language.experimental.macros def $normName(tpref: $StringCls, value: $ScalaPkg.Any): $ScalaPkg.Any = macro $CommonsPkg.macros.misc.WhiteMiscMacros.normalizeGadtSubtype diff --git a/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoClient.scala b/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoClient.scala index ce7862359..9dfeae98a 100644 --- a/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoClient.scala +++ b/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoClient.scala @@ -57,11 +57,14 @@ class TypedMongoClient( def listDatabaseNames: Observable[String] = multi(optionalizeFirstArg(nativeClient.listDatabaseNames(sessionOrNull))) - def listDatabases: Observable[Document] = + @deprecated("Use listTypedDatabases or listRawDatabases instead", "2.25.0") + def listDatabases: Observable[Nothing] = ??? + + def listRawDatabases: Observable[Document] = multi(optionalizeFirstArg(nativeClient.listDatabases(sessionOrNull))) - def listDatabases[T: GenCodec]: Observable[T] = - listDatabases.map(doc => BsonValueInput.read[T](doc.toBsonDocument)) + def listTypedDatabases[T: GenCodec]: Observable[T] = + listRawDatabases.map(doc => BsonValueInput.read[T](doc.toBsonDocument)) //TODO: `watch` methods diff --git a/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoDatabase.scala b/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoDatabase.scala index 739a05005..9f2144b68 100644 --- a/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoDatabase.scala +++ b/mongo/jvm/src/main/scala/com/avsystem/commons/mongo/typed/TypedMongoDatabase.scala @@ -47,11 +47,14 @@ class TypedMongoDatabase( def listCollectionNames: Observable[String] = multi(optionalizeFirstArg(nativeDatabase.listCollectionNames(sessionOrNull))) - def listCollections: Observable[Document] = + @deprecated("Use listTypedCollections or listRawCollections instead", "2.25.0") + def listDatabases: Observable[Nothing] = ??? + + def listRawCollections: Observable[Document] = multi(optionalizeFirstArg(nativeDatabase.listCollections(sessionOrNull))) - def listCollections[T: GenCodec]: Observable[T] = - listCollections.map(doc => BsonValueInput.read[T](doc.toBsonDocument)) + def listTypedCollections[T: GenCodec]: Observable[T] = + listRawCollections.map(doc => BsonValueInput.read[T](doc.toBsonDocument)) def createCollection( name: String, diff --git a/project/Commons.scala b/project/Commons.scala index 795606515..e7d06bb63 100644 --- a/project/Commons.scala +++ b/project/Commons.scala @@ -65,7 +65,7 @@ object Commons extends ProjectGroup("commons") { Developer("ddworak", "Dawid Dworak", "d.dworak@avsystem.com", url("https://github.com/ddworak")), ), - scalaVersion := "2.13.16", + scalaVersion := "2.13.17", compileOrder := CompileOrder.Mixed, githubWorkflowTargetTags ++= Seq("v*"), diff --git a/redis/src/main/scala/com/avsystem/commons/redis/commands/ReplyDecoders.scala b/redis/src/main/scala/com/avsystem/commons/redis/commands/ReplyDecoders.scala index d8f537c5a..f9191385b 100644 --- a/redis/src/main/scala/com/avsystem/commons/redis/commands/ReplyDecoders.scala +++ b/redis/src/main/scala/com/avsystem/commons/redis/commands/ReplyDecoders.scala @@ -303,10 +303,10 @@ object ReplyDecoders { } val multiBulkAsXConsumerInfo: ReplyDecoder[XConsumerInfo] = - flatMultiBulkAsMap(bulkAsUTF8, undecoded).andThen(XConsumerInfo.apply) + flatMultiBulkAsMap(bulkAsUTF8, undecoded).andThen(XConsumerInfo.apply _) val multiBulkAsXGroupInfo: ReplyDecoder[XGroupInfo] = - flatMultiBulkAsMap(bulkAsUTF8, undecoded).andThen(XGroupInfo.apply) + flatMultiBulkAsMap(bulkAsUTF8, undecoded).andThen(XGroupInfo.apply _) def multiBulkAsXStreamInfoOf[Rec: RedisRecordCodec]: ReplyDecoder[XStreamInfo[Rec]] = flatMultiBulkAsMap(bulkAsUTF8, undecoded).andThen(XStreamInfo[Rec](_)) @@ -374,7 +374,7 @@ object ReplyDecoders { flatMultiBulkAsMap(bulkAs[A], bulkAs[B]) def flatMultiBulkAsRecord[R: RedisRecordCodec]: ReplyDecoder[R] = { - case ArrayMsg(elements: IndexedSeq[BulkStringMsg@unchecked]) if elements.forall(_.isInstanceOf[BulkStringMsg]) => + case ArrayMsg(elements: IndexedSeq[BulkStringMsg @unchecked]) if elements.forall(_.isInstanceOf[BulkStringMsg]) => RedisRecordCodec[R].read(elements) } From 8bbf6f45a9059fa5d2eee370c875d5409e0ff452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Thu, 20 Nov 2025 10:38:49 +0100 Subject: [PATCH 2/2] update Scala version to 2.13.18 and enhance default argument handling --- .github/workflows/ci.yml | 2 +- .../com/avsystem/commons/macros/MacroCommons.scala | 14 +++++++++++--- project/Commons.scala | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d66f930e8..a216906de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.17] + scala: [2.13.18] java: [temurin@17, temurin@21] runs-on: ${{ matrix.os }} steps: diff --git a/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala b/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala index af286815d..325fc8536 100644 --- a/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala +++ b/macros/src/main/scala/com/avsystem/commons/macros/MacroCommons.scala @@ -234,11 +234,18 @@ trait MacroCommons extends CompatMacroCommons { bundle => primaryConstructorOf(clsTpe).typeSignatureIn(clsTpe) } + private def isDefaultAnnotArg(tree: Tree): Boolean = { + (tree.tpe match { + case AnnotatedType(annots, _) => annots.exists(_.tree.tpe.typeSymbol.name.toString == "defaultArg") + case _ => false + }) || + tree.symbol != null && tree.symbol.isSynthetic && tree.symbol.name.decodedName.toString.contains("$default$") + } + lazy val treeRes: Res[Tree] = annotTree match { case Apply(constr, args) => val newArgs = (args zip constructorSig.paramLists.head) map { - case (arg, param) if param.asTerm.isParamWithDefault && arg.symbol != null && - arg.symbol.isSynthetic && arg.symbol.name.decodedName.toString.contains("$default$") => + case (arg, param) if param.asTerm.isParamWithDefault && isDefaultAnnotArg(arg) => if (findAnnotation(param, DefaultsToNameAT).nonEmpty) Ok(q"${subject.name.decodedName.toString}") else @@ -283,7 +290,7 @@ trait MacroCommons extends CompatMacroCommons { bundle => .collectFirst { case (param, arg) if param.name == subSym.name => arg match { case Literal(Constant(value: T)) => value - case Literal(Constant(null)) => whenDefault + case _ if param.asTerm.isParamWithDefault && isDefaultAnnotArg(arg) => whenDefault case t if param.asTerm.isParamWithDefault && t.symbol.isSynthetic && t.symbol.name.decodedName.toString.contains("$default$") => whenDefault case t if classTag[T] == classTag[Tree] => t.asInstanceOf[T] @@ -824,6 +831,7 @@ trait MacroCommons extends CompatMacroCommons { bundle => case class LitOrDefault[T: ClassTag](default: T) { def unapply(tree: Tree): Option[T] = tree match { case Literal(Constant(value: T)) => Some(value) + case _ if tree.tpe != null && tree.tpe.toString.endsWith("@scala.annotation.meta.defaultArg") => Some(default) case Select(_, TermName(n)) if n.startsWith("$lessinit$greater$default$") => Some(default) case _ => None } diff --git a/project/Commons.scala b/project/Commons.scala index e7d06bb63..b1be5b4c8 100644 --- a/project/Commons.scala +++ b/project/Commons.scala @@ -65,7 +65,7 @@ object Commons extends ProjectGroup("commons") { Developer("ddworak", "Dawid Dworak", "d.dworak@avsystem.com", url("https://github.com/ddworak")), ), - scalaVersion := "2.13.17", + scalaVersion := "2.13.18", compileOrder := CompileOrder.Mixed, githubWorkflowTargetTags ++= Seq("v*"),