2017-12-26 14 views
0

クラスを解析してCSV文字列に変換するメソッド 'toCSV'を挿入したいと思います。Scalametaで文字列を持ち上げる

  • 配列[文字列]:ヘッダ
  • 配列[配列[任意]:フィールド

マイマクロ:

class model extends scala.annotation.StaticAnnotation { 

    inline def apply(defn: Any): Any = meta { 
    defn match { 
     case cls @ Defn.Class(_, _, _, Ctor.Primary(_, _, paramss), template) => 

     def createToCSV(paramss: Seq[Seq[Term.Param]]): Defn.Def = { 

      val names = paramss.flatten.map(param => param.name.syntax) 
      val fields = paramss.map(_.map(param => Term.Name(param.name.value))) 

      q"""def toCSV = 
      CSVTools.toCSV(Seq(...$names), Seq(Seq(...$fields)))""" 
     } 

     val toCSVImpl = createToCSV(paramss) 

     val templateStats: Seq[Stat] = toCSVImpl +: template.stats.getOrElse(Nil) 
     cls.copy(templ = template.copy(stats = Some(templateStats))) 
     case _ => 
     println(defn.structure) 
     abort("@model must annotate a class.") 
    } 
    } 
} 

変数項である私の機能は、二つの偶然にを取りますSeq [String]とquasiquotes構文はTermを受け入れます。 したがって、以下のエラーが発生しました:

[error] /home/xxxxx/intellij/workspace/heroes-scala-meta/macros/src/main/scala/examples/model.scala:18: type mismatch when unquoting; 
[error] found : scala.collection.immutable.Seq[String] 
[error] required: scala.collection.immutable.Seq[scala.collection.immutable.Seq[scala.meta.Term.Arg]] 
[error]    CSVTools.toCSV(Seq(...$names), Seq(Seq(...$fields)))""" 
[error]         ^
[error] one error found 
[error] (macros/compile:compileIncremental) Compilation failed 

はあなたが解決策を持っていますか?事前に

感謝、

答えて

1

これはおそらく、少しハックですが、動作しているようです:動作することを明示的に文字列リテラルにごnamesをマップ

class model extends scala.annotation.StaticAnnotation { 

    inline def apply(defn: Any): Any = meta { 
    defn match { 
     case [email protected](_, _, _, Ctor.Primary(_, _, paramss), template) => 

     def createToCSV(paramss: Seq[Seq[Term.Param]]): Defn.Def = { 

      val names: Seq[String] = paramss.flatten.map(param => param.name.syntax) 
      val fields = paramss.map(_.map(param => Term.Name(param.name.value))) 

      val nameLiterals: Seq[Lit.String] = names.map(n => q"$n".asInstanceOf[Lit.String]) 

      q"""def toCSV = 
       CSVTools.toCSV(scala.collection.immutable.Seq(..$nameLiterals), 
          scala.collection.immutable.Seq(scala.collection.immutable.Seq(...$fields)))""" 
     } 

     val toCSVImpl = createToCSV(paramss) 

     val templateStats: Seq[Stat] = toCSVImpl +: template.stats.getOrElse(Nil) 
     cls.copy(templ = template.copy(stats = Some(templateStats))) 
     case _ => 
     println(defn.structure) 
     abort("@model must annotate a class.") 
    } 
    } 
} 
+0

、ありがとうございました! – user2931656

関連する問題