예제 #1
0
 public NativeMethodOverload(
     ICollection <MethodInfo> methods,
     JsObject prototype,
     IGlobal global)
     : base(prototype)
 {
     if (global == null)
     {
         throw new ArgumentNullException(nameof(global));
     }
     this.m_marshaller = global.Marshaller;
     using (IEnumerator <MethodInfo> enumerator = methods.GetEnumerator())
     {
         if (enumerator.MoveNext())
         {
             this.Name = enumerator.Current.Name;
         }
     }
     foreach (MethodInfo method in (IEnumerable <MethodInfo>)methods)
     {
         if (method.IsGenericMethodDefinition)
         {
             this.m_generics.AddLast(method);
         }
         else if (!method.ContainsGenericParameters)
         {
             this.m_methods.AddLast(method);
         }
     }
     this.m_overloads = new NativeOverloadImpl <MethodInfo, JsMethodImpl>(this.m_marshaller, new NativeOverloadImpl <MethodInfo, JsMethodImpl> .GetMembersDelegate(this.GetMembers), new NativeOverloadImpl <MethodInfo, JsMethodImpl> .WrapMmemberDelegate(this.WrapMember));
 }
예제 #2
0
        public NativeMethodOverload(ICollection <MethodInfo> methods, JsObject prototype, IGlobal global)
            : base(prototype)
        {
            if (global == null)
            {
                throw new ArgumentNullException("global");
            }
            m_marshaller = global.Marshaller;

            foreach (MethodInfo info in methods)
            {
                Name = info.Name;
                break;
            }

            foreach (var method in methods)
            {
                if (method.IsGenericMethodDefinition)
                {
                    m_generics.AddLast(method);
                }
                else if (!method.ContainsGenericParameters)
                {
                    m_methods.AddLast(method);
                }
            }

            m_overloads = new NativeOverloadImpl <MethodInfo, JsMethodImpl>(
                m_marshaller,
                new NativeOverloadImpl <MethodInfo, JsMethodImpl> .GetMembersDelegate(this.GetMembers),
                new NativeOverloadImpl <MethodInfo, JsMethodImpl> .WrapMmemberDelegate(this.WrapMember)
                );
        }
예제 #3
0
        protected TMemberInfo MatchMethod(Type[] args, IEnumerable <TMemberInfo> members)
        {
            LinkedList <NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch> linkedList = new LinkedList <NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch>();

            foreach (TMemberInfo member in members)
            {
                linkedList.AddLast(new NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch()
                {
                    method     = member,
                    parameters = Array.ConvertAll <ParameterInfo, Type>(member.GetParameters(), (Converter <ParameterInfo, Type>)(p => p.ParameterType)),
                    weight     = 0
                });
            }
            if (args != null)
            {
                for (int index = 0; index < args.Length; ++index)
                {
                    Type type = args[index];
                    LinkedListNode <NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch> next;
                    for (LinkedListNode <NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch> node = linkedList.First; node != null; node = next)
                    {
                        next = node.Next;
                        if (type != null)
                        {
                            Type parameter = node.Value.parameters[index];
                            if (type.Equals(parameter))
                            {
                                ++node.Value.weight;
                            }
                            else if ((!typeof(Delegate).IsAssignableFrom(parameter) || !typeof(JsFunction).IsAssignableFrom(type)) && !this.m_marshaller.IsAssignable(parameter, type))
                            {
                                linkedList.Remove(node);
                            }
                        }
                        else if (node.Value.parameters[index].IsValueType)
                        {
                            linkedList.Remove(node);
                        }
                    }
                }
            }
            NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch methodMatch1 = (NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch)null;
            foreach (NativeOverloadImpl <TMemberInfo, TImpl> .MethodMatch methodMatch2 in linkedList)
            {
                methodMatch1 = methodMatch1 == null ? methodMatch2 : (methodMatch1.weight < methodMatch2.weight ? methodMatch2 : methodMatch1);
            }
            return(methodMatch1 == null ? default(TMemberInfo) : methodMatch1.method);
        }
