protected internal StandardUserDataDescriptor(Type type, InteropAccessMode accessMode, string friendlyName) { if (accessMode == InteropAccessMode.Default) { accessMode = UserData.DefaultAccessMode; } Type = type; Name = type.FullName; AccessMode = accessMode; FriendlyName = friendlyName; if (AccessMode != InteropAccessMode.HideMembers) { foreach (MethodInfo mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static)) { if (CheckVisibility(mi.GetCustomAttributes(true), mi.IsPublic)) { if (mi.IsSpecialName) { continue; } var md = new StandardUserDataMethodDescriptor(mi, this.AccessMode); if (m_Methods.ContainsKey(md.Name)) { continue; } //throw new ArgumentException(string.Format("{0}.{1} has overloads", Name, md.Name)); m_Methods.Add(md.Name, md); } } foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { if (CheckVisibility(pi.GetCustomAttributes(true), IsPropertyInfoPublic(pi))) { var pd = new StandardUserDataPropertyDescriptor(pi, this.AccessMode); m_Properties.Add(pd.Name, pd); } } } }
/// <summary> /// Tries to create a new StandardUserDataPropertyDescriptor, returning <c>null</c> in case the property is not /// visible to script code. /// </summary> /// <param name="pi">The PropertyInfo.</param> /// <param name="accessMode">The <see cref="InteropAccessMode" /></param> /// <returns>A new StandardUserDataPropertyDescriptor or null.</returns> public static StandardUserDataPropertyDescriptor TryCreateIfVisible(PropertyInfo pi, InteropAccessMode accessMode) { MethodInfo getter = pi.GetGetMethod(true); MethodInfo setter = pi.GetSetMethod(true); bool?pvisible = StandardUserDataDescriptor.GetVisibilityFromAttributes(pi); bool?gvisible = StandardUserDataDescriptor.GetVisibilityFromAttributes(getter); bool?svisible = StandardUserDataDescriptor.GetVisibilityFromAttributes(setter); if (pvisible.HasValue) { return(StandardUserDataPropertyDescriptor.TryCreate(pi, accessMode, (gvisible ?? pvisible.Value) ? getter : null, (svisible ?? pvisible.Value) ? setter : null)); } else { return(StandardUserDataPropertyDescriptor.TryCreate(pi, accessMode, (gvisible ?? getter.IsPublic) ? getter : null, (svisible ?? setter.IsPublic) ? setter : null)); } }
/// <summary> /// Tries to perform an indexing "set" operation by checking methods and properties for the given indexName /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="indexName">Member name to be indexed.</param> /// <param name="value">The value.</param> /// <returns></returns> protected virtual bool TrySetIndex(Script script, object obj, string indexName, DynValue value) { StandardUserDataPropertyDescriptor pdesc = m_Properties.GetOrDefault(indexName); if (pdesc != null) { pdesc.SetValue(script, obj, value); return(true); } else { StandardUserDataFieldDescriptor fdesc = m_Fields.GetOrDefault(indexName); if (fdesc != null) { fdesc.SetValue(script, obj, value); return(true); } else { return(false); } } }
/// <summary> /// Initializes a new instance of the <see cref="StandardUserDataDescriptor"/> class. /// </summary> /// <param name="type">The type this descriptor refers to.</param> /// <param name="accessMode">The interop access mode this descriptor uses for members access</param> /// <param name="friendlyName">A human readable friendly name of the descriptor.</param> protected internal StandardUserDataDescriptor(Type type, InteropAccessMode accessMode, string friendlyName) { if (Script.GlobalOptions.Platform.IsRunningOnAOT()) { accessMode = InteropAccessMode.Reflection; } if (accessMode == InteropAccessMode.Default) { accessMode = UserData.DefaultAccessMode; } Type = type; Name = type.FullName; AccessMode = accessMode; FriendlyName = friendlyName; if (AccessMode != InteropAccessMode.HideMembers) { // get first constructor StandardUserDataOverloadedMethodDescriptor constructors = null; foreach (ConstructorInfo ci in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { StandardUserDataMethodDescriptor md = StandardUserDataMethodDescriptor.TryCreateIfVisible(ci, this.AccessMode); if (md != null) { if (constructors == null) { constructors = new StandardUserDataOverloadedMethodDescriptor("__new", this.Type) { IgnoreExtensionMethods = true } } ; constructors.AddOverload(md); } } // valuetypes don't reflect their empty ctor.. actually empty ctors are a perversion, we don't care and implement ours if (type.IsValueType) { if (constructors == null) { constructors = new StandardUserDataOverloadedMethodDescriptor("__new", this.Type); } constructors.AddOverload(new StandardUserDataMethodDescriptor(type, accessMode)); } if (constructors != null) { m_Methods.Add("__new", constructors); } // get methods foreach (MethodInfo mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { StandardUserDataMethodDescriptor md = StandardUserDataMethodDescriptor.TryCreateIfVisible(mi, this.AccessMode); if (md != null) { if (!StandardUserDataMethodDescriptor.CheckMethodIsCompatible(mi, false)) { continue; } Dictionary <string, StandardUserDataOverloadedMethodDescriptor> dic = m_Methods; string name = mi.Name; if (mi.IsSpecialName && (mi.Name == CASTINGS_EXPLICIT || mi.Name == CASTINGS_IMPLICIT)) { name = GetConversionMethodName(mi.ReturnType); } if (m_Methods.ContainsKey(name)) { m_Methods[name].AddOverload(md); } else { m_Methods.Add(name, new StandardUserDataOverloadedMethodDescriptor(name, this.Type, md)); } foreach (string metaname in GetMetaNamesFromAttributes(mi)) { if (m_MetaMethods.ContainsKey(metaname)) { m_MetaMethods[metaname].AddOverload(md); } else { m_MetaMethods.Add(metaname, new StandardUserDataOverloadedMethodDescriptor(metaname, this.Type, md) { IgnoreExtensionMethods = true }); } } } } // get properties foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { if (pi.IsSpecialName || pi.GetIndexParameters().Any()) { continue; } var pd = StandardUserDataPropertyDescriptor.TryCreateIfVisible(pi, this.AccessMode); if (pd != null) { m_Properties.Add(pd.Name, pd); } } // get fields foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { if (fi.IsSpecialName) { continue; } var fd = StandardUserDataFieldDescriptor.TryCreateIfVisible(fi, this.AccessMode); if (fd != null) { m_Fields.Add(fd.Name, fd); } } // get events foreach (EventInfo ei in type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { if (ei.IsSpecialName) { continue; } var ed = StandardUserDataEventDescriptor.TryCreateIfVisible(ei, this.AccessMode); if (ed != null) { m_Events.Add(ei.Name, ed); } } } }