Last active
December 14, 2015 02:59
-
-
Save everpeace/5018148 to your computer and use it in GitHub Desktop.
ユーザから渡されたブロックにimplicit valを注入するマクロを組んでみたけどうまくいかない。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import reflect.macros.Context | |
object Macros{ | |
// on(i){ ... }とやるとblockの中にiをimplicitとして注入するマクロ | |
def on[I, V](i:I)(block:V)= macro impl_on[I,V] | |
def impl_on[I, V](c:Context)(i:c.Expr[I])(block:c.Expr[V]):c.Expr[V] = { | |
import c.universe._ | |
// type of block is | |
// only one sentence => Tree | |
// _ => Block(stats,expr) | |
val stats:List[Tree] = block.tree match{ | |
case Block(s,_) => s | |
case _:Tree => List() | |
} | |
val expr:Tree = block.tree match{ | |
case Block(_,e) => e | |
case _:Tree => block.tree | |
} | |
// extract AST of implicit declaration only. | |
val Block(i_stats,_) = (reify({implicit val _i = i.splice})).tree | |
c.Expr[V](Block(i_stats:::stats,expr)) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Test does NOT compile. see blow. | |
object Test extends App{ | |
import Macros._ | |
def m(a:Int)(implicit b:Int) = a+b | |
val i = 3 | |
// println(m(5))の前にiがimplicit valとして注入される感じを想定 | |
on(i){ | |
println(m(5)) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Test2 does compile and macro is successfuly expanded. see blow. | |
object Test extends App{ | |
import Macros._ | |
def m(a:Int)(implicit b:Int) = a+b | |
val i = 3 | |
// mを呼ばないようにするとcompileできる | |
on(i){ | |
println(5) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ scalac -version | |
Scala compiler version 2.10.0 -- Copyright 2002-2012, LAMP/EPFL | |
$ scalac -language:experimental.macros Macros.scala | |
$ scalac -Ymacro-debug-lite Test2.scala | |
// macroによってiがimplicitとして挿入されたコードが生成されているっぽい。 | |
performing macro expansion Macros.on[Int, Unit](Test2.this.i)(scala.this.Predef.println(5)) at source-/Users/omura/Documents/github/everpeace/on-macro/Test2.scala,line-5,offset=100 | |
{ | |
implicit val _i = Test2.this.i; | |
scala.this.Predef.println(5) | |
} | |
Block(List(ValDef(Modifiers(IMPLICIT), newTermName("_i"), TypeTree(), Select(This(newTypeName("Test2")), newTermName("i")))), Apply(Select(Select(This(newTypeName("scala")), scala.Predef), newTermName("println")), List(Literal(Constant(5))))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ scalac -version | |
Scala compiler version 2.10.0 -- Copyright 2002-2012, LAMP/EPFL | |
$ scalac -language:experimental.macros Macros.scala | |
// macroの展開より前にこのエラーが出てる? | |
$ scalac -Ymacro-debug-lite Test.scala | |
Test.scala:6: error: could not find implicit value for parameter b: Int | |
println(m(5)) | |
^ | |
one error found |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment