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:
10 // The above copyright notice and this permission notice shall be
11 // included in all copies or substantial portions of the Software.
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.
21 // Copyright (C) Lluis Sanchez Gual, 2004
26 using System.Collections;
28 using System.Reflection;
29 using System.Reflection.Emit;
31 namespace Mono.CodeGeneration
33 public class CodeProperty
35 PropertyInfo propertyInfo;
36 CodeBuilder get_builder;
37 CodeBuilder set_builder;
39 PropertyAttributes attributes;
40 MethodAttributes methodAttributes;
42 TypeBuilder typeBuilder;
43 Type[] parameterTypes;
44 ArrayList customAttributes = new ArrayList ();
47 internal static CodeProperty DefineProperty (CodeClass cls, string name, PropertyAttributes attributes, MethodAttributes methodAttributes, Type returnType, Type[] parameterTypes)
49 return new CodeProperty (cls, name, attributes, methodAttributes, returnType, parameterTypes);
52 internal CodeProperty (CodeClass cls, string name, PropertyAttributes attributes, MethodAttributes methodAttributes, Type returnType, Type[] parameterTypes)
55 this.typeBuilder = cls.TypeBuilder;
57 this.attributes = attributes;
58 this.methodAttributes = methodAttributes;
59 this.returnType = returnType;
60 this.parameterTypes = parameterTypes;
62 PropertyBuilder pb = typeBuilder.DefineProperty (name, attributes, returnType, parameterTypes);
63 pb.SetGetMethod (typeBuilder.DefineMethod ("get_" + name, methodAttributes, CallingConventions.Standard, returnType, Type.EmptyTypes));
64 pb.SetSetMethod (typeBuilder.DefineMethod ("set_" + name, methodAttributes, CallingConventions.Standard, typeof (void), new Type [] {returnType}));
65 get_builder = new CodeBuilder (cls);
66 set_builder = new CodeBuilder (cls);
70 public TypeBuilder DeclaringType
72 get { return typeBuilder; }
75 public PropertyBuilder PropertyBuilder
77 get { return propertyInfo as PropertyBuilder; }
85 public PropertyAttributes Attributes
87 get { return attributes; }
90 public Type ReturnType
92 get { return returnType; }
95 public Type[] ParameterTypes
97 get { return parameterTypes; }
100 public CodeBuilder CodeBuilderGet
102 get { return get_builder; }
105 public CodeBuilder CodeBuilderSet
107 get { return set_builder; }
112 get { return (methodAttributes & MethodAttributes.Static) != 0; }
117 get { return (methodAttributes & MethodAttributes.Public) != 0; }
120 public CodeCustomAttribute CreateCustomAttribute (Type attributeType)
122 return CreateCustomAttribute (attributeType,
123 Type.EmptyTypes, new object [0]);
126 public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs)
128 return CreateCustomAttribute (attributeType,
129 ctorArgTypes, ctorArgs, new string [0], new object [0]);
132 public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs, string [] namedArgFieldNames, object [] namedArgValues)
134 CodeCustomAttribute cca = CodeCustomAttribute.Create (
135 attributeType, ctorArgTypes, ctorArgs, namedArgFieldNames, namedArgValues);
136 SetCustomAttribute (cca);
140 public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, CodeLiteral [] ctorArgs, FieldInfo [] fields, CodeLiteral [] fieldValues)
142 CodeCustomAttribute cca = CodeCustomAttribute.Create (
143 attributeType, ctorArgTypes, ctorArgs, fields, fieldValues);
144 SetCustomAttribute (cca);
148 void SetCustomAttribute (CodeCustomAttribute cca)
150 PropertyBuilder.SetCustomAttribute (cca.Builder);
151 customAttributes.Add (cca);
154 public string PrintCode ()
156 StringWriter sw = new StringWriter ();
157 CodeWriter cw = new CodeWriter (sw);
159 return sw.ToString ();
162 public void PrintCode (CodeWriter cp)
165 foreach (CodeCustomAttribute a in customAttributes)
169 cp.Write ("static ");
171 cp.Write ("public ");
172 if (returnType != null) cp.Write (returnType + " ");
174 if (parameterTypes.Length > 0) {
175 cp.Write (name + " [");
176 for (int n=0; n<parameterTypes.Length; n++) {
177 if (n > 0) cp.Write (", ");
178 cp.Write (parameterTypes[n] + " arg" + n);
185 cp.WriteLineInd ("get {");
186 get_builder.PrintCode (cp);
187 cp.WriteLineUnind ("}");
188 cp.WriteLine ("set {");
189 set_builder.PrintCode (cp);
191 cp.WriteLineUnind ("}");
194 public CodeArgumentReference GetArg (int n)
196 if (n < 0 || n >= parameterTypes.Length)
197 throw new InvalidOperationException ("Invalid argument number");
199 int narg = IsStatic ? n : n + 1;
200 return new CodeArgumentReference (parameterTypes[n], narg, "arg" + n);
203 public CodeArgumentReference GetThis ()
206 throw new InvalidOperationException ("'this' not available in static methods");
208 return new CodeArgumentReference (DeclaringType, 0, "this");
211 public void Generate ()
218 mb = (MethodBuilder) propertyInfo.GetGetMethod ();
220 gen = mb.GetILGenerator();
221 returnLabel = gen.DefineLabel ();
222 get_builder.ReturnLabel = returnLabel;
223 get_builder.Generate (gen);
224 gen.MarkLabel (returnLabel);
225 gen.Emit (OpCodes.Ret);
229 mb = (MethodBuilder) propertyInfo.GetSetMethod ();
231 gen = mb.GetILGenerator();
232 returnLabel = gen.DefineLabel ();
233 set_builder.ReturnLabel = returnLabel;
234 set_builder.Generate (gen);
235 gen.MarkLabel (returnLabel);
236 gen.Emit (OpCodes.Ret);
240 public void UpdatePropertyInfo (Type type)
242 propertyInfo = type.GetProperty (propertyInfo.Name, parameterTypes);