Skip to content

Commit

Permalink
make annotation type signature more specific
Browse files Browse the repository at this point in the history
  • Loading branch information
hughsimpson committed Jan 13, 2025
1 parent 23b09cd commit adc83bd
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 66 deletions.
11 changes: 6 additions & 5 deletions src/core/impl.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package magnolia2

import scala.annotation.Annotation
import scala.compiletime.*
import scala.deriving.Mirror
import scala.reflect.*
Expand Down Expand Up @@ -85,7 +86,7 @@ object CaseClassDerivation:
parameters,
IArray(anns[A]*),
IArray(inheritedAnns[A]*),
IArray[Any](typeAnns[A]*)
IArray[Annotation](typeAnns[A]*)
):
def construct[PType: ClassTag](makeParam: Param => PType): A =
product.fromProduct(Tuple.fromArray(params.map(makeParam).to(Array)))
Expand Down Expand Up @@ -120,9 +121,9 @@ object CaseClassDerivation:
}

inline def paramsFromMaps[Typeclass[_], A, Labels <: Tuple, Params <: Tuple](
annotations: Map[String, List[Any]],
inheritedAnnotations: Map[String, List[Any]],
typeAnnotations: Map[String, List[Any]],
annotations: Map[String, List[Annotation]],
inheritedAnnotations: Map[String, List[Annotation]],
typeAnnotations: Map[String, List[Annotation]],
repeated: Map[String, Boolean],
defaults: Map[String, Option[() => Any]],
idx: Int = 0
Expand Down Expand Up @@ -165,7 +166,7 @@ trait SealedTraitDerivation:
typeInfo[A],
IArray(subtypesFromMirror[A, m.MirroredElemTypes](m)*),
IArray.from(anns[A]),
IArray(paramTypeAnns[A]*),
IArray.from(paramTypeAnns[A]),
isEnum[A],
IArray.from(inheritedAnns[A])
)
Expand Down
38 changes: 19 additions & 19 deletions src/core/interface.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package magnolia2

import scala.annotation.tailrec
import scala.annotation.{Annotation, tailrec}
import scala.reflect.*

case class TypeInfo(
Expand All @@ -15,8 +15,8 @@ object CaseClass:
val label: String,
val index: Int,
val repeated: Boolean,
val annotations: IArray[Any],
val typeAnnotations: IArray[Any]
val annotations: IArray[Annotation],
val typeAnnotations: IArray[Annotation]
) extends Serializable:

type PType
Expand All @@ -42,7 +42,7 @@ object CaseClass:
* default argument value, if any
*/
def default: Option[PType]
def inheritedAnnotations: IArray[Any] = IArray.empty[Any]
def inheritedAnnotations: IArray[Annotation] = IArray.empty[Annotation]
override def toString: String = s"Param($label)"

