Example #1
0
        /// <summary>
        /// Creates a new ClrStaticTypeWrapper object.
        /// </summary>
        /// <param name="engine"> The associated script engine. </param>
        /// <param name="type"> The CLR type to wrap. </param>
        private ClrStaticTypeWrapper(ScriptEngine engine, Type type)
            : base(engine, GetPrototypeObject(engine, type))
        {
            this.WrappedType = type;

            // Pick up the public constructors, if any.
            var constructors = type.GetConstructors();

            if (constructors.Length > 0)
            {
                this.constructBinder = new ClrBinder(constructors);
            }
            else
            {
                // The built-in primitive types do not have constructors, but we still want to
                // allow their construction since there is no way to construct them otherwise.
                // Pretend that a constructor does exist.
                switch (Type.GetTypeCode(type))
                {
                case TypeCode.Int32:
                    this.constructBinder = new ClrBinder(ReflectionHelpers.Convert_ToInt32_Double);
                    break;
                }
            }

            this.FastSetProperty("name", type.Name, PropertyAttributes.Configurable);
            if (this.constructBinder != null)
            {
                this.FastSetProperty("length", this.constructBinder.FunctionLength, PropertyAttributes.Configurable);
            }

            // Populate the fields, properties and methods.
            PopulateMembers(this, type, BindingFlags.Static);
        }
Example #2
0
        //     METHODS
        //_________________________________________________________________________________________


        /// <summary>
        /// Populates the given object with properties, field and methods based on the given .NET
        /// type.
        /// </summary>
        /// <param name="target"> The object to populate. </param>
        /// <param name="type"> The .NET type to search for methods. </param>
        /// <param name="flags"> <c>BindingFlags.Static</c> to populate static methods;
        /// <c>BindingFlags.Instance</c> to populate instance methods. </param>
        internal static void PopulateMembers(ObjectInstance target, Type type, BindingFlags flags)
        {
            // Register static methods as functions.
            var methodGroups = new Dictionary <string, List <MethodBase> >();

            foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.DeclaredOnly | flags))
            {
                switch (member.MemberType)
                {
                case MemberTypes.Method:
                    MethodInfo        method = (MethodInfo)member;
                    List <MethodBase> methodGroup;
                    if (methodGroups.TryGetValue(method.Name, out methodGroup) == true)
                    {
                        methodGroup.Add(method);
                    }
                    else
                    {
                        methodGroups.Add(method.Name, new List <MethodBase>()
                        {
                            method
                        });
                    }
                    break;

                case MemberTypes.Property:
                    PropertyInfo property  = (PropertyInfo)member;
                    var          getMethod = property.GetGetMethod();
                    ClrFunction  getter    = getMethod == null ? null : new ClrFunction(target.Engine.Function.InstancePrototype, new ClrBinder(getMethod));
                    var          setMethod = property.GetSetMethod();
                    ClrFunction  setter    = setMethod == null ? null : new ClrFunction(target.Engine.Function.InstancePrototype, new ClrBinder(setMethod));
                    target.DefineProperty(property.Name, new PropertyDescriptor(getter, setter, PropertyAttributes.NonEnumerable), false);

                    // Property getters and setters also show up as methods, so remove them here.
                    // NOTE: only works if properties are enumerated after methods.
                    if (getMethod != null)
                    {
                        methodGroups.Remove(getMethod.Name);
                    }
                    if (setMethod != null)
                    {
                        methodGroups.Remove(setMethod.Name);
                    }
                    break;

                case MemberTypes.Field:
                    FieldInfo   field       = (FieldInfo)member;
                    ClrFunction fieldGetter = new ClrFunction(target.Engine.Function.InstancePrototype, new FieldGetterBinder(field));
                    ClrFunction fieldSetter = new ClrFunction(target.Engine.Function.InstancePrototype, new FieldSetterBinder(field));
                    target.DefineProperty(field.Name, new PropertyDescriptor(fieldGetter, fieldSetter, PropertyAttributes.NonEnumerable), false);
                    break;

                case MemberTypes.Constructor:
                case MemberTypes.NestedType:
                case MemberTypes.Event:
                case MemberTypes.TypeInfo:
                    // Support not yet implemented.
                    break;
                }
            }
            foreach (var methodGroup in methodGroups.Values)
            {
                var binder   = new ClrBinder(methodGroup);
                var function = new ClrFunction(target.Engine.Function.InstancePrototype, binder);
                target.FastSetProperty(binder.Name, function, PropertyAttributes.NonEnumerable, overwriteAttributes: true);
            }
        }