Added tests for Task.WhenAll w/ empty list
[mono.git] / mcs / class / System.ServiceModel / Mono.CodeGeneration / CodeMethodCall.cs
1 //
2 // Permission is hereby granted, free of charge, to any person obtaining
3 // a copy of this software and associated documentation files (the
4 // "Software"), to deal in the Software without restriction, including
5 // without limitation the rights to use, copy, modify, merge, publish,
6 // distribute, sublicense, and/or sell copies of the Software, and to
7 // permit persons to whom the Software is furnished to do so, subject to
8 // the following conditions:
9 // 
10 // The above copyright notice and this permission notice shall be
11 // included in all copies or substantial portions of the Software.
12 // 
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
17 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 //
21 // Copyright (C) Lluis Sanchez Gual, 2004
22 //
23
24 #if !MONOTOUCH
25 using System;
26 using System.Reflection;
27 using System.Reflection.Emit;
28
29 namespace Mono.CodeGeneration
30 {
31         public class CodeMethodCall: CodeExpression
32         {
33                 CodeExpression target;
34                 CodeExpression[] parameters;
35                 MethodBase method;
36                 CodeMethod codeMethod;
37                 
38                 public CodeMethodCall (CodeExpression target, string name, params CodeExpression[] parameters)
39                 {
40                         this.target = target;
41                         this.parameters = parameters;
42                         Type[] types = GetParameterTypes (parameters);
43                         method = target.GetResultType().GetMethod (name, types);
44                         if (method == null) {
45                                 throw new InvalidOperationException ("Method " + GetSignature(target.GetResultType(), name, parameters) + " not found");
46                         }
47                 }
48                 
49                 public CodeMethodCall (CodeExpression target, MethodBase method, params CodeExpression[] parameters)
50                 {
51                         this.target = target;
52                         this.parameters = parameters;
53                         this.method = method;
54                 }
55                 
56                 public CodeMethodCall (CodeExpression target, CodeMethod method, params CodeExpression[] parameters)
57                 {
58                         this.target = target;
59                         this.parameters = parameters;
60                         this.codeMethod = method;
61                 }
62                 
63                 public CodeMethodCall (Type type, string name, params CodeExpression[] parameters)
64                 {
65                         this.parameters = parameters;
66                         method = type.GetMethod (name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, GetParameterTypes (parameters), null);
67                         if (method == null) throw new InvalidOperationException ("Method " + GetSignature(type, name, parameters) + " not found");
68                 }
69                 
70                 public CodeMethodCall (MethodInfo method, params CodeExpression[] parameters)
71                 {
72                         this.parameters = parameters;
73                         this.method = method;
74                 }
75                 
76                 public CodeMethodCall (CodeMethod method, params CodeExpression[] parameters)
77                 {
78                         this.parameters = parameters;
79                         this.codeMethod = method;
80                 }
81                 
82                 Type[] GetParameterTypes (CodeExpression[] parameters)
83                 {
84                         Type[] ts = new Type [parameters.Length];
85                         for (int n=0; n<ts.Length; n++)
86                                 ts [n] = parameters[n].GetResultType ();
87                         return ts;
88                 }
89                 
90                 string GetSignature (Type type, string name, params CodeExpression[] parameters)
91                 {
92                         System.Text.StringBuilder sb = new System.Text.StringBuilder ();
93                         sb.Append (type.FullName).Append(".").Append(name);
94                         
95                         Type[] types = GetParameterTypes (parameters);
96                         sb.Append ("(");
97                         for (int n=0; n<types.Length; n++)
98                         {
99                                 if (n > 0) sb.Append (", ");
100                                 sb.Append (types[n].FullName);
101                         }
102                         sb.Append (")");
103                         return sb.ToString ();
104                 }
105                 
106                 public override void Generate (ILGenerator gen)
107                 {
108                         if (codeMethod != null)
109                                 CodeGenerationHelper.GenerateMethodCall (gen, target, codeMethod, parameters);
110                         else
111                                 CodeGenerationHelper.GenerateMethodCall (gen, target, method, parameters);
112                 }
113                 
114                 public override void GenerateAsStatement (ILGenerator gen)
115                 {
116                         Generate (gen);
117                         if (GetResultType () != typeof(void)) gen.Emit (OpCodes.Pop);
118                 }
119                 
120                 public override void PrintCode (CodeWriter cp)
121                 {
122                         MethodBase met = method != null ? method : codeMethod.MethodInfo;
123                         if (!object.ReferenceEquals (target, null))
124                                 target.PrintCode (cp);
125                         else
126                                 cp.Write (met.DeclaringType.FullName);
127                         
128                         cp.Write (".");
129                         cp.Write (met.Name).Write (" (");
130                         for (int n=0; n<parameters.Length; n++) {
131                                 if (n > 0) cp.Write (", ");
132                                 parameters[n].PrintCode (cp);
133                         }
134                         cp.Write (")");
135                 }
136                 
137                 public override Type GetResultType ()
138                 {
139                         if (codeMethod != null) return codeMethod.ReturnType;
140                         else if (method is MethodInfo) return ((MethodInfo) method).ReturnType;
141                         else return typeof (void);
142                 }
143         }
144 }
145
146 #endif