From fb48cc0e97af65c866b0cdb5b73dbb1c75635904 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Wed, 4 Jan 2017 20:21:23 +0900 Subject: [PATCH] Also no longer search deeper than first body level for constructor method calls. --- .../main/scala-2.10/enumeratum/ContextUtils.scala | 7 +++++++ .../main/scala-2.11/enumeratum/ContextUtils.scala | 7 +++++++ .../main/scala/enumeratum/ValueEnumMacros.scala | 15 ++++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/macros/compat/src/main/scala-2.10/enumeratum/ContextUtils.scala b/macros/compat/src/main/scala-2.10/enumeratum/ContextUtils.scala index ba4bc05c..efeb8887 100644 --- a/macros/compat/src/main/scala-2.10/enumeratum/ContextUtils.scala +++ b/macros/compat/src/main/scala-2.10/enumeratum/ContextUtils.scala @@ -30,4 +30,11 @@ object ContextUtils { case m if m.isMethod && m.asMethod.isConstructor => m.asMethod.paramss.flatten.map(_.asTerm.name) } + + /** + * Returns the reserved constructor name + */ + def constructorName(c: Context): c.universe.TermName = { + c.universe.nme.CONSTRUCTOR + } } diff --git a/macros/compat/src/main/scala-2.11/enumeratum/ContextUtils.scala b/macros/compat/src/main/scala-2.11/enumeratum/ContextUtils.scala index 60b929f9..8345a885 100644 --- a/macros/compat/src/main/scala-2.11/enumeratum/ContextUtils.scala +++ b/macros/compat/src/main/scala-2.11/enumeratum/ContextUtils.scala @@ -30,4 +30,11 @@ object ContextUtils { case m if m.isConstructor => m.asMethod.paramLists.flatten.map(_.asTerm.name) } + + /** + * Returns the reserved constructor name + */ + def constructorName(c: Context): c.universe.TermName = { + c.universe.termNames.CONSTRUCTOR + } } diff --git a/macros/src/main/scala/enumeratum/ValueEnumMacros.scala b/macros/src/main/scala/enumeratum/ValueEnumMacros.scala index 34f2c5be..9c17d370 100644 --- a/macros/src/main/scala/enumeratum/ValueEnumMacros.scala +++ b/macros/src/main/scala/enumeratum/ValueEnumMacros.scala @@ -167,7 +167,17 @@ object ValueEnumMacros { val valueTerm = ContextUtils.termName(c)("value") // go through all the trees memberTrees.map { declTree => - val directMemberTrees = declTree.children.flatMap(_.children) + val directMemberTrees = declTree.children.flatMap(_.children) // Things that are body-level, no lower + val constructorTrees = { + val immediate = directMemberTrees // for 2.11+ this is enough + val constructorName = ContextUtils.constructorName(c) + val method = + directMemberTrees.collect { // for 2.10.x, we need to grab the body-level constructor method's trees + case t @ DefDef(_, `constructorName`, _, _, _, _) => + t.collect { case t => t } + }.flatten + immediate ++ method + }.iterator val valuesFromMembers = directMemberTrees.iterator.collect { case ValDef(_, termName, _, Literal(Constant(i: ValueType))) if termName == valueTerm => @@ -175,8 +185,7 @@ object ValueEnumMacros { } // Sadly 2.10 has parent-class constructor calls nested inside a member.. - val lazyTrees = declTree.collect { case t => t }.iterator - val valuesFromConstructors = lazyTrees.collect { + val valuesFromConstructors = constructorTrees.collect { // The tree has a method call case Apply(_, args) => { val valueArguments: List[Option[ValueType]] =