Skip to content

Commit ff6e7b2

Browse files
Merge pull request #5 from GermanSmoliar/add-support-for-derrives
Add support for derrives scala 3
2 parents 881692a + bf359b0 commit ff6e7b2

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
case class Derives3(x: Int) derives ReadWriter
2+

src/BreakingChangeDetector.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ object BreakingChangeDetector {
6969
initArgs: List[String]
7070
): Boolean =
7171
classInfo.annotations.exists(x =>
72-
x.name == "deriving" && x.args.find(initArgs.contains).isDefined
72+
(x.name == "deriving" || x.name == "derives") && x.args.exists(initArgs.contains)
7373
)
7474
private def listOfFieldsThatDefaultValueWasAdded(
7575
oldClass: ClassInfo,
@@ -98,15 +98,15 @@ object BreakingChangeDetector {
9898
newClass: ClassInfo
9999
): Boolean = {
100100
val isOldClassContainsSerializable = !(oldClass.annotations
101-
.filter(_.name == "deriving")
101+
.filter(x => x.name == "deriving" || x.name == "derives")
102102
.flatMap(_.args)
103103
.filter(x => serializableClasses.contains(x))
104104
.length == 0)
105105

106106
val oldClassDerivingAnnotations =
107-
oldClass.annotations.filter(_.name == "deriving")
107+
oldClass.annotations.filter(x => x.name == "deriving" || x.name == "derives")
108108
val newClassDerivingAnnotations =
109-
newClass.annotations.find(_.name == "deriving")
109+
newClass.annotations.filter(x => x.name == "deriving" || x.name == "derives")
110110

111111
isOldClassContainsSerializable &&
112112
!oldClassDerivingAnnotations

src/FileParser.scala

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,27 @@ object FileParser {
5454

5555
val tree =
5656
parseTreeClasses(exampleTree)
57-
.map(c =>
58-
(ClassInfo(
57+
.map(c => {
58+
val derivingFromAnnotation =
59+
c.mods
60+
.flatMap(_.children)
61+
.collect { case Init(tpe, _, args) =>
62+
Annotation(tpe.toString, args.flatten.map(_.toString))
63+
}
64+
val derivingFromDerives =
65+
c.templ.derives.map(d => Annotation("derives", List(d.toString)))
66+
ClassInfo(
5967
c.name.value,
60-
c.ctor.paramss.flatten.map(p =>
68+
c.ctor.paramss.headOption.getOrElse(Nil).map(p =>
6169
Field(
6270
p.name.value,
6371
p.decltpe.get.toString,
6472
p.default.map(_.toString)
6573
)
6674
),
67-
c.mods
68-
.flatMap(_.children)
69-
.collect { case Init(tpe, name, args) =>
70-
Annotation(tpe.toString, args.flatten.map(_.toString))
71-
}
72-
))
73-
)
75+
derivingFromAnnotation ++ derivingFromDerives
76+
)
77+
})
7478
ScalaFile(
7579
praseTreeImport(exampleTree),
7680
addSuffixToDuplicates(tree),

test/FileParser.test.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,24 @@ class FileParserTest extends munit.FunSuite {
7171
.getPath
7272
val parsedFile = FileParser.fromPathToClassDef(file)
7373
assert(parsedFile.classes.head.name == "Scala3Class")
74+
// Assert only first param list is treated as fields (using params should be ignored)
75+
assert(parsedFile.classes.head.fields.length == 1)
76+
assert(parsedFile.classes.head.fields(0).name == "a")
77+
assert(parsedFile.classes.head.fields(0).tpe == "Int")
78+
}
79+
80+
test("parses Scala 3 derives annotation") {
81+
val file = Thread
82+
.currentThread()
83+
.getContextClassLoader
84+
.getResource("scala-3/Scala3Derives.scala_test")
85+
.getPath
86+
val parsedFile = FileParser.fromPathToClassDef(file)
87+
assert(parsedFile.classes.head.name == "Derives3")
88+
assert(parsedFile.classes.head.fields.length == 1)
89+
assert(parsedFile.classes.head.fields(0).name == "x")
90+
val derivesAnnotation = parsedFile.classes.head.annotations.find(_.name == "derives")
91+
assert(derivesAnnotation.isDefined)
92+
assert(derivesAnnotation.get.args.contains("ReadWriter"))
7493
}
7594
}

0 commit comments

Comments
 (0)