move to from olive to mcs
[mono.git] / mcs / class / System.ServiceModel / Mono.CodeGeneration / CodeExpression.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 using System;
25 using System.Reflection;
26 using System.Reflection.Emit;
27
28 namespace Mono.CodeGeneration
29 {
30         public abstract class CodeExpression: CodeItem
31         {
32                 internal CodeVariableReference var;
33
34                 public abstract Type GetResultType ();
35                 
36                 public virtual void GenerateAsStatement (ILGenerator gen)
37                 {
38                         Generate (gen);
39                         gen.Emit (OpCodes.Pop);
40                 }
41                 
42                 public CodeExpression CallToString ()
43                 {
44                         return new CodeMethodCall (this, "ToString");
45                 }
46                 
47                 public static CodeExpression AreEqual (CodeExpression e1, CodeExpression e2)
48                 {
49                         return new CodeEquals (e1, e2);
50                 }
51                 
52                 public static CodeExpression AreNotEqual (CodeExpression e1, CodeExpression e2)
53                 {
54                         return new CodeNotEquals (e1, e2);
55                 }
56                 
57                 public static CodeExpression IsGreaterThan (CodeExpression e1, CodeExpression e2)
58                 {
59                         return new CodeGreaterThan (e1, e2);
60                 }
61                 
62                 public static CodeExpression IsSmallerThan (CodeExpression e1, CodeExpression e2)
63                 {
64                         return new CodeLessThan (e1, e2);
65                 }
66                 
67                 public static CodeExpression IsGreaterEqualThan (CodeExpression e1, CodeExpression e2)
68                 {
69                         return new CodeGreaterEqualThan (e1, e2);
70                 }
71                 
72                 public static CodeExpression IsSmallerEqualThan (CodeExpression e1, CodeExpression e2)
73                 {
74                         return new CodeLessEqualThan (e1, e2);
75                 }
76                 
77                 public static CodeExpression Not (CodeExpression e)
78                 {
79                         return new CodeNot (e);
80                 }
81                 
82                 public static CodeExpression Add (CodeExpression e1, CodeExpression e2)
83                 {
84                         return new CodeAdd (e1, e2);
85                 }
86                 
87                 public static CodeExpression Subtract (CodeExpression e1, CodeExpression e2)
88                 {
89                         return new CodeSub (e1, e2);
90                 }
91                 
92                 public static CodeExpression Multiply (CodeExpression e1, CodeExpression e2)
93                 {
94                         return new CodeMul (e1, e2);
95                 }
96                 
97                 public static CodeExpression Divide (CodeExpression e1, CodeExpression e2)
98                 {
99                         return new CodeDiv (e1, e2);
100                 }
101                 
102                 public CodeExpression CastTo (Type type)
103                 {
104                         return new CodeCast (type, this);
105                 }
106                 
107                 public CodeExpression And (CodeExpression other)
108                 {
109                         return new CodeAnd (this, other);
110                 }
111                 
112                 public CodeExpression Is (Type type)
113                 {
114                         return new CodeIs (type, this);
115                 }
116                 
117                 public CodeExpression Call (string name, params CodeExpression[] parameters)
118                 {
119                         return new CodeMethodCall (this, name, parameters);
120                 }
121                 
122                 public CodeExpression Call (MethodInfo method, params CodeExpression[] parameters)
123                 {
124                         return new CodeMethodCall (this, method, parameters);
125                 }
126                 
127                 public CodeValueReference MemGet (string name)
128                 {
129                         MemberInfo[] mems = GetResultType().GetMember (name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
130                         if (mems.Length == 0) throw new InvalidOperationException ("Field '" + name + "' not found in " + GetResultType()); 
131                         return MemGet (mems[0]);
132                 }
133                 
134                 public CodeValueReference MemGet (MemberInfo member)
135                 {
136                         if (member is FieldInfo) 
137                                 return new CodeFieldReference (this, (FieldInfo)member);
138                         else if (member is PropertyInfo)
139                                 return new CodePropertyReference (this, (PropertyInfo)member);
140                         else
141                                 throw new InvalidOperationException (member.Name + " is not either a field or a property");
142                 }
143                 
144                 public CodeValueReference this [CodeExpression index]
145                 {
146                         get { return new CodeArrayItem (this, index); }
147                 }
148                 
149                 public CodeValueReference this [string name]
150                 {
151                         get { return MemGet (name); }
152                 }
153                 
154                 public CodeValueReference this [FieldInfo field]
155                 {
156                         get { return new CodeFieldReference (this, field); }
157                 }
158                 
159                 public CodeValueReference this [PropertyInfo prop]
160                 {
161                         get { return new CodePropertyReference (this, prop); }
162                 }
163                 
164                 public CodeExpression ArrayLength
165                 {
166                         get { return new CodeArrayLength (this); }
167                 }
168                 
169                 public CodeExpression IsNull
170                 {
171                         get { return new CodeEquals (this, new CodeLiteral (null, this.GetResultType())); }
172                 }
173                 
174                 public static CodeExpression NullValue (Type type)
175                 {
176                         return new CodeLiteral (null, type);
177                 }
178                 
179                 public bool IsNumber
180                 {
181                         get {
182                                 return CodeGenerationHelper.IsNumber (GetResultType ());
183                         }
184                 }
185         }
186         
187         public abstract class CodeConditionExpression: CodeExpression
188         {
189                 public virtual void GenerateForBranch (ILGenerator gen, Label label, bool jumpCase)
190                 {
191                         Generate (gen);
192                         if (jumpCase)
193                                 gen.Emit (OpCodes.Brtrue, label);
194                         else
195                                 gen.Emit (OpCodes.Brfalse, label);
196                 }
197         }
198 }