Skip to content

Commit

Permalink
Cross-build cats module on scala3
Browse files Browse the repository at this point in the history
  • Loading branch information
RustedBones committed Nov 9, 2023
1 parent 074618a commit f3335b6
Show file tree
Hide file tree
Showing 42 changed files with 1,114 additions and 390 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:

- name: Build project
if: matrix.scala == '3'
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' shared/test test/test scalacheck/test
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' shared/test test/test scalacheck/test cats/test

- name: Make target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
Expand Down
5 changes: 3 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ val scala3Cond = "matrix.scala == '3'"
val scala3Projects = List(
"shared",
"test",
"scalacheck"
"scalacheck",
"cats"
)
ThisBuild / scalaVersion := scalaDefault
ThisBuild / crossScalaVersions := Seq(scala3, scala213, scala212)
Expand Down Expand Up @@ -321,9 +322,9 @@ lazy val cats = project
commonSettings,
moduleName := "magnolify-cats",
description := "Magnolia add-on for Cats",
crossScalaVersions := Seq(scala3, scala213, scala212),
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-core" % catsVersion % Provided,
"com.twitter" %% "algebird-core" % algebirdVersion % Test,
"org.typelevel" %% "cats-laws" % catsVersion % Test
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
* limitations under the License.
*/

package magnolify.cats.semiauto
package magnolify.cats

import cats.kernel.Band
import magnolia1._
import magnolia1.*

import scala.annotation.implicitNotFound
import scala.collection.compat._
import scala.collection.compat.*

