Created
April 12, 2024 07:53
-
-
Save anatawa12/6fe2a6802922a50193cc2ebadf02cfb1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if UNITY_EDITOR && (!ANATAWA12_GISTS_VPM_PACKAGE || GIST_a4bb4e2e5d75b4fa5ba42e236aae564d) | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Reflection; | |
using System.Text; | |
using HarmonyLib; | |
using JetBrains.Annotations; | |
using UnityEditor; | |
using UnityEditorInternal; | |
using UnityEngine; | |
namespace anatawa12.gists | |
{ | |
internal static class VRCSDKApiChecker | |
{ | |
[MenuItem("Tools/anatawa12 gists/Export VRCSDK API List")] | |
private static void CheckVRCSDKAPI() | |
{ | |
var assemblies = new List<string>(); | |
foreach (var sdkPath in new[] | |
{ | |
"Packages/com.vrchat.base", | |
"Packages/com.vrchat.worlds", | |
"Packages/com.vrchat.avatars", | |
}) | |
{ | |
try | |
{ | |
foreach (var file in Directory.GetFiles(sdkPath, "*.asmdef", SearchOption.AllDirectories)) | |
{ | |
var asmdef = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(file); | |
assemblies.Add(asmdef.name); | |
} | |
foreach (var file in Directory.GetFiles(sdkPath, "*.dll", SearchOption.AllDirectories)) | |
{ | |
var pluginImporter = (PluginImporter)AssetImporter.GetAtPath(file); | |
if (!pluginImporter.isNativePlugin && pluginImporter.GetCompatibleWithEditor()) | |
{ | |
assemblies.Add(Path.GetFileNameWithoutExtension(file)); | |
} | |
} | |
} | |
catch (DirectoryNotFoundException) | |
{ | |
// ignored | |
} | |
} | |
Debug.Log("VRCSDK Assembly" + string.Join(", ", assemblies)); | |
Directory.CreateDirectory("VRCSDKApiChecker"); | |
foreach (var assemblyName in assemblies) | |
{ | |
var assembly = Assembly.Load(assemblyName); | |
Directory.CreateDirectory($"VRCSDKApiChecker/{assemblyName}"); | |
foreach (var type in assembly.GetTypes()) | |
{ | |
var apiText = CreateTypeApis(type); | |
if (apiText == null) continue; // it's not public | |
File.WriteAllText($"VRCSDKApiChecker/{assemblyName}/{type.FullName}.txt", apiText); | |
} | |
} | |
} | |
[CanBeNull] | |
private static string CreateTypeApis(Type type) | |
{ | |
if (!type.IsPubliclyVisible()) return null; | |
var apiText = new StringBuilder(); | |
apiText.AppendLine($"Type: {type.FullName}"); | |
apiText.AppendLine($"Extends: {type.BaseType}"); | |
foreach (var @interface in type.GetInterfaces()) | |
apiText.AppendLine($"Implements: {@interface}"); | |
apiText.AppendLine($"Access: {type.Attributes}"); | |
const BindingFlags allMembers = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; | |
foreach (var method in type.GetMethods(allMembers)) | |
if (method.IsPubliclyVisible()) | |
apiText.AppendLine($"Method: {method.Attributes} {method.ReturnType} {method.Name}({method.GetParameters().Join()})"); | |
foreach (var field in type.GetFields(allMembers)) | |
if (field.IsPubliclyVisible()) | |
apiText.AppendLine($"Field: {field.Attributes} {field.FieldType} {field.Name}"); | |
foreach (var property in type.GetProperties(allMembers)) | |
{ | |
if (property.GetMethod != null && property.GetMethod.IsPubliclyVisible()) | |
apiText.AppendLine($"Property: {property.PropertyType} {property.Name} {{ get; }}"); | |
if (property.SetMethod != null && property.SetMethod.IsPubliclyVisible()) | |
apiText.AppendLine($"Property: {property.PropertyType} {property.Name} {{ set; }}"); | |
} | |
return apiText.ToString(); | |
} | |
private static bool IsPubliclyVisible(this MethodInfo method) => method.IsPublic || method.IsFamilyOrAssembly || method.IsFamily; | |
private static bool IsPubliclyVisible(this FieldInfo field) => field.IsPublic || field.IsFamilyOrAssembly || field.IsFamily; | |
private static bool IsPubliclyVisible(this Type type) | |
{ | |
switch (type.Attributes & TypeAttributes.VisibilityMask) | |
{ | |
case TypeAttributes.Public: | |
return true; | |
case TypeAttributes.NestedPublic: | |
case TypeAttributes.NestedFamORAssem: | |
case TypeAttributes.NestedFamily: | |
return type.DeclaringType.IsPubliclyVisible(); | |
default: | |
return false; | |
} | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment