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