Added comment
[castle.git] / Tools / Castle.DynamicProxy2 / Castle.DynamicProxy / Generators / Emitters / PropertyEmitter.cs
blobf02797800ab2937e79f76daed8dce6e3767f7ba0
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.DynamicProxy.Generators.Emitters
17 using System;
18 using System.Reflection;
19 using System.Reflection.Emit;
21 public class PropertyEmitter : IMemberEmitter
23 private PropertyBuilder builder;
24 private AbstractTypeEmitter parentTypeEmitter;
25 private MethodEmitter getMethod;
26 private MethodEmitter setMethod;
28 private static readonly MethodInfo newDefinePropertyMethodInfo = typeof (TypeBuilder).GetMethod("DefineProperty", new Type[]
30 typeof (string), typeof (PropertyAttributes),
31 typeof (CallingConventions), typeof (Type),
32 typeof (Type[]), typeof (Type[]), typeof (Type[]),
33 typeof (Type[][]), typeof (Type[][])
34 });
36 // private ParameterInfo[] indexParameters;
38 private delegate PropertyBuilder DefineProperty_Clr2_0(
39 string name, PropertyAttributes attributes, Type propertyType, Type[] parameters);
41 public delegate PropertyBuilder DefineProperty_Clr_2_0_SP1(string name,
42 PropertyAttributes attributes,
43 CallingConventions callingConvention,
44 Type returnType,
45 Type[] returnTypeRequiredCustomModifiers,
46 Type[] returnTypeOptionalCustomModifiers,
47 Type[] parameterTypes,
48 Type[][] parameterTypeRequiredCustomModifiers,
49 Type[][] parameterTypeOptionalCustomModifiers);
51 public PropertyEmitter(AbstractTypeEmitter parentTypeEmitter, String name, PropertyAttributes attributes,
52 Type propertyType)
54 this.parentTypeEmitter = parentTypeEmitter;
56 // DYNPROXY-73 - AmbiguousMatchException for properties
57 // This is a workaround for a framework limitation in CLR 2.0
58 // This limitation was removed in CLR 2.0 SP1, but we don't want to
59 // tie ourselves to that version. This perform the lookup for the new overload
60 // dynamically, so we have a nice fallback on vanilla CLR 2.0
61 DefineProperty_Clr2_0 oldDefineProperty = parentTypeEmitter.TypeBuilder.DefineProperty;
62 DefineProperty_Clr_2_0_SP1 newDefinedProperty = (DefineProperty_Clr_2_0_SP1)
63 Delegate.CreateDelegate(typeof(DefineProperty_Clr_2_0_SP1), parentTypeEmitter.TypeBuilder, newDefinePropertyMethodInfo);
65 if(newDefinedProperty==null)
67 builder = oldDefineProperty(name, attributes, propertyType, new Type[0]);
69 else
71 builder = parentTypeEmitter.TypeBuilder.DefineProperty(
72 name, attributes, CallingConventions.HasThis, propertyType,
73 null, null, new Type[0], null, null);
77 public MethodEmitter GetMethod
79 get { return getMethod; }
80 set { getMethod = value; }
83 public MethodEmitter SetMethod
85 get { return setMethod; }
86 set { setMethod = value; }
89 public MethodEmitter CreateGetMethod()
91 return CreateGetMethod(MethodAttributes.Public |
92 MethodAttributes.Virtual |
93 MethodAttributes.SpecialName);
96 public MethodEmitter CreateGetMethod(MethodAttributes attrs, params Type[] parameters)
98 if (getMethod != null)
100 throw new InvalidOperationException("A getMethod exists");
103 if (parameters.Length == 0)
105 getMethod = new MethodEmitter(parentTypeEmitter, "get_" + builder.Name, attrs);
107 else
109 getMethod = new MethodEmitter(parentTypeEmitter, "get_" + builder.Name,
110 attrs,
111 ReturnType,
112 parameters);
115 return getMethod;
118 public MethodEmitter CreateSetMethod()
120 return CreateSetMethod(MethodAttributes.Public |
121 MethodAttributes.Virtual |
122 MethodAttributes.SpecialName);
125 public MethodEmitter CreateSetMethod(Type arg)
127 return CreateSetMethod(MethodAttributes.Public |
128 MethodAttributes.Virtual |
129 MethodAttributes.SpecialName, arg);
132 public MethodEmitter CreateSetMethod(MethodAttributes attrs, params Type[] parameters)
134 if (setMethod != null)
136 throw new InvalidOperationException("A setMethod exists");
139 if (parameters.Length == 0)
141 setMethod = new MethodEmitter(parentTypeEmitter, "set_" + builder.Name, attrs);
143 else
145 setMethod = new MethodEmitter(parentTypeEmitter, "set_" + builder.Name,
146 attrs, typeof (void),
147 parameters);
150 return setMethod;
153 public MemberInfo Member
155 get { return null; }
158 public Type ReturnType
160 get { return builder.PropertyType; }
163 public void Generate()
165 if (setMethod != null)
167 setMethod.Generate();
168 builder.SetSetMethod(setMethod.MethodBuilder);
171 if (getMethod != null)
173 getMethod.Generate();
174 builder.SetGetMethod(getMethod.MethodBuilder);
178 public void EnsureValidCodeBlock()
180 if (setMethod != null)
182 setMethod.EnsureValidCodeBlock();
185 if (getMethod != null)
187 getMethod.EnsureValidCodeBlock();