BOO-988: Added else block to the for and while statements, and include a suite of...
[boo.git] / src / Boo.Lang.Compiler / Steps / TransformCallableDefinitions.cs
blob73c7a98b176ccc448c0b3946dd31f3b22b3cceb8
1 #region license
2 // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
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.
27 #endregion
29 namespace Boo.Lang.Compiler.Steps
31 using System;
32 using Boo.Lang.Compiler.Ast;
34 public class TransformCallableDefinitions : AbstractTransformerCompilerStep
36 override public void Run()
38 Visit(CompileUnit);
41 override public void OnMethod(Method node)
45 override public void OnClassDefinition(ClassDefinition node)
47 Visit(node.Members);
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);
84 else
86 parameter.Type = CodeBuilder.CreateTypeReference(TypeSystemServices.ObjectType);
92 Method CreateInvokeMethod(CallableDefinition node)
94 Method method = CreateRuntimeMethod("Invoke", node.ReturnType);
95 method.Parameters = node.Parameters;
96 return method;
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)));
110 return method;
113 Method CreateEndInvokeMethod(CallableDefinition node)
115 Method method = CreateRuntimeMethod("EndInvoke", node.ReturnType);
117 foreach(ParameterDeclaration p in node.Parameters)
119 if (p.IsByRef)
121 method.Parameters.Add(p.CloneNode());
125 method.Parameters.Add(
126 new ParameterDeclaration("asyncResult",
127 CodeBuilder.CreateTypeReference(node.LexicalInfo, typeof(IAsyncResult))));
128 return method;
131 Method CreateRuntimeMethod(string name, TypeReference returnType)
133 Method method = new Method();
134 method.Name = name;
135 method.ReturnType = returnType;
136 method.Modifiers = TypeMemberModifiers.Public|TypeMemberModifiers.Virtual;
137 method.ImplementationFlags = MethodImplementationFlags.Runtime;
138 return method;