/// <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 PropertyMemberDescriptor TryCreateIfVisible(PropertyInfo pi, InteropAccessMode accessMode) { MethodInfo getter = Framework.Do.GetGetMethod(pi); MethodInfo setter = Framework.Do.GetSetMethod(pi); bool?pvisible = pi.GetVisibilityFromAttributes(); bool?gvisible = getter.GetVisibilityFromAttributes(); bool?svisible = setter.GetVisibilityFromAttributes(); if (pvisible.HasValue) { return(PropertyMemberDescriptor.TryCreate(pi, accessMode, (gvisible ?? pvisible.Value) ? getter : null, (svisible ?? pvisible.Value) ? setter : null)); } else { return(PropertyMemberDescriptor.TryCreate(pi, accessMode, (gvisible ?? getter.IsPublic) ? getter : null, (svisible ?? setter.IsPublic) ? setter : null)); } }
/// <summary> /// Fills the member list. /// </summary> private void FillMemberList() { HashSet <string> membersToIgnore = new HashSet <string>( Framework.Do.GetCustomAttributes(this.Type, typeof(MoonSharpHideMemberAttribute), true) .OfType <MoonSharpHideMemberAttribute>() .Select(a => a.MemberName) ); Type type = this.Type; if (AccessMode == InteropAccessMode.HideMembers) { return; } if (!type.IsDelegateType()) { // add declared constructors foreach (ConstructorInfo ci in Framework.Do.GetConstructors(type)) { if (membersToIgnore.Contains("__new")) { continue; } AddMember("__new", MethodMemberDescriptor.TryCreateIfVisible(ci, this.AccessMode)); } // valuetypes don't reflect their empty ctor.. actually empty ctors are a perversion, we don't care and implement ours if (Framework.Do.IsValueType(type) && !membersToIgnore.Contains("__new")) { AddMember("__new", new ValueTypeDefaultCtorMemberDescriptor(type)); } } // add methods to method list and metamethods foreach (MethodInfo mi in Framework.Do.GetMethods(type)) { if (membersToIgnore.Contains(mi.Name)) { continue; } MethodMemberDescriptor md = MethodMemberDescriptor.TryCreateIfVisible(mi, this.AccessMode); if (md != null) { if (!MethodMemberDescriptor.CheckMethodIsCompatible(mi, false)) { continue; } // transform explicit/implicit conversions to a friendlier name. string name = mi.Name; if (mi.IsSpecialName && (mi.Name == SPECIALNAME_CAST_EXPLICIT || mi.Name == SPECIALNAME_CAST_IMPLICIT)) { name = mi.ReturnType.GetConversionMethodName(); } AddMember(name, md); foreach (string metaname in mi.GetMetaNamesFromAttributes()) { AddMetaMember(metaname, md); } } } // get properties foreach (PropertyInfo pi in Framework.Do.GetProperties(type)) { if (pi.IsSpecialName || pi.GetIndexParameters().Any() || membersToIgnore.Contains(pi.Name)) { continue; } AddMember(pi.Name, PropertyMemberDescriptor.TryCreateIfVisible(pi, this.AccessMode)); } // get fields foreach (FieldInfo fi in Framework.Do.GetFields(type)) { if (fi.IsSpecialName || membersToIgnore.Contains(fi.Name)) { continue; } AddMember(fi.Name, FieldMemberDescriptor.TryCreateIfVisible(fi, this.AccessMode)); } // get events foreach (EventInfo ei in Framework.Do.GetEvents(type)) { if (ei.IsSpecialName || membersToIgnore.Contains(ei.Name)) { continue; } AddMember(ei.Name, EventMemberDescriptor.TryCreateIfVisible(ei, this.AccessMode)); } // get nested types and create statics foreach (Type nestedType in Framework.Do.GetNestedTypes(type)) { if (membersToIgnore.Contains(nestedType.Name)) { continue; } if (!Framework.Do.IsGenericTypeDefinition(nestedType)) { if (Framework.Do.IsNestedPublic(nestedType) || Framework.Do.GetCustomAttributes(nestedType, typeof(MoonSharpUserDataAttribute), true).Length > 0) { var descr = UserData.RegisterType(nestedType, this.AccessMode); if (descr != null) { AddDynValue(nestedType.Name, UserData.CreateStatic(nestedType)); } } } } if (!membersToIgnore.Contains("[this]")) { if (Type.IsArray) { int rank = Type.GetArrayRank(); ParameterDescriptor[] get_pars = new ParameterDescriptor[rank]; ParameterDescriptor[] set_pars = new ParameterDescriptor[rank + 1]; for (int i = 0; i < rank; i++) { get_pars[i] = set_pars[i] = new ParameterDescriptor("idx" + i.ToString(), typeof(int)); } set_pars[rank] = new ParameterDescriptor("value", Type.GetElementType()); AddMember(SPECIALNAME_INDEXER_SET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_SET, true, set_pars)); AddMember(SPECIALNAME_INDEXER_GET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_GET, false, get_pars)); } else if (Type == typeof(Array)) { AddMember(SPECIALNAME_INDEXER_SET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_SET, true)); AddMember(SPECIALNAME_INDEXER_GET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_GET, false)); } } }