object Param:
Expand All @@ -53,9 +53,9 @@ object CaseClass:
repeated: Boolean,
cbn: CallByNeed[F[P]],
defaultVal: CallByNeed[Option[P]],
annotations: IArray[Any],
inheritedAnns: IArray[Any],
typeAnnotations: IArray[Any]
annotations: IArray[Annotation],
inheritedAnns: IArray[Annotation],
typeAnnotations: IArray[Annotation]
): Param[F, T] =
new CaseClass.Param[F, T](
name,
Expand Down Expand Up @@ -89,9 +89,9 @@ abstract class CaseClass[Typeclass[_], Type](
val isObject: Boolean,
val isValueClass: Boolean,
val params: IArray[CaseClass.Param[Typeclass, Type]],
val annotations: IArray[Any],
val inheritedAnnotations: IArray[Any] = IArray.empty[Any],
val typeAnnotations: IArray[Any]
val annotations: IArray[Annotation],
val inheritedAnnotations: IArray[Annotation] = IArray.empty[Annotation],
val typeAnnotations: IArray[Annotation]
) extends Serializable:

type Param = CaseClass.Param[Typeclass, Type]
Expand All @@ -113,9 +113,9 @@ abstract class CaseClass[Typeclass[_], Type](
repeated: Boolean,
cbn: CallByNeed[Typeclass[P]],
defaultVal: CallByNeed[Option[P]],
annotations: IArray[Any],
inheritedAnns: IArray[Any],
typeAnnotations: IArray[Any]
annotations: IArray[Annotation],
inheritedAnns: IArray[Annotation],
typeAnnotations: IArray[Annotation]
): Param =
new CaseClass.Param[Typeclass, Type](
name,
Expand All @@ -141,10 +141,10 @@ end CaseClass
case class SealedTrait[Typeclass[_], Type](
typeInfo: TypeInfo,
subtypes: IArray[SealedTrait.Subtype[Typeclass, Type, _]],
annotations: IArray[Any],
typeAnnotations: IArray[Any],
annotations: IArray[Annotation],
typeAnnotations: IArray[(String, List[Annotation])],
isEnum: Boolean,
inheritedAnnotations: IArray[Any]
inheritedAnnotations: IArray[Annotation]
) extends Serializable:

type Subtype[S] = SealedTrait.SubtypeValue[Typeclass, Type, S]
Expand Down Expand Up @@ -191,9 +191,9 @@ object SealedTrait:
*/
class Subtype[Typeclass[_], Type, SType](
val typeInfo: TypeInfo,
val annotations: IArray[Any],
val inheritedAnnotations: IArray[Any],
val typeAnnotations: IArray[Any],
val annotations: IArray[Annotation],
val inheritedAnnotations: IArray[Annotation],
val typeAnnotations: IArray[(String, List[Annotation])],
val isObject: Boolean,
callByNeed: CallByNeed[Typeclass[SType]],
isType: Type => Boolean,
Expand Down
79 changes: 40 additions & 39 deletions src/core/macro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package magnolia2
import scala.quoted.*
import scala.annotation.meta.field
import scala.annotation.Annotation
import scala.reflect.ClassTag

object Macro:

Expand All @@ -15,19 +16,19 @@ object Macro:
inline def isEnum[T]: Boolean =
${ isEnum[T] }

inline def anns[T]: List[Any] =
inline def anns[T]: List[Annotation] =
${ anns[T] }

inline def inheritedAnns[T]: List[Any] =
inline def inheritedAnns[T]: List[Annotation] =
${ inheritedAnns[T] }

inline def typeAnns[T]: List[Any] =
inline def typeAnns[T]: List[Annotation] =
${ typeAnns[T] }

inline def paramAnns[T]: List[(String, List[Any])] =
inline def paramAnns[T]: List[(String, List[Annotation])] =
${ paramAnns[T] }

inline def inheritedParamAnns[T]: List[(String, List[Any])] =
inline def inheritedParamAnns[T]: List[(String, List[Annotation])] =
${ inheritedParamAnns[T] }

inline def isValueClass[T]: Boolean =
Expand All @@ -36,7 +37,7 @@ object Macro:
inline def defaultValue[T]: List[(String, Option[() => Any])] =
${ defaultValue[T] }

inline def paramTypeAnns[T]: List[(String, List[Any])] =
inline def paramTypeAnns[T]: List[(String, List[Annotation])] =
${ paramTypeAnns[T] }

inline def repeated[T]: List[(String, Boolean)] =
Expand All @@ -60,26 +61,26 @@ object Macro:

def paramTypeAnns[T: Type](using
q: Quotes
): Expr[List[(String, List[Any])]] =
): Expr[List[(String, List[Annotation])]] =
new CollectAnnotations[q.type, T].paramTypeAnns

def anns[T: Type](using q: Quotes): Expr[List[Any]] =
def anns[T: Type](using q: Quotes): Expr[List[Annotation]] =
new CollectAnnotations[q.type, T].anns

def inheritedAnns[T: Type](using q: Quotes): Expr[List[Any]] =
def inheritedAnns[T: Type](using q: Quotes): Expr[List[Annotation]] =
new CollectAnnotations[q.type, T].inheritedAnns

def typeAnns[T: Type](using q: Quotes): Expr[List[Any]] =
def typeAnns[T: Type](using q: Quotes): Expr[List[Annotation]] =
new CollectAnnotations[q.type, T].typeAnns

def paramAnns[T: Type](using
q: Quotes
): Expr[List[(String, List[Any])]] =
): Expr[List[(String, List[Annotation])]] =
new CollectAnnotations[q.type, T].paramAnns

def inheritedParamAnns[T: Type](using
q: Quotes
): Expr[List[(String, List[Any])]] =
): Expr[List[(String, List[Annotation])]] =
new CollectAnnotations[q.type, T].inheritedParamAnns

