/// <summary> /// Initializes a new instance of the <see cref="ArrayMemberDescriptor"/> class. /// </summary> /// <param name="name">The name.</param> /// <param name="isSetter">if set to <c>true</c> is a setter indexer.</param> /// <param name="indexerParams">The indexer parameters.</param> public ArrayMemberDescriptor(string name, bool isSetter, ParameterDescriptor[] indexerParams) : base( name, isSetter ? (Func<object, ScriptExecutionContext, CallbackArguments, object>)ArrayIndexerSet : (Func<object, ScriptExecutionContext, CallbackArguments, object>)ArrayIndexerGet, indexerParams) { m_IsSetter = isSetter; }
/// <summary> /// Initializes a new instance of the <see cref="MethodMemberDescriptor"/> class. /// </summary> /// <param name="methodBase">The MethodBase (MethodInfo or ConstructorInfo) got through reflection.</param> /// <param name="accessMode">The interop access mode.</param> /// <exception cref="System.ArgumentException">Invalid accessMode</exception> public MethodMemberDescriptor(MethodBase methodBase, InteropAccessMode accessMode = InteropAccessMode.Default) { CheckMethodIsCompatible(methodBase, true); IsConstructor = (methodBase is ConstructorInfo); this.MethodInfo = methodBase; bool isStatic = methodBase.IsStatic || IsConstructor; if (IsConstructor) m_IsAction = false; else m_IsAction = ((MethodInfo)methodBase).ReturnType == typeof(void); ParameterInfo[] reflectionParams = methodBase.GetParameters(); ParameterDescriptor[] parameters; if (this.MethodInfo.DeclaringType.IsArray) { m_IsArrayCtor = true; int rank = this.MethodInfo.DeclaringType.GetArrayRank(); parameters = new ParameterDescriptor[rank]; for (int i = 0; i < rank; i++) parameters[i] = new ParameterDescriptor("idx" + i.ToString(), typeof(int)); } else { parameters = reflectionParams.Select(pi => new ParameterDescriptor(pi)).ToArray(); } bool isExtensionMethod = (methodBase.IsStatic && parameters.Length > 0 && methodBase.GetCustomAttributes(typeof(ExtensionAttribute), false).Any()); base.Initialize(methodBase.Name, isStatic, parameters, isExtensionMethod); // adjust access mode if (Script.GlobalOptions.Platform.IsRunningOnAOT()) accessMode = InteropAccessMode.Reflection; if (accessMode == InteropAccessMode.Default) accessMode = UserData.DefaultAccessMode; if (accessMode == InteropAccessMode.HideMembers) throw new ArgumentException("Invalid accessMode"); if (parameters.Any(p => p.Type.IsByRef)) accessMode = InteropAccessMode.Reflection; this.AccessMode = accessMode; if (AccessMode == InteropAccessMode.Preoptimized) ((IOptimizableDescriptor)this).Optimize(); }
/// <summary> /// Initializes a new instance of the /// <see cref="MethodMemberDescriptor" /> class /// representing the default empty ctor for a value type. /// </summary> /// <param name="valueType">Type of the value.</param> /// <exception cref="System.ArgumentException">valueType is not a value type</exception> public ValueTypeDefaultCtorMemberDescriptor(Type valueType) { if (!valueType.IsValueType) throw new ArgumentException("valueType is not a value type"); Name = "__new"; Parameters = new ParameterDescriptor[0]; ValueTypeDefaultCtor = valueType; }
/// <summary> /// Initializes this instance. /// This *MUST* be called by the constructors extending this class to complete initialization. /// </summary> /// <param name="funcName">Name of the function.</param> /// <param name="isStatic">if set to <c>true</c> [is static].</param> /// <param name="parameters">The parameters.</param> /// <param name="isExtensionMethod">if set to <c>true</c> [is extension method].</param> protected void Initialize(string funcName, bool isStatic, ParameterDescriptor[] parameters, bool isExtensionMethod) { this.Name = funcName; this.IsStatic = isStatic; this.Parameters = parameters; if (isExtensionMethod) this.ExtensionMethodType = Parameters[0].Type; if (Parameters.Length > 0 && Parameters[Parameters.Length - 1].IsVarArgs) { VarArgsArrayType = Parameters[Parameters.Length - 1].Type; VarArgsElementType = Parameters[Parameters.Length - 1].Type.GetElementType(); } SortDiscriminant = string.Join(":", Parameters.Select(pi => pi.Type.FullName).ToArray()); }
/// <summary> /// Fills the member list. /// </summary> private void FillMemberList() { HashSet<string> membersToIgnore = new HashSet<string>( this.Type .GetCustomAttributes(typeof(MoonSharpHideMemberAttribute), true) .OfType<MoonSharpHideMemberAttribute>() .Select(a => a.MemberName) ); Type type = this.Type; var accessMode = this.AccessMode; if (AccessMode == InteropAccessMode.HideMembers) return; // add declared constructors foreach (ConstructorInfo ci in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { 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 (type.IsValueType && !membersToIgnore.Contains("__new")) AddMember("__new", new ValueTypeDefaultCtorMemberDescriptor(type)); // add methods to method list and metamethods foreach (MethodInfo mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { 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 type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { 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 type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { if (fi.IsSpecialName || membersToIgnore.Contains(fi.Name)) continue; AddMember(fi.Name, FieldMemberDescriptor.TryCreateIfVisible(fi, this.AccessMode)); } // get events foreach (EventInfo ei in type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { 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 type.GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Public)) { if (membersToIgnore.Contains(nestedType.Name)) continue; if (!nestedType.IsGenericTypeDefinition) { if (nestedType.IsNestedPublic || nestedType.GetCustomAttributes(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)); } } }
/// <summary> /// Initializes a new instance of the <see cref="ObjectCallbackMemberDescriptor"/> class. /// Members defined with this constructor will support overload resolution. /// </summary> /// <param name="funcName">Name of the function.</param> /// <param name="callBack">The call back.</param> /// <param name="parameters">The parameters.</param> public ObjectCallbackMemberDescriptor(string funcName, Func<object, ScriptExecutionContext, CallbackArguments, object> callBack, ParameterDescriptor[] parameters) { m_CallbackFunc = callBack; Initialize(funcName, false, parameters, false); }