2017-12-26 18 views
0

클래스를 CSV String으로 구문 분석하기 위해 '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.") 
        } 
        } 
    } 
    

    가변 용어는 :

매크로 내 필드 내 함수는 두 paramters 걸릴 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

이 아마 조금 해키하지만이 작동하는 것 같다 명시 적으로 문자열 리터럴, 감사합니다 작품

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

names지도! – user2931656