def isValueClass[T: Type](using Quotes): Expr[Boolean] =
Expand Down Expand Up @@ -192,14 +193,14 @@ object Macro:

val tpe: TypeRepr = TypeRepr.of[T]

def anns: Expr[List[Any]] =
def anns: Expr[List[Annotation]] =
Expr.ofList {
tpe.typeSymbol.annotations
.filter(filterAnnotation)
.map(_.asExpr.asInstanceOf[Expr[Any]])
.map(_.asExpr.asInstanceOf[Expr[Annotation]])
}

def inheritedAnns: Expr[List[Any]] =
def inheritedAnns: Expr[List[Annotation]] =
Expr.ofList {
tpe.baseClasses
.filterNot(isObjectOrScala)
Expand All @@ -208,10 +209,10 @@ object Macro:
} // skip self
.flatten
.filter(filterAnnotation)
.map(_.asExpr.asInstanceOf[Expr[Any]])
.map(_.asExpr.asInstanceOf[Expr[Annotation]])
}

def typeAnns: Expr[List[Any]] =
def typeAnns: Expr[List[Annotation]] =
val symbol: Option[Symbol] =
if tpe.typeSymbol.isNoSymbol then None else Some(tpe.typeSymbol)

Expand All @@ -231,7 +232,7 @@ object Macro:
}
.flatMap(loopForAnnotations)
.filter(filterAnnotation)
.map { _.asExpr.asInstanceOf[Expr[Any]] }
.map { _.asExpr.asInstanceOf[Expr[Annotation]] }
case _ =>
List.empty
}
Expand All @@ -248,8 +249,8 @@ object Macro:
}
.filter(_._2.nonEmpty)

def paramTypeAnns: Expr[List[(String, List[Any])]] =
liftTermsDict(paramTypeAnnsOnTerms)
def paramTypeAnns: Expr[List[(String, List[Annotation])]] =
liftTermsDict(paramTypeAnnsOnTerms).asInstanceOf[Expr[List[(String, List[Annotation])]]]