object BandDerivation {
type Typeclass[T] = Band[T]

def join[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
def join[T](caseClass: CaseClass[Band, T]): Band[T] = {
val combineImpl = SemigroupMethods.combine(caseClass)
val combineNImpl = SemigroupMethods.combineN(caseClass)
val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)
Expand All @@ -39,7 +39,10 @@ object BandDerivation {

@implicitNotFound("Cannot derive Band for sealed trait")
private sealed trait Dispatchable[T]
def split[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???
def split[T: Dispatchable](sealedTrait: SealedTrait[Band, T]): Band[T] = ???

implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
implicit def gen[T]: Band[T] = macro Magnolia.gen[T]

@deprecated("Use gen instead", "0.7.0")
def apply[T]: Band[T] = macro Magnolia.gen[T]
}
150 changes: 150 additions & 0 deletions cats/src/main/scala-2/magnolify/cats/CatsMacros.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2019 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package magnolify.cats

import cats.Show
import cats.kernel.*

import scala.annotation.nowarn
import scala.reflect.macros.*

private object CatsMacros {

@nowarn("msg=parameter lp in method genShowMacro is never used")
def genShowMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.ShowDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genEqMacro is never used")
def genEqMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.EqDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genHashMacro is never used")
def genHashMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.HashDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genSemigroupMacro is never used")
def genSemigroupMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.SemigroupDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genMonoidMacro is never used")
def genMonoidMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.MonoidDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genCommutativeSemigroupMacro is never used")
def genCommutativeSemigroupMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.CommutativeSemigroupDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genCommutativeMonoidMacro is never used")
def genCommutativeMonoidMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.CommutativeMonoidDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genGroupMacro is never used")
def genGroupMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.GroupDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genCommutativeGroupMacro is never used")
def genCommutativeGroupMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.CommutativeGroupDerivation.gen[$wtt]"""
}

@nowarn("msg=parameter lp in method genBandMacro is never used")
def genBandMacro[T: c.WeakTypeTag](c: whitebox.Context)(lp: c.Tree): c.Tree = {
import c.universe.*
val wtt = weakTypeTag[T]
q"""_root_.magnolify.cats.BandDerivation.gen[$wtt]"""
}
}

// set implicit priority to avoid conflicts
// see: https://typelevel.org/cats/guidelines.html#implicit-instance-priority
// use shapeless.LowPriority so the
// provided cats type classes are always preferred
// triggers derivation as last resort
trait AutoDerivation extends LowPriority0Implicits

trait LowPriority0Implicits extends LowPriority1Implicits {
implicit def genShow[T](implicit lp: shapeless.LowPriority): Show[T] =
macro CatsMacros.genShowMacro[T]
// CommutativeGroup <: Group | CommutativeMonoid
implicit def genCommutativeGroup[T](implicit lp: shapeless.LowPriority): CommutativeGroup[T] =
macro CatsMacros.genCommutativeGroupMacro[T]
// Hash <: Eq
implicit def genHash[T](implicit lp: shapeless.LowPriority): Hash[T] =
macro CatsMacros.genHashMacro[T]
}

trait LowPriority1Implicits extends LowPriority2Implicits {
implicit def genEq[T](implicit lp: shapeless.LowPriority): Eq[T] =
macro CatsMacros.genEqMacro[T]
// Group <: Monoid
implicit def genGroup[T](implicit lp: shapeless.LowPriority): Group[T] =
macro CatsMacros.genGroupMacro[T]
}

trait LowPriority2Implicits extends LowPriority3Implicits {
// CommutativeMonoid <: Monoid | CommutativeSemigroup
implicit def genCommutativeMonoid[T](implicit lp: shapeless.LowPriority): CommutativeMonoid[T] =
macro CatsMacros.genCommutativeMonoidMacro[T]
}

trait LowPriority3Implicits extends LowPriority4Implicits {
// CommutativeSemigroup <: Semigroup
implicit def genCommutativeSemigroup[T](implicit
lp: shapeless.LowPriority
): CommutativeSemigroup[T] =
macro CatsMacros.genCommutativeSemigroupMacro[T]
// Monoid <: Semigroup
implicit def genMonoid[T](implicit lp: shapeless.LowPriority): Monoid[T] =
macro CatsMacros.genMonoidMacro[T]
}

trait LowPriority4Implicits extends LowPriority5Implicits {
// Band <: Semigroup
implicit def genBand[T](implicit lp: shapeless.LowPriority): Band[T] =
macro CatsMacros.genBandMacro[T]
}

trait LowPriority5Implicits {
implicit def genSemigroup[T](implicit lp: shapeless.LowPriority): Semigroup[T] =
macro CatsMacros.genSemigroupMacro[T]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
* limitations under the License.
*/

package magnolify.cats.semiauto
package magnolify.cats

import cats.kernel.CommutativeGroup
import magnolia1._
import magnolia1.*

import scala.annotation.implicitNotFound
import scala.collection.compat._
import scala.collection.compat.*

object CommutativeGroupDerivation {
type Typeclass[T] = CommutativeGroup[T]

def join[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
def join[T](caseClass: CaseClass[CommutativeGroup, T]): CommutativeGroup[T] = {
val emptyImpl = MonoidMethods.empty(caseClass)
val combineImpl = SemigroupMethods.combine(caseClass)
val combineNImpl = GroupMethods.combineN(caseClass)
Expand All @@ -47,7 +47,11 @@ object CommutativeGroupDerivation {

@implicitNotFound("Cannot derive CommutativeGroup for sealed trait")
private sealed trait Dispatchable[T]
def split[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???
def split[T: Dispatchable](sealedTrait: SealedTrait[CommutativeGroup, T]): CommutativeGroup[T] =
???

implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
implicit def gen[T]: CommutativeGroup[T] = macro Magnolia.gen[T]

@deprecated("Use gen instead", "0.7.0")
def apply[T]: CommutativeGroup[T] = macro Magnolia.gen[T]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
* limitations under the License.
*/

package magnolify.cats.semiauto
package magnolify.cats

import cats.kernel.CommutativeMonoid
import magnolia1._
import magnolia1.*

import scala.annotation.implicitNotFound
import scala.collection.compat._
import scala.collection.compat.*

object CommutativeMonoidDerivation {
type Typeclass[T] = CommutativeMonoid[T]

def join[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
def join[T](caseClass: CaseClass[CommutativeMonoid, T]): CommutativeMonoid[T] = {
val emptyImpl = MonoidMethods.empty(caseClass)
val combineImpl = SemigroupMethods.combine(caseClass)
val combineNImpl = MonoidMethods.combineN(caseClass)
Expand All @@ -43,7 +43,11 @@ object CommutativeMonoidDerivation {

@implicitNotFound("Cannot derive CommutativeMonoid for sealed trait")
private sealed trait Dispatchable[T]
def split[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???
def split[T: Dispatchable](sealedTrait: SealedTrait[CommutativeMonoid, T]): CommutativeMonoid[T] =
???

implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
implicit def gen[T]: CommutativeMonoid[T] = macro Magnolia.gen[T]

@deprecated("Use gen instead", "0.7.0")
def apply[T]: CommutativeMonoid[T] = macro Magnolia.gen[T]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
* limitations under the License.
*/

package magnolify.cats.semiauto
package magnolify.cats

import cats.kernel.CommutativeSemigroup
import magnolia1._
import magnolia1.*

import scala.annotation.implicitNotFound
import scala.collection.compat._
import scala.collection.compat.*

object CommutativeSemigroupDerivation {
type Typeclass[T] = CommutativeSemigroup[T]

def join[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
def join[T](caseClass: CaseClass[CommutativeSemigroup, T]): CommutativeSemigroup[T] = {
val combineImpl = SemigroupMethods.combine(caseClass)
val combineNImpl = SemigroupMethods.combineN(caseClass)
val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)
Expand All @@ -39,7 +39,12 @@ object CommutativeSemigroupDerivation {

@implicitNotFound("Cannot derive CommutativeSemigroup for sealed trait")
private sealed trait Dispatchable[T]
def split[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???
def split[T: Dispatchable](
sealedTrait: SealedTrait[CommutativeSemigroup, T]
): CommutativeSemigroup[T] = ???

implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
implicit def gen[T]: CommutativeSemigroup[T] = macro Magnolia.gen[T]

@deprecated("Use gen instead", "0.7.0")
def apply[T]: CommutativeSemigroup[T] = macro Magnolia.gen[T]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,24 @@
* limitations under the License.
*/

package magnolify.cats.semiauto
package magnolify.cats

import cats.Eq
import magnolia1._
import magnolia1.*

object EqDerivation {
type Typeclass[T] = Eq[T]

def join[T](caseClass: ReadOnlyCaseClass[Typeclass, T]): Typeclass[T] =
def join[T](caseClass: ReadOnlyCaseClass[Eq, T]): Eq[T] =
Eq.instance(EqMethods.join(caseClass))

def split[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] =
def split[T](sealedTrait: SealedTrait[Eq, T]): Eq[T] =
Eq.instance(EqMethods.split(sealedTrait))

implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
implicit def gen[T]: Eq[T] = macro Magnolia.gen[T]

@deprecated("Use gen instead", "0.7.0")
def apply[T]: Eq[T] = macro Magnolia.gen[T]
}

private object EqMethods {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
* limitations under the License.
*/

package magnolify.cats.semiauto
package magnolify.cats

import cats.Group
import magnolia1._
import magnolia1.*

import scala.annotation.implicitNotFound
import scala.collection.compat._
import scala.collection.compat.*

object GroupDerivation {
type Typeclass[T] = Group[T]

def join[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
def join[T](caseClass: CaseClass[Group, T]): Group[T] = {
val emptyImpl = MonoidMethods.empty(caseClass)
val combineImpl = SemigroupMethods.combine(caseClass)
val combineNImpl = GroupMethods.combineN(caseClass)
Expand All @@ -47,9 +47,12 @@ object GroupDerivation {

@implicitNotFound("Cannot derive Group for sealed trait")
private sealed trait Dispatchable[T]
def split[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???
def split[T: Dispatchable](sealedTrait: SealedTrait[Group, T]): Group[T] = ???

implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
implicit def gen[T]: Group[T] = macro Magnolia.gen[T]

@deprecated("Use gen instead", "0.7.0")
def apply[T]: Group[T] = macro Magnolia.gen[T]
}

private object GroupMethods {
Expand Down
Loading

0 comments on commit f3335b6

Please sign in to comment.