public void LoadTypeInfo(IntPtr t) { using (var type = new NetTypeInfo(t)) { var typeInfo = Type.GetType(type.FullTypeName); if (typeInfo == null) { throw new InvalidOperationException($"Invalid type {type.FullTypeName}"); } // Don't grab properties and methods for system-level types. if (Helpers.IsPrimitive(typeInfo)) { return; } if (typeInfo.IsArray) { type.IsArray = true; } else { if (typeof(IList).IsAssignableFrom(typeInfo)) { type.IsList = true; } else if (typeInfo.IsGenericType) { if (typeof(IList <>).IsAssignableFrom(typeInfo.GetGenericTypeDefinition())) { type.IsList = true; } } } if (typeof(IQmlComponentCompleted).IsAssignableFrom(typeInfo)) { type.HasComponentCompleted = true; } if (typeof(IQmlObjectDestroyed).IsAssignableFrom(typeInfo)) { type.HasObjectDestroyed = true; } foreach (var methodInfo in typeInfo.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) { if (methodInfo.IsGenericMethod) { continue; // No generics supported. } if (Helpers.IsPrimitive(methodInfo.DeclaringType)) { continue; } if (methodInfo.IsSpecialName) { continue; // Ignore the property get/set methods. } NetTypeInfo returnType = null; if (methodInfo.ReturnParameter != null && methodInfo.ReturnParameter.ParameterType != typeof(void)) { returnType = NetTypeManager.GetTypeInfo(methodInfo.ReturnParameter.ParameterType); } var method = new NetMethodInfo(type, methodInfo.Name, returnType, methodInfo.IsStatic); foreach (var parameter in methodInfo.GetParameters()) { method.AddParameter(parameter.Name, NetTypeManager.GetTypeInfo(parameter.ParameterType)); } type.AddMethod(method); } var signals = new Dictionary <string, NetSignalInfo>(); foreach (var signalAttribute in typeInfo.GetCustomAttributes(false).OfType <SignalAttribute>()) { if (string.IsNullOrEmpty(signalAttribute.Name)) { throw new InvalidOperationException($"Signal name was null for {typeInfo.Name}"); } if (!char.IsLower(signalAttribute.Name[0])) { throw new InvalidOperationException($"Signal {signalAttribute.Name} for {typeInfo.Name} must begin with a lower case letter."); } var signal = new NetSignalInfo(type, signalAttribute.Name); foreach (var parameter in signalAttribute.Parameters) { signal.AddParameter(parameter); } type.AddSignal(signal); signals.Add(signal.Name, signal); } foreach (var propertyInfo in typeInfo.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (Helpers.IsPrimitive(propertyInfo.DeclaringType)) { continue; } NetSignalInfo notifySignal = null; var notifySignalAttribute = propertyInfo.GetCustomAttribute <NotifySignalAttribute>(); if (notifySignalAttribute != null) { var name = notifySignalAttribute.Name; if (string.IsNullOrEmpty(name)) { name = $"{propertyInfo.Name}Changed"; name = char.ToLower(name[0]) + name.Substring(1); } if (signals.ContainsKey(name)) { notifySignal = signals[name]; // Make sure the signal we are referencing has no parameters. if (notifySignal.ParameterCount != 0) { // TODO: They can actually of parameters, but not implemented yet. throw new Exception("Notify signals must have no parameters."); } } else { if (!char.IsLower(name[0])) { throw new InvalidOperationException($"Signal {name} for {typeInfo.Name} must begin with a lower case letter."); } notifySignal = new NetSignalInfo(type, name); type.AddSignal(notifySignal); } } using (var property = new NetPropertyInfo( type, propertyInfo.Name, NetTypeManager.GetTypeInfo(propertyInfo.PropertyType), propertyInfo.CanRead, propertyInfo.CanWrite, notifySignal)) { foreach (var indexParameter in propertyInfo.GetIndexParameters()) { property.AddIndexParameter(indexParameter.Name, NetTypeManager.GetTypeInfo(indexParameter.ParameterType)); } type.AddProperty(property); } } // NOTE: This type is going to get a typeInfo object // with IsLoading=true and IsLoaded=false. It technically // is loaded, but it's misleading. InteropBehaviors.OnNetTypeInfoCreated(type, typeInfo); } }
public override void BuildTypeInfo(NetTypeInfo typeInfo) { var type = Type.GetType(typeInfo.GetFullTypeName()); typeInfo.SetClassName(type.Name); if (type == typeof(bool)) { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_Bool); } else if (type == typeof(char)) { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_Char); } else if (type == typeof(int)) { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_Int); } else if (type == typeof(uint)) { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_UInt); } else if (type == typeof(double)) { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_Double); } else if (type == typeof(string)) { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_String); } else if (type == typeof(DateTime)) { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_DateTime); } else { typeInfo.SetPrefVariantType(NetVariantTypeEnum.NetVariantTypeEnum_Object); } if (type.Namespace == "System") { return; // built in type! } foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance)) { if (method.DeclaringType == typeof(Object)) { continue; } NetTypeInfo returnType = null; if (method.ReturnParameter.ParameterType != typeof(void)) { returnType = NetTypeInfoManager.GetTypeInfo(method.ReturnParameter.ParameterType); } var methodInfo = NetTypeInfoManager.NewMethodInfo(typeInfo, method.Name, returnType); foreach (var parameter in method.GetParameters()) { methodInfo.AddParameter(parameter.Name, NetTypeInfoManager.GetTypeInfo(parameter.ParameterType)); } typeInfo.AddMethod(methodInfo); } foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { typeInfo.AddProperty(NetTypeInfoManager.NewPropertyInfo( typeInfo, property.Name, NetTypeInfoManager.GetTypeInfo(property.PropertyType), property.CanRead, property.CanWrite)); } }