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)); }
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) ); }
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); }
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) ); }
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; }
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)); }
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)); } }
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)); } }