예제 #4
0
 public NativeIndexer(Marshaller marshaller, MethodInfo[] getters, MethodInfo[] setters)
 {
     m_getOverload = new NativeOverloadImpl <MethodInfo, JsIndexerGetter>(
         marshaller,
         delegate(Type[] genericArgs, int Length)
     {
         return(Array.FindAll <MethodInfo>(getters, mi => mi.GetParameters().Length == Length));
     },
         new NativeOverloadImpl <MethodInfo, JsIndexerGetter> .WrapMmemberDelegate(marshaller.WrapIndexerGetter)
         );
     m_setOverload = new NativeOverloadImpl <MethodInfo, JsIndexerSetter>(
         marshaller,
         delegate(Type[] genericArgs, int Length)
     {
         return(Array.FindAll <MethodInfo>(setters, mi => mi.GetParameters().Length == Length));
     },
         new NativeOverloadImpl <MethodInfo, JsIndexerSetter> .WrapMmemberDelegate(marshaller.WrapIndexerSetter)
         );
 }
예제 #5
0
 public NativeOverloadImpl(
     Marshaller marshaller,
     NativeOverloadImpl <TMemberInfo, TImpl> .GetMembersDelegate getMembers,
     NativeOverloadImpl <TMemberInfo, TImpl> .WrapMmemberDelegate wrapMember)
 {
     if (marshaller == null)
     {
         throw new ArgumentNullException(nameof(marshaller));
     }
     if (getMembers == null)
     {
         throw new ArgumentNullException(nameof(getMembers));
     }
     if (wrapMember == null)
     {
         throw new ArgumentNullException(nameof(wrapMember));
     }
     this.m_marshaller = marshaller;
     this.GetMembers   = getMembers;
     this.WrapMember   = wrapMember;
 }
예제 #6
0
 public NativeIndexer(Marshaller marshaller, MethodInfo[] getters, MethodInfo[] setters)
 {
     this.m_getOverload = new NativeOverloadImpl <MethodInfo, JsIndexerGetter>(marshaller, (NativeOverloadImpl <MethodInfo, JsIndexerGetter> .GetMembersDelegate)((genericArgs, Length) => (IEnumerable <MethodInfo>)Array.FindAll <MethodInfo>(getters, (Predicate <MethodInfo>)(mi => mi.GetParameters().Length == Length))), new NativeOverloadImpl <MethodInfo, JsIndexerGetter> .WrapMmemberDelegate(marshaller.WrapIndexerGetter));
     this.m_setOverload = new NativeOverloadImpl <MethodInfo, JsIndexerSetter>(marshaller, (NativeOverloadImpl <MethodInfo, JsIndexerSetter> .GetMembersDelegate)((genericArgs, Length) => (IEnumerable <MethodInfo>)Array.FindAll <MethodInfo>(setters, (Predicate <MethodInfo>)(mi => mi.GetParameters().Length == Length))), new NativeOverloadImpl <MethodInfo, JsIndexerSetter> .WrapMmemberDelegate(marshaller.WrapIndexerSetter));
 }
예제 #7
0
        public NativeConstructor(
            Type type,
            IGlobal global,
            JsObject PrototypePrototype,
            JsObject prototype)
            : base(global, prototype)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (type.IsGenericType && type.ContainsGenericParameters)
            {
                throw new InvalidOperationException("A native constructor can't be built against an open generic");
            }
            this.m_marshaller  = global.Marshaller;
            this.reflectedType = type;
            this.Name          = type.FullName;
            if (!type.IsAbstract)
            {
                this.m_constructors = type.GetConstructors();
            }
            this.DefineOwnProperty(JsFunction.PROTOTYPE, PrototypePrototype == null ? (JsInstance)this.Global.ObjectClass.New((JsFunction)this) : (JsInstance)this.Global.ObjectClass.New((JsFunction)this, PrototypePrototype), PropertyAttributes.ReadOnly | PropertyAttributes.DontEnum | PropertyAttributes.DontDelete);
            this.m_overloads = new NativeOverloadImpl <ConstructorInfo, ConstructorImpl>(this.m_marshaller, new NativeOverloadImpl <ConstructorInfo, ConstructorImpl> .GetMembersDelegate(this.GetMembers), new NativeOverloadImpl <ConstructorInfo, ConstructorImpl> .WrapMmemberDelegate(this.WrapMember));
            if (type.IsValueType)
            {
                this.m_overloads.DefineCustomOverload(new Type[0], new Type[0], (ConstructorImpl)Delegate.CreateDelegate(typeof(ConstructorImpl), typeof(NativeConstructor).GetMethod("CreateStruct", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(type)));
            }
            Dictionary <string, LinkedList <MethodInfo> > dictionary = new Dictionary <string, LinkedList <MethodInfo> >();

            foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
            {
                if (!method.ReturnType.IsByRef)
                {
                    if (!dictionary.ContainsKey(method.Name))
                    {
                        dictionary[method.Name] = new LinkedList <MethodInfo>();
                    }
                    dictionary[method.Name].AddLast(method);
                }
            }
            foreach (KeyValuePair <string, LinkedList <MethodInfo> > keyValuePair in dictionary)
            {
                this.DefineOwnProperty(keyValuePair.Key, (JsInstance)this.ReflectOverload((ICollection <MethodInfo>)keyValuePair.Value));
            }
            foreach (PropertyInfo property in type.GetProperties(BindingFlags.Static | BindingFlags.Public))
            {
                this.DefineOwnProperty((Descriptor)this.Global.Marshaller.MarshalPropertyInfo(property, (JsDictionaryObject)this));
            }
            foreach (FieldInfo field in type.GetFields(BindingFlags.Static | BindingFlags.Public))
            {
                this.DefineOwnProperty((Descriptor)this.Global.Marshaller.MarshalFieldInfo(field, (JsDictionaryObject)this));
            }
            if (type.IsEnum)
            {
                string[] names    = Enum.GetNames(type);
                object[] objArray = new object[names.Length];
                Enum.GetValues(type).CopyTo((Array)objArray, 0);
                for (int index = 0; index < names.Length; ++index)
                {
                    this.DefineOwnProperty(names[index], (JsInstance)this.Global.ObjectClass.New(objArray[index], this.PrototypeProperty));
                }
            }
            foreach (Type nestedType in type.GetNestedTypes(BindingFlags.Public))
            {
                this.DefineOwnProperty(nestedType.Name, this.Global.Marshaller.MarshalClrValue <Type>(nestedType), PropertyAttributes.DontEnum);
            }
            LinkedList <MethodInfo> linkedList1 = new LinkedList <MethodInfo>();
            LinkedList <MethodInfo> linkedList2 = new LinkedList <MethodInfo>();

            foreach (PropertyInfo property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                ParameterInfo[] indexParameters = property.GetIndexParameters();
                if (indexParameters == null || indexParameters.Length == 0)
                {
                    this.m_properties.AddLast(global.Marshaller.MarshalPropertyInfo(property, (JsDictionaryObject)this));
                }
                else if (property.Name == "Item" && indexParameters.Length == 1)
                {
                    if (property.CanRead)
                    {
                        linkedList1.AddLast(property.GetGetMethod());
                    }
                    if (property.CanWrite)
                    {
                        linkedList2.AddLast(property.GetSetMethod());
                    }
                }
            }
            if (linkedList1.Count > 0 || linkedList2.Count > 0)
            {
                MethodInfo[] methodInfoArray1 = new MethodInfo[linkedList1.Count];
                linkedList1.CopyTo(methodInfoArray1, 0);
                MethodInfo[] methodInfoArray2 = new MethodInfo[linkedList2.Count];
                linkedList2.CopyTo(methodInfoArray2, 0);
                this.m_indexer = (INativeIndexer) new NativeIndexer(this.m_marshaller, methodInfoArray1, methodInfoArray2);
            }
            if (this.reflectedType.IsArray)
            {
                this.m_indexer = (INativeIndexer)typeof(NativeArrayIndexer <>).MakeGenericType(this.reflectedType.GetElementType()).GetConstructor(new Type[1]
                {
                    typeof(Marshaller)
                }).Invoke(new object[1]
                {
                    (object)this.m_marshaller
                });
            }
            foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.Public))
            {
                this.m_properties.AddLast(global.Marshaller.MarshalFieldInfo(field, (JsDictionaryObject)this));
            }
        }
예제 #8
0
        public NativeConstructor(Type type, IGlobal global, JsObject PrototypePrototype, JsObject prototype) :
            base(global, prototype)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (type.IsGenericType && type.ContainsGenericParameters)
            {
                throw new InvalidOperationException("A native constructor can't be built against an open generic");
            }

            m_marshaller = global.Marshaller;

            reflectedType = type;
            Name          = type.FullName;

            if (!type.IsAbstract)
            {
                m_constructors = type.GetConstructors();
            }

            DefineOwnProperty(PROTOTYPE, PrototypePrototype == null ? Global.ObjectClass.New(this) : Global.ObjectClass.New(this, PrototypePrototype), PropertyAttributes.DontEnum | PropertyAttributes.DontDelete | PropertyAttributes.ReadOnly);

            m_overloads = new NativeOverloadImpl <ConstructorInfo, ConstructorImpl>(
                m_marshaller,
                new NativeOverloadImpl <ConstructorInfo, ConstructorImpl> .GetMembersDelegate(this.GetMembers),
                new NativeOverloadImpl <ConstructorInfo, ConstructorImpl> .WrapMmemberDelegate(this.WrapMember)
                );

            // if this is a value type, define a default constructor
            if (type.IsValueType)
            {
                m_overloads.DefineCustomOverload(
                    new Type[0],
                    new Type[0],
                    (ConstructorImpl)Delegate.CreateDelegate(
                        typeof(ConstructorImpl),
                        typeof(NativeConstructor).GetMethod("CreateStruct", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(type)
                        )
                    );
            }

            // now we should find all static members and add them as a properties

            // members are grouped by their names
            Dictionary <string, LinkedList <MethodInfo> > members = new Dictionary <string, LinkedList <MethodInfo> >();

            foreach (var info in type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public))
            {
                if (info.ReturnType.IsByRef)
                {
                    continue;
                }
                if (!members.ContainsKey(info.Name))
                {
                    members[info.Name] = new LinkedList <MethodInfo>();
                }

                members[info.Name].AddLast(info);
            }

            // add the members to the object
            foreach (var pair in members)
            {
                DefineOwnProperty(pair.Key, ReflectOverload(pair.Value));
            }

            // find and add all static properties and fields
            foreach (var info in type.GetProperties(BindingFlags.Static | BindingFlags.Public))
            {
                DefineOwnProperty(info.Name, Global.Marshaller.MarshalPropertyInfo(info, this));
            }

            foreach (var info in type.GetFields(BindingFlags.Static | BindingFlags.Public))
            {
                DefineOwnProperty(info.Name, Global.Marshaller.MarshalFieldInfo(info, this));
            }

            if (type.IsEnum)
            {
                string[] names  = Enum.GetNames(type);
                object[] values = new object[names.Length];
                Enum.GetValues(type).CopyTo(values, 0);

                for (int i = 0; i < names.Length; i++)
                {
                    DefineOwnProperty(names[i], Global.ObjectClass.New(values[i], PrototypeProperty));
                }
            }

            // find all nested types
            foreach (var info in type.GetNestedTypes(BindingFlags.Public))
            {
                DefineOwnProperty(info.Name, Global.Marshaller.MarshalClrValue(info), PropertyAttributes.DontEnum);
            }

            // find all instance properties and fields
            LinkedList <MethodInfo> getMethods = new LinkedList <MethodInfo>();
            LinkedList <MethodInfo> setMethods = new LinkedList <MethodInfo>();

            foreach (var info in type.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public))
            {
                ParameterInfo[] indexerParams = info.GetIndexParameters();
                if (indexerParams == null || indexerParams.Length == 0)
                {
                    m_properties.AddLast(global.Marshaller.MarshalPropertyInfo(info, this));
                }
                else if (info.Name == "Item" && indexerParams.Length == 1)
                {
                    if (info.CanRead)
                    {
                        getMethods.AddLast(info.GetGetMethod());
                    }
                    if (info.CanWrite)
                    {
                        setMethods.AddLast(info.GetSetMethod());
                    }
                }
            }

            if (getMethods.Count > 0 || setMethods.Count > 0)
            {
                MethodInfo[] getters = new MethodInfo[getMethods.Count];
                getMethods.CopyTo(getters, 0);
                MethodInfo[] setters = new MethodInfo[setMethods.Count];
                setMethods.CopyTo(setters, 0);

                m_indexer = new NativeIndexer(m_marshaller, getters, setters);
            }

            if (reflectedType.IsArray)
            {
                m_indexer = (INativeIndexer)typeof(NativeArrayIndexer <>)
                            .MakeGenericType(reflectedType.GetElementType())
                            .GetConstructor(new Type[] { typeof(Marshaller) })
                            .Invoke(new object[] { m_marshaller });
            }

            foreach (var info in type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public))
            {
                m_properties.AddLast(global.Marshaller.MarshalFieldInfo(info, this));
            }
        }