5 // Chris J Breisch (cjbreisch@altavista.net)
6 // Marco Ridoni (marco.ridoni@virgilio.it)
7 // Dennis Hayes (dennish@raytek.com)
8 // Satya Sudha K (ksathyasudha@novell.com)
10 // (C) 2002 Chris J Breisch
11 // (C) 2003 Marco Ridoni
14 * Copyright (c) 2002-2003 Mainsoft Corporation.
15 * Copyright (C) 2004 Novell, Inc (http://www.novell.com)
17 * Permission is hereby granted, free of charge, to any person obtaining a
18 * copy of this software and associated documentation files (the "Software"),
19 * to deal in the Software without restriction, including without limitation
20 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 * and/or sell copies of the Software, and to permit persons to whom the
22 * Software is furnished to do so, subject to the following conditions:
24 * The above copyright notice and this permission notice shall be included in
25 * all copies or substantial portions of the Software.
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 * DEALINGS IN THE SOFTWARE.
40 using System.Reflection;
41 using Microsoft.VisualBasic;
42 using System.ComponentModel;
45 namespace Microsoft.VisualBasic.CompilerServices {
46 [StandardModule, EditorBrowsable(EditorBrowsableState.Never)]
47 sealed public class LateBinding {
48 private LateBinding () {}
50 [System.Diagnostics.DebuggerHiddenAttribute]
51 [System.Diagnostics.DebuggerStepThroughAttribute]
52 public static object LateGet(object o,
59 if (objType == null) {
61 throw new NullReferenceException();
63 objType = o.GetType();
66 IReflect objReflect = (IReflect) objType;
68 BindingFlags flags = BindingFlags.FlattenHierarchy |
69 BindingFlags.IgnoreCase |
70 BindingFlags.Instance |
73 BindingFlags.GetProperty |
74 BindingFlags.InvokeMethod;
79 MemberInfo [] memberinfo = objReflect.GetMember (name, flags);
81 if (memberinfo == null || memberinfo.Length == 0) {
82 throw new MissingMemberException ("Public Member '" + name + "' not found on type '" + objType + "'");
85 MemberInfo mi = GetMostDerivedMemberInfo (memberinfo);
86 if (mi.MemberType == MemberTypes.Field) {
87 FieldInfo fi = (FieldInfo) mi;
88 object ret = fi.GetValue (o);
89 if (args != null && args.Length > 0)
90 return LateIndexGet (ret, args, paramnames);
94 VBBinder binder = new VBBinder (CopyBack);
95 return binder.InvokeMember (name, flags, objType, objReflect, o, args, null, null, paramnames);
98 [System.Diagnostics.DebuggerStepThroughAttribute]
99 [System.Diagnostics.DebuggerHiddenAttribute]
100 public static void LateSetComplex(
109 LateSet(o, objType, name, args, paramnames);
112 [System.Diagnostics.DebuggerStepThroughAttribute]
113 [System.Diagnostics.DebuggerHiddenAttribute]
114 public static void LateSet (object o,
118 string[] paramnames) {
120 if (objType == null) {
122 throw new NullReferenceException();
123 objType = o.GetType();
126 IReflect objReflect = (IReflect) objType;
128 BindingFlags flags = BindingFlags.FlattenHierarchy |
129 BindingFlags.IgnoreCase |
130 BindingFlags.Instance |
131 BindingFlags.Public |
132 BindingFlags.Static |
133 BindingFlags.SetProperty |
134 BindingFlags.InvokeMethod;
140 MemberInfo [] memberinfo = objReflect.GetMember (name, flags);
142 if (memberinfo == null || memberinfo.Length == 0) {
143 throw new MissingMemberException ("Public Member '" + name + "' not found on type '" + objType + "'");
146 MemberInfo mi = GetMostDerivedMemberInfo (memberinfo);
147 if (mi.MemberType == MemberTypes.Field) {
148 FieldInfo fi = (FieldInfo) mi;
149 if (args == null || args.Length == 0) {
150 throw new MissingMemberException ("Public Member '" + name + "' not found on type '" + objType + "' that can be assigned the given set of arguments");
153 if (fi.IsInitOnly || fi.IsPrivate) {
154 throw new MissingMemberException ("Member '" + name + "' is a readonly field");
158 if (args.Length == 1)
161 fi.SetValue (o, value);
165 VBBinder binder = new VBBinder (null);
166 binder.InvokeMember (name, flags, objType, objReflect, o, args, null, null, paramnames);
170 // [System.Diagnostics.DebuggerStepThroughAttribute]
171 // [System.Diagnostics.DebuggerHiddenAttribute]
172 // public static System.Object LateIndexGet (System.Object o, System.Object[] args, System.String[] paramnames)
175 // Object binderState = null;
177 // if (o == null || args == null)
178 // throw new ArgumentException();
180 // objType = o.GetType();
181 // if (objType.IsArray) {
182 // Array a = (Array) o;
183 // int[] idxs = new int[args.Length];
184 // Array.Copy (args, idxs, args.Length);
186 // return a.GetValue(idxs);
190 // MemberInfo[] defaultMembers = objType.GetDefaultMembers();
191 // if (defaultMembers == null)
192 // throw new Exception(); // FIXME: Which exception should we throw?
194 // // We try to find a default method/property/field we can invoke/use
195 // VBBinder MyBinder = new VBBinder();
196 // BindingFlags bindingFlags = BindingFlags.IgnoreCase |
197 // BindingFlags.Instance |
198 // BindingFlags.Static |
199 // BindingFlags.Public |
200 // BindingFlags.GetProperty |
201 // BindingFlags.GetField |
202 // BindingFlags.InvokeMethod;
204 // MethodBase[] mb = new MethodBase[defaultMembers.Length];
206 // for (int x = 0; x < defaultMembers.Length; x++)
207 // if (defaultMembers[x].MemberType == MemberTypes.Property)
208 // mb[x] = ((PropertyInfo) defaultMembers[x]).GetGetMethod();
210 // mb[x] = (MethodBase) defaultMembers[x];
211 // } catch (Exception e) { }
213 // MethodBase TheMethod = MyBinder.BindToMethod (bindingFlags,
220 // if (TheMethod == null)
221 // throw new TargetInvocationException(new ArgumentNullException());
223 // return TheMethod.Invoke (o, args);
227 [System.Diagnostics.DebuggerStepThroughAttribute]
228 [System.Diagnostics.DebuggerHiddenAttribute]
229 public static object LateIndexGet(
232 string[] paramnames) {
234 throw new NullReferenceException();
236 throw new NullReferenceException();
237 Type type = o.GetType();
238 //late binding for array
241 Array objAsArray = (Array) o;
242 if (objAsArray.Rank != args.Length)
243 throw new RankException ();
245 int numArgs = args.Length;
246 int [] indexArray = new int [numArgs];
247 for (int index = 0; index < numArgs; index ++)
248 indexArray [index] = IntegerType.FromObject (args [index]);
249 return objAsArray.GetValue (indexArray);
252 //late binding for default property
253 VBBinder binder = new VBBinder (null);
254 BindingFlags flags = BindingFlags.FlattenHierarchy |
255 BindingFlags.IgnoreCase |
256 BindingFlags.Instance |
257 BindingFlags.Public |
258 BindingFlags.Static |
259 BindingFlags.GetProperty |
260 BindingFlags.InvokeMethod;
261 IReflect objReflect = (IReflect) type;
262 return binder.InvokeMember ("", flags, type, objReflect, o, args, null, null, paramnames);
265 private static string getDefaultMemberName(Type type) {
266 string defaultName = null;
267 while (type != null) {
269 throw new NotImplementedException("LateBinding not implmented");
271 // type.GetCustomAttributes(
272 // Type.GetType("System.Reflection.DefaultMemberAttribute"),
274 //if (locals != null && locals.Length != 0) {
276 // ((DefaultMemberAttribute) locals[0]).get_MemberName();
279 //type = type.get_BaseType();
283 // mono implmentation
284 // [System.Diagnostics.DebuggerStepThroughAttribute]
285 // [System.Diagnostics.DebuggerHiddenAttribute]
286 // public static void LateIndexSet (System.Object o, System.Object[] args, System.String[] paramnames)
289 // Object binderState = null;
292 // if (o == null || args == null)
293 // throw new ArgumentException();
295 // myValue = args[args.Length - 1];
296 // objType = o.GetType();
297 // if (objType.IsArray) {
298 // Array a = (Array) o;
299 // int[] idxs = new int[args.Length - 1];
300 // Array.Copy (args, idxs, args.Length -1);
301 // a.SetValue(myValue, idxs);
305 // MemberInfo[] defaultMembers = objType.GetDefaultMembers();
306 // if (defaultMembers == null)
307 // throw new Exception(); // FIXME: Which exception should we throw?
309 // // We try to find a default method/property/field we can invoke/use
310 // VBBinder MyBinder = new VBBinder();
311 // BindingFlags bindingFlags = BindingFlags.IgnoreCase |
312 // BindingFlags.Instance |
313 // BindingFlags.Static |
314 // BindingFlags.Public |
315 // BindingFlags.GetProperty |
316 // BindingFlags.GetField |
317 // BindingFlags.InvokeMethod;
319 // MethodBase[] mb = new MethodBase[defaultMembers.Length];
321 // for (int x = 0; x < defaultMembers.Length; x++)
322 // if (defaultMembers[x].MemberType == MemberTypes.Property)
323 // mb[x] = ((PropertyInfo) defaultMembers[x]).GetSetMethod();
325 // mb[x] = (MethodBase) defaultMembers[x];
326 // } catch (Exception e) { }
328 // MethodBase TheMethod = MyBinder.BindToMethod (bindingFlags,
335 // if (TheMethod == null)
336 // throw new TargetInvocationException(new ArgumentNullException());
338 // TheMethod.Invoke (o, args);
344 [System.Diagnostics.DebuggerHiddenAttribute]
345 [System.Diagnostics.DebuggerStepThroughAttribute]
346 public static void LateIndexSet(
349 string[] paramnames) {
351 throw new NullReferenceException();
352 if (args == null || args.Length == 0)
353 throw new NullReferenceException();
354 Type type = o.GetType();
355 //late binding for array
357 Array array = (Array) o;
358 if (array.Rank != args.Length - 1)
359 throw new RankException ();
360 object setValue = args [args.GetUpperBound (0)];
361 int [] indexArray = new int [args.GetUpperBound (0)];
362 for (int index = 0; index < indexArray.Length; index ++) {
363 indexArray [index] = IntegerType.FromObject (args [index]);
365 array.SetValue (setValue, indexArray);
368 //late binding for default property
369 VBBinder binder = new VBBinder (null);
370 BindingFlags flags = BindingFlags.FlattenHierarchy |
371 BindingFlags.IgnoreCase |
372 BindingFlags.Instance |
373 BindingFlags.Public |
374 BindingFlags.Static |
375 BindingFlags.SetProperty |
376 BindingFlags.InvokeMethod;
377 IReflect objReflect = (IReflect) type;
378 binder.InvokeMember ("", flags, type, objReflect, o, args, null, null, paramnames);
381 [System.Diagnostics.DebuggerHiddenAttribute]
382 [System.Diagnostics.DebuggerStepThroughAttribute]
383 public static void LateIndexSetComplex(
389 LateIndexSet(o, args, paramnames);
392 [System.Diagnostics.DebuggerStepThroughAttribute]
393 [System.Diagnostics.DebuggerHiddenAttribute]
394 public static void LateCall(
402 InternalLateCall (o, objType, name, args, paramnames, CopyBack, true);
405 [System.Diagnostics.DebuggerStepThroughAttribute]
406 [System.Diagnostics.DebuggerHiddenAttribute]
407 internal static object InternalLateCall( object o,
414 if (objType == null) {
416 throw new NullReferenceException();
418 objType = o.GetType();
421 IReflect objReflect = (IReflect) objType;
423 BindingFlags flags = BindingFlags.FlattenHierarchy |
424 BindingFlags.IgnoreCase |
425 BindingFlags.Instance |
426 BindingFlags.Public |
427 BindingFlags.Static |
428 BindingFlags.InvokeMethod;
433 MemberInfo [] memberinfo = objReflect.GetMember (name, flags);
435 if (memberinfo == null || memberinfo.Length == 0) {
436 throw new MissingMemberException ("Public Member '" + name + "' not found on type '" + objType + "'");
440 foreach (MemberInfo mi in memberinfo) {
441 if (mi.MemberType == MemberTypes.Field)
442 throw new ArgumentException ("Expression '" + name + "' is not a procedure, but occurs as a target of a procedure call");
446 VBBinder binder = new VBBinder (CopyBack);
447 return binder.InvokeMember (name, flags, objType, objReflect, o, args, null, null, paramnames);
450 private static MemberInfo GetMostDerivedMemberInfo (MemberInfo [] mi)
452 if (mi == null || mi.Length == 0)
454 MemberInfo m = mi [0];
455 for (int index = 1; index < mi.Length; index ++) {
456 MemberInfo m1 = mi [index];
457 if (m1.DeclaringType.IsSubclassOf (m.DeclaringType))