Skip to content

Instantly share code, notes, and snippets.

@matsu-chara
Created February 27, 2017 15:45
Show Gist options
  • Save matsu-chara/550c0444bd684035694518bd7186cf89 to your computer and use it in GitHub Desktop.
Save matsu-chara/550c0444bd684035694518bd7186cf89 to your computer and use it in GitHub Desktop.
meta 0.16, pardaise-3.0.0M8
package scalaworld.macros
import scala.collection.immutable.Seq
import scala.meta._
/**
* <s>コンパニオンオブジェクト</s> case classにつけるアノテーション。
* 対応するcase classのフィールドを取得し、
* def フィールド名(value: フィールドの型): (String, フィールドの型) = (フィールド名, value)
* というメソッドをフィールドの数だけコンパニオンオブジェクトに生成する。
*/
class FieldNameAndValuePorter extends scala.annotation.StaticAnnotation {
inline def apply(defn: Any): Any = meta {
defn match {
case cls @ Defn.Class(_, _, _, Ctor.Primary(_, _, paramss), template) =>
val namesToValues: Seq[Defn] = paramss.flatten.map { param =>
q"def ${Term.Name("_" + param.name.syntax)}(value: ${param.decltpe.get}): (String, ${Type.Name(param.decltpe.get.syntax)}) = (${param.name.syntax}, value)"
}
val templateStats: Seq[Stat] = namesToValues ++: template.stats.getOrElse(Nil)
cls.copy(templ = template.copy(stats = Some(templateStats)))
case _ =>
println(defn.structure)
abort("@FieldNameAndValuePorter must annotate a class.")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment