2 // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 // * Neither the name of Rodrigo B. de Oliveira nor the names of its
14 // contributors may be used to endorse or promote products derived from this
15 // software without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 namespace Boo
.Lang
.Compiler
.Steps
32 using Boo
.Lang
.Compiler
.Ast
;
34 public class TransformCallableDefinitions
: AbstractTransformerCompilerStep
36 override public void Run()
41 override public void OnMethod(Method node
)
45 override public void OnClassDefinition(ClassDefinition node
)
50 override public void OnCallableDefinition(CallableDefinition node
)
52 if (null == node
.ReturnType
)
54 node
.ReturnType
= CodeBuilder
.CreateTypeReference(TypeSystemServices
.VoidType
);
57 CompleteOmittedParameterType(node
);
59 ClassDefinition cd
= TypeSystemServices
.CreateCallableDefinition(node
.Name
);
60 cd
.LexicalInfo
= node
.LexicalInfo
;
61 cd
.GenericParameters
= node
.GenericParameters
;
63 cd
.Members
.Add(CreateInvokeMethod(node
));
64 cd
.Members
.Add(CreateBeginInvokeMethod(node
));
65 cd
.Members
.Add(CreateEndInvokeMethod(node
));
67 ReplaceCurrentNode(cd
);
70 private void CompleteOmittedParameterType(CallableDefinition node
)
72 ParameterDeclarationCollection parameters
= node
.Parameters
;
73 if (0 == parameters
.Count
) return;
75 ParameterDeclaration last
= parameters
[-1];
76 foreach (ParameterDeclaration parameter
in parameters
)
78 if (null == parameter
.Type
)
80 if (parameters
.VariableNumber
&& last
== parameter
)
82 parameter
.Type
= CodeBuilder
.CreateTypeReference(TypeSystemServices
.ObjectArrayType
);
86 parameter
.Type
= CodeBuilder
.CreateTypeReference(TypeSystemServices
.ObjectType
);
92 Method
CreateInvokeMethod(CallableDefinition node
)
94 Method method
= CreateRuntimeMethod("Invoke", node
.ReturnType
);
95 method
.Parameters
= node
.Parameters
;
99 Method
CreateBeginInvokeMethod(CallableDefinition node
)
101 Method method
= CreateRuntimeMethod("BeginInvoke",
102 CodeBuilder
.CreateTypeReference(node
.LexicalInfo
, typeof(IAsyncResult
)));
103 method
.Parameters
.ExtendWithClones(node
.Parameters
);
104 method
.Parameters
.Add(
105 new ParameterDeclaration("callback",
106 CodeBuilder
.CreateTypeReference(node
.LexicalInfo
, typeof(AsyncCallback
))));
107 method
.Parameters
.Add(
108 new ParameterDeclaration("asyncState",
109 CodeBuilder
.CreateTypeReference(node
.LexicalInfo
, TypeSystemServices
.ObjectType
)));
113 Method
CreateEndInvokeMethod(CallableDefinition node
)
115 Method method
= CreateRuntimeMethod("EndInvoke", node
.ReturnType
);
117 foreach(ParameterDeclaration p
in node
.Parameters
)
121 method
.Parameters
.Add(p
.CloneNode());
125 method
.Parameters
.Add(
126 new ParameterDeclaration("asyncResult",
127 CodeBuilder
.CreateTypeReference(node
.LexicalInfo
, typeof(IAsyncResult
))));
131 Method
CreateRuntimeMethod(string name
, TypeReference returnType
)
133 Method method
= new Method();
135 method
.ReturnType
= returnType
;
136 method
.Modifiers
= TypeMemberModifiers
.Public
|TypeMemberModifiers
.Virtual
;
137 method
.ImplementationFlags
= MethodImplementationFlags
.Runtime
;