Advertisement
Guest User

Untitled

a guest
Feb 13th, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.22 KB | None | 0 0
  1. package codes.bytes.macros_intro.macros
  2.  
  3. import scala.annotation.{ compileTimeOnly, StaticAnnotation }
  4. import scala.language.postfixOps
  5.  
  6. import scala.reflect.macros.whitebox.Context
  7. import scala.language.experimental.macros
  8.  
  9. object ADT {
  10. def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
  11. import c.universe._
  12. import Flag._
  13.  
  14. // the errors should cause us to stop before this, but needed to match up our match type
  15. val badTree = reify {}.tree
  16.  
  17. // check if it meets the requirements for what can be annotated
  18. // todo - consider a boolean flag that "Fixes" any bug...
  19. val inputs = annottees.map(_.tree).toList
  20. val result: Tree = {
  21. inputs match {
  22. case ClassDef(mods, name, tparams, impl) :: Nil ⇒
  23. if (mods.hasFlag(TRAIT)) {
  24. if (!mods.hasFlag(SEALED)) {
  25. c.error(c.enclosingPosition, s"ADT Root traits (trait $name) must be sealed.")
  26. badTree
  27. } else {
  28. c.info(c.enclosingPosition, s"ADT Root trait $name sanity checks OK.", force = true)
  29. ClassDef(mods, name, tparams, impl)
  30. }
  31. } else if (!mods.hasFlag(ABSTRACT)) {
  32. c.error(c.enclosingPosition, s"ADT Root classes (class $name) must be abstract.")
  33. badTree
  34. } else if (!mods.hasFlag(SEALED)) { // class that's abstract
  35. c.error(c.enclosingPosition, s"ADT Root classes (abstract class $name) must be sealed.")
  36. badTree
  37. } else {
  38. c.info(c.enclosingPosition, s"ADT Root type $name sanity checks OK.", force = true)
  39. ClassDef(mods, name, tparams, impl)
  40. }
  41. case ModuleDef(_, name, _) :: Nil ⇒
  42. c.error(c.enclosingPosition, s"ADT Roots (object $name) may not be Objects.")
  43. badTree
  44. // Not sure what would hit here, I checked and you cannot annotate a package object at all
  45. case x ⇒
  46. c.error(c.enclosingPosition, s"Invalid ADT Root ($x)")
  47. badTree
  48. }
  49. }
  50.  
  51. c.Expr[Unit](result)
  52. }
  53.  
  54. }
  55.  
  56. @compileTimeOnly("Enable Macro Paradise for Expansion of Annotations via Macros.")
  57. class ADT extends StaticAnnotation {
  58. def macroTransform(annottees: Any*): Any = macro ADT.impl
  59. }
  60. // vim: set ts=2 sw=2 sts=2 et:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement