2014-05-13 165 views
1

我試圖定義一個擴展到類與伴侶對象的案例類的宏註釋,但我運行在一些問題。斯卡拉類擴展與伴侶的宏擴展:類型未找到

我可以創建一個與該類名稱相同的對象,並在其上定義方法。 但是當我嘗試使用類的類型名稱作爲方法的返回類型或參數類型,我得到一個「未找到:鍵入」

class term extends StaticAnnotation { 
def macroTransform(annottees: Any*) = macro termMacro.impl 
} 

object termMacro { 

def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { 
    import c.universe._ 
    val inputs = annottees.map(_.tree).toList 

    val (cls, comp) = annottees.map(_.tree) match { 

     case [email protected]"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$_ } with ..$_ { $self => ..$stats }" :: tail => 

      val paramnames = paramss.head.map { 
       case q"$mods val $name: $tpt = $default" => name 
      } 

      val ctorparams = List(paramss.head ++ Seq(
       q"val position: SourcePosition = (0,0)" 
      )) 

      val ctorname = TermName(tpname.decodedName.toString) 
      //val clstype = 
      (
       q""" 
         import ast.Term 
         case class $tpname(...$ctorparams) extends Term { $self => 
          def children() = { 
           List(..$paramnames) 
          } 

          ..$stats 
         } 
       """, 
       q""" 
         object $ctorname { 
          def unapply(t: $tpname): Option[(Int, Int)] = { 
           Some(Tuple2(3, 4)) 
          } 
        } 
       """ 
      ) 

     case head :: tail => 
      c.abort(c.enclosingPosition, s"The @Term annotation is for case classes, found $head") 
    } 

    c.error(c.enclosingPosition, showRaw(cls) + "\n" + showRaw(comp)) 
    c.Expr[Any](Block(List(cls, comp), Literal(Constant(())))) 
} 
} 

例如用法是:@term case class A(x: Term) extends Term,並會給我的編譯器錯誤「未找到:A型」在這個定義的位置@term

我已經收窄的位置下降到對象定義的不應用方法

。 。

任何幫助表示讚賞 我非常新斯卡拉宏,所以任何進一步的建議也可以理解

方的問題:在的IntelliJ/gradle這個項目調試宏任何意見

+0

對我來說它說「方法不適用被定義兩次」。你能否將整個項目發佈到某個地方在github? –

+0

感謝你看看這個,尤金。如果可能的話,我想暫時保留這個項目的私有權限,但由於我希望你的進一步幫助,我已經給你訪問github上的repo。分支術語宏包含如此處所示的宏定義。 –

+0

我以前見過類似的錯誤btw。看起來,case class的自己的伴侶對象仍然由編譯器創建。 –

回答

1

q"import foo; class Bar"創建?一個塊,所以宏註釋會失效tly用{ import foo; class Bar }代替class Bar,這使得Bar成爲一個本地類,它在塊外部是不可見的。

+0

(Re)移動導入確實修復了它。感謝您花時間檢查項目並幫助我解決這個問題。最親切。自從我在代爾夫特大學(在代理Spoofax工作的人)聽到你的講話以來,我一直期待着自己檢查Scala宏。我對你正在做的工作印象最深刻。看到你的項目產生了多少有趣的後續工作,這是不可思議的。我將密切關注鈀金項目。 –