できたー
IConnectable.boo
namespace ConsoleApplicationBoo import System import Boo.Lang.Compiler import Boo.Lang.Compiler.Ast interface IConnectable: def Open(): pass def Close(): pass class ConnectMacro(AbstractAstMacro): override def Expand(macro as MacroStatement) as Statement: assert len(macro.Arguments) == 1 connectableAssignExpression = macro.Arguments[0] openInvocationExpression = MethodInvocationExpression() openInvocationExpression.Target = MemberReferenceExpression(connectableAssignExpression, "Open") closeInvocationExpression = MethodInvocationExpression() closeInvocationExpression.Target = MemberReferenceExpression(connectableAssignExpression, "Close") tryStatement = TryStatement() tryStatement.ProtectedBlock = Block() tryStatement.ProtectedBlock.Add(openInvocationExpression) tryStatement.ProtectedBlock.Add(macro.Block) tryStatement.EnsureBlock = Block() tryStatement.EnsureBlock.Add(closeInvocationExpression) connectBlock = Block() connectBlock.Add(tryStatement) return connectBlock
Program.boo
namespace ConsoleApplicationBoo import System class HelloWorld(IConnectable): def Open(): print "open" def Close(): print "close" def Execute(): print "Hello, World !" connect con = HelloWorld(): con.Execute() Console.ReadLine()
で、ConnectMacro クラス書く代わりにこーやって簡単に書くことも可能、と。
macro Connect: assert len(Connect.Arguments) == 1 return [| try: connectable as IConnectable = $(Connect.Arguments[0]) connectable.Open() $(Connect.Block) ensure: connectable.Close() |]
こっちは簡単に記述できるけど、マクロ実行時 (=コンパイル時) に検証を行わせたりすることはできない。・・・たぶんw
できたので検証処理追加しといた^^;