annotate Source/TypeBuilder/Builders/DuckTypeBuilder.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Reflection.Emit;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5 using BLToolkit.Patterns;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6 using BLToolkit.Properties;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 using BLToolkit.Reflection.Emit;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 namespace BLToolkit.TypeBuilder.Builders
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11 class DuckTypeBuilder : ITypeBuilder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 public DuckTypeBuilder(MustImplementAttribute defaultAttribute, Type interfaceType, Type[] objectTypes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 _interfaceType = interfaceType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16 _objectTypes = objectTypes;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17 _defaultAttribute = defaultAttribute;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 private readonly Type _interfaceType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21 private readonly Type[] _objectTypes;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 private TypeBuilderHelper _typeBuilder;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 private readonly MustImplementAttribute _defaultAttribute;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25 #region ITypeBuilder Members
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 public string AssemblyNameSuffix
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29 get { return "DuckType." + AbstractClassBuilder.GetTypeFullName(_interfaceType).Replace('+', '.'); }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32 public Type Build(AssemblyBuilderHelper assemblyBuilder)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 _typeBuilder = assemblyBuilder.DefineType(GetTypeName(), typeof(DuckType), _interfaceType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 if (!BuildMembers(_interfaceType))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 foreach (Type t in _interfaceType.GetInterfaces())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 if (!BuildMembers(t))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43 return _typeBuilder.Create();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46 public string GetTypeName()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 string name = String.Empty;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 foreach (Type t in _objectTypes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52 if (t != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53 name += AbstractClassBuilder.GetTypeFullName(t).Replace('+', '.');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 name += "$";
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57 return name + AssemblyNameSuffix;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60 public Type GetBuildingType()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 return _interfaceType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67 private static bool CompareMethodSignature(MethodInfo m1, MethodInfo m2)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 if (m1 == m2)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 if (m1.Name != m2.Name)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 if (m1.ReturnType != m2.ReturnType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 ParameterInfo[] ps1 = m1.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 ParameterInfo[] ps2 = m2.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81 if (ps1.Length != ps2.Length)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84 for (int i = 0; i < ps1.Length; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86 ParameterInfo p1 = ps1[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 ParameterInfo p2 = ps2[i];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89 if (p1.ParameterType != p2.ParameterType ||
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 #if !SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91 p1.IsIn != p2.IsIn ||
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 p1.IsOut != p2.IsOut)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100 private bool BuildMembers(Type interfaceType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102 FieldInfo objectsField = typeof(DuckType).GetField("_objects", BindingFlags.NonPublic | BindingFlags.Instance);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 | (DuckTyping.AllowStaticMembers? BindingFlags.Static | BindingFlags.FlattenHierarchy: 0);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 foreach (MethodInfo interfaceMethod in interfaceType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 MethodInfo targetMethod = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109 int typeIndex = 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 for (; typeIndex < _objectTypes.Length; typeIndex++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113 if (_objectTypes[typeIndex] == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114 continue;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 foreach (MethodInfo mi in _objectTypes[typeIndex].GetMethods(flags))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118 if (CompareMethodSignature(interfaceMethod, mi))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 targetMethod = mi;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 if (targetMethod == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 foreach (Type intf in _objectTypes[typeIndex].GetInterfaces())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129 if (intf.IsPublic || intf.IsNestedPublic)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 foreach (MethodInfo mi in intf.GetMethods(flags))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 if (CompareMethodSignature(interfaceMethod, mi))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135 targetMethod = mi;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140 if (targetMethod != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146 if (targetMethod != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150 ParameterInfo[] ips = interfaceMethod.GetParameters();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 MethodBuilderHelper builder = _typeBuilder.DefineMethod(interfaceMethod);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152 EmitHelper emit = builder.Emitter;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 if (targetMethod != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156 Type targetType = targetMethod.DeclaringType;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 if (!targetMethod.IsStatic)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161 .ldarg_0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 .ldfld (objectsField)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163 .ldc_i4 (typeIndex)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164 .ldelem_ref
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165 .end()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168 if (targetType.IsValueType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 // For value types we have to use stack.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172 LocalBuilder obj = emit.DeclareLocal(targetType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175 .unbox_any (targetType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176 .stloc (obj)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177 .ldloca (obj)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 .castclass (targetType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186 foreach (ParameterInfo p in ips)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 emit.ldarg(p);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189 if (targetMethod.IsStatic || targetMethod.IsFinal || targetMethod.DeclaringType.IsSealed)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191 .call (targetMethod)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 .ret();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 .callvirt (targetMethod)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196 .ret();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200 // Method or property was not found.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201 // Insert an empty stub or stub that throws the NotImplementedException.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203 MustImplementAttribute attr = (MustImplementAttribute)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 Attribute.GetCustomAttribute(interfaceMethod, typeof (MustImplementAttribute));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206 if (attr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208 attr = (MustImplementAttribute)Attribute.GetCustomAttribute(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209 interfaceMethod.DeclaringType, typeof (MustImplementAttribute));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 if (attr == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211 attr = _defaultAttribute;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214 // When the member is marked as 'Required' throw a build-time exception.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216 if (attr.Implement)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 if (attr.ThrowException)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220 throw new TypeBuilderException(string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221 Resources.TypeBuilder_PublicMethodMustBeImplemented,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222 _objectTypes.Length > 0 && _objectTypes[0] != null ? _objectTypes[0].FullName : "???",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223 interfaceMethod));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227 // Implement == true, but ThrowException == false.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228 // In this case the null pointer will be returned.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229 // This mimics the 'as' operator behaviour.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 if (attr.ThrowException)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237 string message = attr.ExceptionMessage;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 if (message == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241 message = string.Format(Resources.TypeBuilder_PublicMethodNotImplemented,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242 _objectTypes.Length > 0 && _objectTypes[0] != null ? _objectTypes[0].FullName : "???",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 interfaceMethod);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 emit
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247 .ldstr (message)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248 .newobj (typeof(InvalidOperationException), typeof(string))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 .@throw
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250 .end();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254 // Emit a 'do nothing' stub.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256 LocalBuilder returnValue = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258 if (interfaceMethod.ReturnType != typeof(void))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260 returnValue = emit.DeclareLocal(interfaceMethod.ReturnType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261 emit.Init(returnValue);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264 // Initialize out parameters.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266 ParameterInfo[] parameters = ips;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268 if (parameters != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269 emit.InitOutParameters(parameters);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271 if (returnValue != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272 emit.ldloc(returnValue);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274 emit.ret();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
275 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
276 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
277 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
278
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
279 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
280 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
281 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
282 }