private void BuildExposedTypeList() { if (exposedTypes != null) { return; } try { ResolverContext resolver = new ResolverContext(); Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); HashSet <System.Type> exposedTypeSet = new HashSet <System.Type>(); for (int i = 0; i < assemblies.Length; ++i) { EditorUtility.DisplayProgressBar("Processing methods and types...", $"Assembly {i + 1}/{assemblies.Length} {assemblies[i].GetName().Name}", i / (float)assemblies.Length); Assembly assembly = assemblies[i]; if (assembly.FullName.Contains("UdonSharp") || assembly.FullName.Contains("CodeAnalysis")) { continue; } System.Type[] assemblyTypes = assembly.GetTypes(); List <System.Type> types = new List <System.Type>(); foreach (System.Type assemblyType in assemblyTypes) { types.Add(assemblyType); types.AddRange(GetNestedTypes(assemblyType)); } types = types.Distinct().ToList(); foreach (System.Type type in types) { if (type.IsByRef) { continue; } string typeName = resolver.GetUdonTypeName(type); if (resolver.ValidateUdonTypeName(typeName, UdonReferenceType.Type) || resolver.ValidateUdonTypeName(typeName, UdonReferenceType.Variable) || UdonEditorManager.Instance.GetTypeFromTypeString(typeName) != null) { exposedTypeSet.Add(type); if (!type.IsGenericType && !type.IsGenericTypeDefinition) { exposedTypeSet.Add(type.MakeArrayType()); } } MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); foreach (MethodInfo method in methods) { if (resolver.IsValidUdonMethod(resolver.GetUdonMethodName(method, false))) { exposedTypeSet.Add(method.DeclaringType); // We also want to highlight types that can be returned or taken as parameters if (method.ReturnType != null && method.ReturnType != typeof(void) && method.ReturnType.Name != "T" && method.ReturnType.Name != "T[]") { exposedTypeSet.Add(method.ReturnType); if (!method.ReturnType.IsArray && !method.ReturnType.IsGenericType && !method.ReturnType.IsGenericTypeDefinition) { exposedTypeSet.Add(method.ReturnType.MakeArrayType()); } } foreach (ParameterInfo parameterInfo in method.GetParameters()) { if (!parameterInfo.ParameterType.IsByRef) { exposedTypeSet.Add(parameterInfo.ParameterType); if (!parameterInfo.ParameterType.IsArray) { exposedTypeSet.Add(parameterInfo.ParameterType.MakeArrayType()); } } } } } foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) { MethodInfo propertyGetter = property.GetGetMethod(); if (propertyGetter == null) { continue; } if (resolver.IsValidUdonMethod(resolver.GetUdonMethodName(propertyGetter, false))) { System.Type returnType = propertyGetter.ReturnType; exposedTypeSet.Add(property.DeclaringType); if (returnType != null && returnType != typeof(void) && returnType.Name != "T" && returnType.Name != "T[]") { exposedTypeSet.Add(returnType); if (!returnType.IsArray && !returnType.IsGenericType && !returnType.IsGenericTypeDefinition) { exposedTypeSet.Add(returnType.MakeArrayType()); } } } } foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) { if (resolver.IsValidUdonMethod(resolver.GetUdonFieldAccessorName(field, FieldAccessorType.Get, false))) { System.Type returnType = field.FieldType; exposedTypeSet.Add(field.DeclaringType); if (returnType != null && returnType != typeof(void) && returnType.Name != "T" && returnType.Name != "T[]") { exposedTypeSet.Add(returnType); if (!returnType.IsArray && !returnType.IsGenericType && !returnType.IsGenericTypeDefinition) { exposedTypeSet.Add(returnType.MakeArrayType()); } } } } } } exposedTypes = exposedTypeSet.ToList(); } finally { EditorUtility.ClearProgressBar(); } EditorUtility.ClearProgressBar(); }
private void AddChildNode(TreeViewItem parentItem, MemberInfo memberInfo, ref int currentID) { var obsoleteAttribute = memberInfo.GetCustomAttribute <System.ObsoleteAttribute>(); if (obsoleteAttribute != null) { return; } if (memberInfo.MemberType == MemberTypes.Property && !((PropertyInfo)memberInfo).GetGetMethod().IsPublic) { return; } if (memberInfo.DeclaringType.IsEnum) { return; } if (ShouldHideMemberTopLevel(memberInfo)) { return; } string staticStr = ""; { if ((memberInfo is FieldInfo fieldInfo && fieldInfo.IsStatic) || (memberInfo is PropertyInfo propertyInfo && (propertyInfo.GetGetMethod()?.IsStatic ?? false)) || (memberInfo is MethodInfo methodInfo && methodInfo.IsStatic)) { staticStr = "<Static>"; } } TreeViewItem memberItem = new TreeViewItem(currentID++, parentItem.depth + 1, $"<{memberInfo.MemberType}>{staticStr} {memberInfo.ToString()}"); parentItem.AddChild(memberItem); TypeItemMetadata itemMetadata = new TypeItemMetadata(); itemMetadata.member = memberInfo; switch (memberInfo.MemberType) { case MemberTypes.Constructor: case MemberTypes.Method: itemMetadata.exposed = resolver.IsValidUdonMethod(resolver.GetUdonMethodName((MethodBase)memberInfo, false)); break; case MemberTypes.Field: string getAccessor = resolver.GetUdonFieldAccessorName((FieldInfo)memberInfo, FieldAccessorType.Get, false); string setAccessor = resolver.GetUdonFieldAccessorName((FieldInfo)memberInfo, FieldAccessorType.Set, false); exposedUdonExterns.Remove(getAccessor); exposedUdonExterns.Remove(setAccessor); itemMetadata.exposed = resolver.IsValidUdonMethod(getAccessor); break; case MemberTypes.Property: string getProperty = resolver.GetUdonMethodName(((PropertyInfo)memberInfo).GetGetMethod(), false); exposedUdonExterns.Remove(getProperty); if (((PropertyInfo)memberInfo).GetSetMethod() != null) { string setProperty = resolver.GetUdonMethodName(((PropertyInfo)memberInfo).GetSetMethod(), false); exposedUdonExterns.Remove(setProperty); } itemMetadata.exposed = resolver.IsValidUdonMethod(getProperty); break; } itemMetadatas.Add(memberItem, itemMetadata); exposedUdonExterns.Remove(GetMemberUdonName(memberItem)); }