-
Notifications
You must be signed in to change notification settings - Fork 533
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for
Generic
materialized in companion object of nested …
…case class (#1286) Co-authored-by: Georgi Krastev <[email protected]>
- Loading branch information
1 parent
977f354
commit df313df
Showing
4 changed files
with
73 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
coreTestMacros/shared/src/main/scala/shapeless/generateGeneric.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package shapeless | ||
|
||
import scala.annotation.{StaticAnnotation, compileTimeOnly} | ||
import scala.reflect.macros.blackbox | ||
import scala.language.experimental.macros | ||
|
||
@compileTimeOnly("enable macro annotations") | ||
class generateGeneric extends StaticAnnotation { | ||
def macroTransform(annottees: Any*): Any = macro GenerateGenericMacroImpl.macroTransformImpl | ||
} | ||
|
||
object GenerateGenericMacroImpl { | ||
def macroTransformImpl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { | ||
import c.universe._ | ||
|
||
def modifyObject(obj: Tree): Tree = obj match { | ||
case q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }" => | ||
q"""$mods object $tname extends { ..$earlydefns } with ..$parents { $self => | ||
..$body | ||
_root_.shapeless.Generic[${tname.toTypeName}](_root_.shapeless.Generic.materialize) | ||
}""" | ||
case _ => sys.error("impossible") | ||
} | ||
|
||
def modify(cls: Tree, obj: Tree): Tree = q"..${Seq(cls, modifyObject(obj))}" | ||
|
||
annottees match { | ||
case (cls: ClassDef) :: (obj: ModuleDef) :: Nil => modify(cls, obj) | ||
case (cls: ClassDef) :: Nil => modify(cls, q"object ${cls.name.toTermName}") | ||
// this works for the companion object of a sealed trait or top-level case class but not nested case class | ||
case (obj: ModuleDef) :: Nil => modifyObject(obj) | ||
case _ => c.abort(c.enclosingPosition, "@generateGeneric can annotate only traits, classes, and objects") | ||
} | ||
} | ||
} |