こんどこそできたー

(できてなかったー - 気楽に諸々 の続き)

class ConnectMacro(AbstractAstMacro):
    override def Expand(macro as MacroStatement) as Statement:
        assert len(macro.Arguments) == 1
        assert macro.Arguments[0] isa BinaryExpression
        
        connectableAssignExpression as BinaryExpression = macro.Arguments[0]
        assert connectableAssignExpression.Operator == BinaryOperatorType.Assign
        connectableReferenceExpression as ReferenceExpression = connectableAssignExpression.Left
        
        openInvocationExpression = MethodInvocationExpression()
        openInvocationExpression.Target = MemberReferenceExpression(connectableReferenceExpression, "Open")
        
        closeInvocationExpression = MethodInvocationExpression()
        closeInvocationExpression.Target = MemberReferenceExpression(connectableReferenceExpression, "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(connectableAssignExpression)
        connectBlock.Add(tryStatement)
        
        return connectBlock

簡単実装の方は、try ブロック内で割り当てを行っているので、Close 呼び出し前に null チェックをするようにしといた。

macro Connect:
    assert len(Connect.Arguments) == 1
    return [|
        try:
            connectable as IConnectable = $(Connect.Arguments[0])
            connectable.Open()
            $(Connect.Block)
        ensure:
            if (connectable != null):
                connectable.Close()
    |]