def paramAnnsOnTerms: List[(String, List[Term])] =
val terms = (annotationsFromConstructorOnTerms(
Expand All @@ -259,8 +260,8 @@ object Macro:

groupByNameOnTerms(terms)

def paramAnns: Expr[List[(String, List[Any])]] =
liftTermsDict(paramAnnsOnTerms)
def paramAnns: Expr[List[(String, List[Annotation])]] =
liftTermsDict(paramAnnsOnTerms).asInstanceOf[Expr[List[(String, List[Annotation])]]]

def inheritedParamAnnsOnTerms: List[(String, List[Term])] =
val annTerms: List[(String, List[Term])] =
Expand All @@ -279,8 +280,8 @@ object Macro:

groupByNameOnTerms(annTerms)

def inheritedParamAnns: Expr[List[(String, List[Any])]] =
liftTermsDict(inheritedParamAnnsOnTerms)
def inheritedParamAnns: Expr[List[(String, List[Annotation])]] =
liftTermsDict(inheritedParamAnnsOnTerms).asInstanceOf[Expr[List[(String, List[Annotation])]]]

private def loopForAnnotations(t: TypeRepr): List[Term] =
t match
Expand Down Expand Up @@ -310,10 +311,10 @@ object Macro:

private def annotationsfromConstructor(
from: Symbol
): List[(String, List[Expr[Any]])] =
): List[(String, List[Expr[Annotation]])] =
annotationsFromConstructorOnTerms(from)
.map { p =>
p._1 -> p._2.map(_.asExpr.asInstanceOf[Expr[Any]])
p._1 -> p._2.map(_.asExpr.asInstanceOf[Expr[Annotation]])
}

private def annotationsFromDeclarationsOnTerms(
Expand All @@ -327,10 +328,10 @@ object Macro:

private def annotationsFromDeclarations(
from: Symbol
): List[(String, List[Expr[Any]])] =
): List[(String, List[Expr[Annotation]])] =
annotationsFromDeclarationsOnTerms(from)
.map { p =>
p._1 -> p._2.map(_.asExpr.asInstanceOf[Expr[Any]])
p._1 -> p._2.map(_.asExpr.asInstanceOf[Expr[Annotation]])
}

private def groupByNameOnTerms(
Expand All @@ -346,7 +347,7 @@ object Macro:
bc.fullName.startsWith("scala.")

private def filterAnnotation(a: Term): Boolean =
(a.tpe <:< TypeRepr.of[scala.annotation.Annotation]) &&
(a.tpe <:< TypeRepr.of[Annotation]) &&
(a.tpe.typeSymbol.maybeOwner.isNoSymbol ||
a.tpe.typeSymbol.owner.fullName != "scala.annotation.internal")

Expand Down Expand Up @@ -384,7 +385,7 @@ object Macro:
case Some(expr) =>
'{ new CallByNeed(() => Some(($expr).asInstanceOf[P])) }

def selectFromDict(
def selectFromDict[T: Type](
dict: List[(String, List[Term])],
name: String
) =
Expand All @@ -394,11 +395,11 @@ object Macro:
dict,
name
)
.map(_.asExpr)
.map(_.asExprOf[T])
}

def toIArray(es: Expr[List[Any]]): Expr[IArray[Any]] =
'{ IArray($es: _*) }
def toAnnIArray(es: Expr[List[Annotation]]): Expr[IArray[Annotation]] =
'{ IArray[Annotation]($es: _*) }

extension [B: Type](e: Expr[B])
def asCallByNeedExpr: Expr[CallByNeed[B]] =
Expand Down Expand Up @@ -438,24 +439,24 @@ object Macro:
selectDefault[p](defaultValueOnTerms[a], paramSymbol.name)

val annotations =
toIArray(
selectFromDict(
toAnnIArray(
selectFromDict[Annotation](
new CollectAnnotations[q.type, A].paramAnnsOnTerms,
paramSymbol.name
)
)

val inheritedAnnotations =
toIArray(
selectFromDict(
toAnnIArray(
selectFromDict[Annotation](
new CollectAnnotations[q.type, A].inheritedParamAnnsOnTerms,
paramSymbol.name
)
)

val typeAnnotations =
toIArray(
selectFromDict(
toAnnIArray(
selectFromDict[Annotation](
new CollectAnnotations[q.type, A].paramTypeAnnsOnTerms,
paramSymbol.name
)
Expand Down
7 changes: 4 additions & 3 deletions src/core/magnolia.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package magnolia2

import scala.annotation.Annotation
import scala.compiletime.*
import scala.deriving.Mirror
import scala.reflect.*
Expand Down Expand Up @@ -30,9 +31,9 @@ trait CommonDerivation[TypeClass[_]]:
): Typeclass[A] = join(CaseClassDerivation.fromMirror(product))

inline def getParams__[T, Labels <: Tuple, Params <: Tuple](
annotations: Map[String, List[Any]],
inheritedAnnotations: Map[String, List[Any]],
typeAnnotations: Map[String, List[Any]],
annotations: Map[String, List[Annotation]],
inheritedAnnotations: Map[String, List[Annotation]],
typeAnnotations: Map[String, List[Annotation]],
repeated: Map[String, Boolean],
defaults: Map[String, Option[() => Any]],
idx: Int = 0
Expand Down

0 comments on commit adc83bd

Please sign in to comment.