protected override TreeViewItem BuildRoot() { BuildExposedTypeList(); itemMetadatas.Clear(); hiearchyItems.Clear(); TreeViewItem root = new TreeViewItem(0, -1); itemMetadatas.Add(root, new TypeItemMetadata()); int currentID = 1; exposedUdonExterns.UnionWith(UdonEditorManager.Instance.GetNodeDefinitions().Select(e => e.fullName)); exposedUdonExterns.RemoveWhere(e => e.StartsWith("Event_") || e.Contains(".__op_") || e.Contains("__SystemFunc") || e.Contains("__SystemAction")); // Build the namespace sections first foreach (System.Type type in exposedTypes) { string typeNamespace = type.Namespace; if (typeNamespace == null || typeNamespace == "") { if (type.GetElementType() != null && type.GetElementType().Namespace != null) { typeNamespace = type.GetElementType().Namespace; } } TreeViewItem namespaceItem = GetNamespaceParent(typeNamespace, root, ref currentID); } int currentTypeCount = 0; foreach (System.Type type in exposedTypes.OrderBy(e => e.Name)) { EditorUtility.DisplayProgressBar("Adding types...", $"Adding type {type}", currentTypeCount++ / (float)exposedTypes.Count); if (ShouldHideTypeTopLevel(type, true)) { continue; } string typeNamespace = type.Namespace; if (typeNamespace == null || typeNamespace == "") { if (type.GetElementType() != null && type.GetElementType().Namespace != null) { typeNamespace = type.GetElementType().Namespace; } } TreeViewItem namespaceParent = GetNamespaceParent(typeNamespace, root, ref currentID); string typeTypeName = ""; if (type.IsEnum) { typeTypeName = " <enum>"; } else if (type.IsValueType) { typeTypeName = " <struct>"; } else if (type.IsArray) { typeTypeName = " <array>"; } else { typeTypeName = " <class>"; } TreeViewItem typeParent = new TreeViewItem(currentID++, namespaceParent.depth + 1, type.Name + typeTypeName); namespaceParent.AddChild(typeParent); itemMetadatas.Add(typeParent, new TypeItemMetadata() { isType = true }); exposedUdonExterns.Remove("Variable_" + resolver.GetUdonTypeName(type)); exposedUdonExterns.Remove("Const_" + resolver.GetUdonTypeName(type)); exposedUdonExterns.Remove("Type_" + resolver.GetUdonTypeName(type)); exposedUdonExterns.Remove("Type_" + resolver.GetUdonTypeName(type.MakeByRefType())); //if (!type.IsEnum) //{ // // Variable definition // TreeViewItem variableDef = new TreeViewItem(currentID++, typeParent.depth + 1, "<variable> " + type.Name); // typeParent.AddChild(variableDef); // itemMetadatas.Add(variableDef, new TypeItemMetadata() { exposed = resolver.ValidateUdonTypeName(resolver.GetUdonTypeName(type), UdonReferenceType.Variable) }); //} // Type definition //TreeViewItem typeDef = new TreeViewItem(currentID++, typeParent.depth + 1, "<type> " + type.Name); //typeParent.AddChild(typeDef); //itemMetadatas.Add(typeDef, new TypeItemMetadata() { exposed = resolver.ValidateUdonTypeName(resolver.GetUdonTypeName(type), UdonReferenceType.Type) }); // Internal type TreeViewItem internalTypeDef = new TreeViewItem(currentID++, typeParent.depth + 1, "<Type> " + type.Name); typeParent.AddChild(internalTypeDef); itemMetadatas.Add(internalTypeDef, new TypeItemMetadata() { exposed = UdonEditorManager.Instance.GetTypeFromTypeString(resolver.GetUdonTypeName(type)) != null }); // Const definition //if (!type.IsArray && !type.IsEnum) //{ // TreeViewItem constDef = new TreeViewItem(currentID++, typeParent.depth + 1, "<const> " + type.Name); // typeParent.AddChild(constDef); // itemMetadatas.Add(constDef, new TypeItemMetadata() { exposed = resolver.ValidateUdonTypeName(resolver.GetUdonTypeName(type), UdonReferenceType.Const) }); //} BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; if (!showBaseTypeMembers) { bindingFlags |= BindingFlags.DeclaredOnly; } foreach (ConstructorInfo constructor in type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) { AddChildNode(typeParent, constructor, ref currentID); } foreach (FieldInfo field in type.GetFields(bindingFlags)) { AddChildNode(typeParent, field, ref currentID); } foreach (PropertyInfo property in type.GetProperties(bindingFlags)) { AddChildNode(typeParent, property, ref currentID); } if (!type.IsEnum) { foreach (MethodInfo method in type.GetMethods(bindingFlags).Where(e => (!type.IsArray || e.Name != "Address"))) { if (method.IsSpecialName && !method.Name.StartsWith("op_")) { continue; } AddChildNode(typeParent, method, ref currentID); } } } EditorUtility.ClearProgressBar(); BuildDrawInfo(root); //foreach (string exposedExtern in exposedUdonExterns) //{ // Debug.Log(exposedExtern); //} return(root); }
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(); }