-
Notifications
You must be signed in to change notification settings - Fork 148
fireAndForget
rollynoel edited this page Jun 15, 2013
·
2 revisions
Added by Sorin Ionescu
Example:
class Foo:
[AsyncMethod]
def PrintMessage(message):
print message
def Main():
foo = Foo()
fireAndForget foo.BeginPrintMessage("Hello World!")
#region license
// Copyright (c) 2005, Sorin Ionescu
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of Sorin Ionescu nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregionTestFixtureTestFixtureTestFixtureTestFixture
namespace Boo.Lang.Useful.Macros
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
class FireAndForgetMacro(AbstractAstMacro):
"""
Automatically calls the End<Method> of an asynchronous invocation in a closure.
"""
public override def Expand(macro as MacroStatement) as Statement:
assert macro.Arguments.Count == 1
assert macro.Arguments[0] isa MethodInvocationExpression
lexicalInfo = macro.LexicalInfo
statement = Block(lexicalInfo)
localIndex = Context.AllocIndex()
beginMethodInvocation = macro.Arguments[0] as MethodInvocationExpression
beginMethodTarget = \
beginMethodInvocation.Target as MemberReferenceExpression
objectReference = beginMethodTarget.Target
endMethodName = "End" + beginMethodTarget.Name.Substring(5)
endMethodInvocation = MethodInvocationExpression(
LexicalInfo: lexicalInfo,
Target: MemberReferenceExpression(
objectReference.CloneNode(),
endMethodName))
callbackClosure = CallableBlockExpression(lexicalInfo)
iAsyncResult = DeclarationStatement(
LexicalInfo: lexicalInfo,
Declaration(LexicalInfo: lexicalInfo,
Name: "___iAsyncResult${localIndex}",
Type: SimpleTypeReference(lexicalInfo, "System.IAsyncResult")),
NullLiteralExpression(lexicalInfo))
iAsyncResultAssignment = BinaryExpression(
lexicalInfo,
BinaryOperatorType.Assign,
ReferenceExpression(
LexicalInfo: lexicalInfo,
Name: iAsyncResult.Declaration.Name),
beginMethodInvocation)
beginMethodInvocation.Arguments.Add(callbackClosure)
beginMethodInvocation.Arguments.Add(NullLiteralExpression(lexicalInfo))
endMethodInvocation.Arguments.Add(
ReferenceExpression(
LexicalInfo: lexicalInfo,
Name: iAsyncResult.Declaration.Name))
callbackClosure.Body.Add(endMethodInvocation)
statement.Add(iAsyncResult)
statement.Add(iAsyncResultAssignment)
return statement