Skip to content

Commit

Permalink
Merge pull request #559 from hughsimpson/annotation_tests
Browse files Browse the repository at this point in the history
uncomment and fix java annotation tests
  • Loading branch information
adamw authored Jan 13, 2025
2 parents e046c3d + 5e533af commit 9a4cfc6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 28 deletions.
35 changes: 18 additions & 17 deletions core/src/main/scala/magnolia1/macro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,14 @@ object Macro:

private val tpe: TypeRepr = TypeRepr.of[T]

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

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

def typeAnns: Expr[List[Any]] = {
def typeAnns: Expr[List[scala.annotation.Annotation]] = {

def getAnnotations(t: TypeRepr): List[Term] = t match
case AnnotatedType(inner, ann) => ann :: getAnnotations(inner)
Expand All @@ -212,28 +212,28 @@ object Macro:
.collect { case t: TypeTree => t.tpe }
.flatMap(getAnnotations)
.filter(filterAnnotation)
.map(_.asExpr.asInstanceOf[Expr[Any]])
.map(_.asExpr.asInstanceOf[Expr[scala.annotation.Annotation]])
case _ =>
// Best effort in case whe -Yretain-trees is not used
// Does not support class parent annotations (in the extends clouse)
tpe.baseClasses
.map(tpe.baseType(_))
.flatMap(getAnnotations(_))
.filter(filterAnnotation)
.map(_.asExpr)
.map(_.asExprOf[scala.annotation.Annotation])
}
}
}

def paramAnns: Expr[List[(String, List[Any])]] =
def paramAnns: Expr[List[(String, List[scala.annotation.Annotation])]] =
Expr.ofList {
groupByParamName {
(fromConstructor(tpe.typeSymbol) ++ fromDeclarations(tpe.typeSymbol))
.filter { case (_, anns) => anns.nonEmpty }
}
}

def inheritedParamAnns: Expr[List[(String, List[Any])]] =
def inheritedParamAnns: Expr[List[(String, List[scala.annotation.Annotation])]] =
Expr.ofList {
groupByParamName {
tpe.baseClasses
Expand All @@ -248,25 +248,25 @@ object Macro:
}
}

private def fromConstructor(from: Symbol): List[(String, List[Expr[Any]])] =
private def fromConstructor(from: Symbol): List[(String, List[Expr[scala.annotation.Annotation]])] =
from.primaryConstructor.paramSymss.flatten.map { field =>
field.name -> field.annotations
.filter(filterAnnotation)
.map(_.asExpr.asInstanceOf[Expr[Any]])
.map(_.asExpr.asInstanceOf[Expr[scala.annotation.Annotation]])
}

private def fromDeclarations(
from: Symbol,
inherited: Boolean = false
): List[(String, List[Expr[Any]])] =
): List[(String, List[Expr[scala.annotation.Annotation]])] =
from.fieldMembers.collect { case field: Symbol =>
val annotations = if (!inherited) field.annotations else field.allOverriddenSymbols.flatMap(_.annotations).toList
field.name -> annotations
.filter(filterAnnotation)
.map(_.asExpr.asInstanceOf[Expr[Any]])
.map(_.asExpr.asInstanceOf[Expr[scala.annotation.Annotation]])
}

private def groupByParamName(anns: List[(String, List[Expr[Any]])]) =
private def groupByParamName(anns: List[(String, List[Expr[scala.annotation.Annotation]])]) =
anns
.groupBy { case (name, _) => name }
.toList
Expand All @@ -277,7 +277,8 @@ object Macro:
bc.name.contains("java.lang.Object") || bc.fullName.startsWith("scala.")

private def filterAnnotation(a: Term): Boolean =
a.tpe.typeSymbol.maybeOwner.isNoSymbol ||
(a.tpe.typeSymbol.owner.fullName != "scala.annotation.internal" &&
a.tpe.typeSymbol.owner.fullName != "jdk.internal")
scala.util.Try(a.tpe <:< TypeRepr.of[scala.annotation.Annotation]).toOption.contains(true) &&
(a.tpe.typeSymbol.maybeOwner.isNoSymbol ||
(a.tpe.typeSymbol.owner.fullName != "scala.annotation.internal" &&
a.tpe.typeSymbol.owner.fullName != "jdk.internal"))
}
20 changes: 9 additions & 11 deletions test/src/test/scala/magnolia1/tests/AnnotationsTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,15 @@ class AnnotationsTests extends munit.FunSuite:
assertEquals(subtypeAnnotations(1).mkString, "MyAnnotation(2)")
}

// TODO - not compiling
// test("serialize case class with Java annotations by skipping them") {
// val res = Show.derived[MyDto].show(MyDto("foo", 42))
// assertEquals(res, "MyDto{MyAnnotation(0)}(foo=foo,bar=42)")
// }

// TODO - not compiling
// test("serialize case class with Java annotations which comes from external module by skipping them") {
// val res = Show.derived[JavaAnnotatedCase].show(JavaAnnotatedCase(1))
// assertEquals(res, "JavaAnnotatedCase(v=1)")
// }
test("serialize case class with Java annotations by skipping them") {
val res = Show.derived[MyDto].show(MyDto("foo", 42))
assertEquals(res, "MyDto{MyAnnotation(0)}(foo=foo,bar=42)")
}

test("serialize case class with Java annotations which comes from external module by skipping them") {
val res = Show.derived[JavaAnnotatedCase].show(JavaAnnotatedCase(1))
assertEquals(res, "JavaAnnotatedCase(v=1)")
}

object AnnotationsTests:

Expand Down

0 comments on commit 9a4cfc6

Please sign in to comment.