Fixed indentation on docs generator project

This commit is contained in:
EvilFactory
2023-02-04 14:20:55 -03:00
parent 81970b3fd4
commit 14c45e4900
2 changed files with 343 additions and 283 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ end_of_line = lf
[*.cs] [*.cs]
indent_style = space indent_style = space
indent_size = 2 indent_size = 4
csharp_prefer_braces = when_multiline:warning csharp_prefer_braces = when_multiline:warning
csharp_indent_case_contents_when_block = false csharp_indent_case_contents_when_block = false
# One True Brace style # One True Brace style
@@ -6,19 +6,23 @@ using System.Text.RegularExpressions;
using Barotrauma; using Barotrauma;
using Barotrauma.Networking; using Barotrauma.Networking;
string NormalizeGenericTypeName(string s) { string NormalizeGenericTypeName(string s)
{
var idx = s.LastIndexOf('`'); var idx = s.LastIndexOf('`');
if (idx != -1) { if (idx != -1)
{
return s[..idx]; return s[..idx];
} }
return s; return s;
} }
string TypeToString(Type type, bool useLuaTypes = true) { string TypeToString(Type type, bool useLuaTypes = true)
{
// Return "T" for unresolved type params // Return "T" for unresolved type params
if (type.IsGenericParameter) { if (type.IsGenericParameter)
{
return type.Name; return type.Name;
} }
@@ -26,15 +30,18 @@ string TypeToString(Type type, bool useLuaTypes = true) {
? type.GetGenericTypeDefinition() ? type.GetGenericTypeDefinition()
: null; : null;
if (type == typeof(bool)) { if (type == typeof(bool))
{
return "bool"; return "bool";
} }
if (type == typeof(string)) { if (type == typeof(string))
{
return "string"; return "string";
} }
if (useLuaTypes) { if (useLuaTypes)
{
if (type == typeof(sbyte) if (type == typeof(sbyte)
|| type == typeof(byte) || type == typeof(byte)
|| type == typeof(short) || type == typeof(short)
@@ -44,17 +51,20 @@ string TypeToString(Type type, bool useLuaTypes = true) {
|| type == typeof(long) || type == typeof(long)
|| type == typeof(ulong) || type == typeof(ulong)
|| type == typeof(float) || type == typeof(float)
|| type == typeof(double)) { || type == typeof(double))
{
return "number"; return "number";
} }
if (genericType == typeof(List<>) if (genericType == typeof(List<>)
|| genericType == typeof(Dictionary<,>)) { || genericType == typeof(Dictionary<,>))
{
return "table"; return "table";
} }
if (genericType == typeof(Action<,>) if (genericType == typeof(Action<,>)
|| genericType == typeof(Func<,>)) { || genericType == typeof(Func<,>))
{
return "function"; return "function";
} }
} }
@@ -66,23 +76,29 @@ string TypeToString(Type type, bool useLuaTypes = true) {
"System.Collections.Generic", "System.Collections.Generic",
}; };
string Namespaced(string typeName) { string Namespaced(string typeName)
if (type.Namespace == null) { {
if (type.Namespace == null)
{
return typeName; return typeName;
} }
// Full namespace match // Full namespace match
if (nsToRemove.Contains(type.Namespace)) { if (nsToRemove.Contains(type.Namespace))
{
return typeName; return typeName;
} }
// Partial namespace match // Partial namespace match
foreach (var ns in nsToRemove) { foreach (var ns in nsToRemove)
if (ns == type.Namespace) { {
if (ns == type.Namespace)
{
return typeName; return typeName;
} }
if (type.Namespace.StartsWith(ns + ".")) { if (type.Namespace.StartsWith(ns + "."))
{
var shortNs = type.Namespace.Remove(0, ns.Length + 1); var shortNs = type.Namespace.Remove(0, ns.Length + 1);
return $"{shortNs}.{typeName}"; return $"{shortNs}.{typeName}";
} }
@@ -91,19 +107,25 @@ string TypeToString(Type type, bool useLuaTypes = true) {
return $"{type.Namespace}.{typeName}"; return $"{type.Namespace}.{typeName}";
} }
string Impl(string? ns) { string Impl(string? ns)
if (type.IsGenericType) { {
if (type.IsGenericType)
{
var genericTypeDef = type.GetGenericTypeDefinition(); var genericTypeDef = type.GetGenericTypeDefinition();
var genericTypeName = NormalizeGenericTypeName(genericTypeDef.Name); var genericTypeName = NormalizeGenericTypeName(genericTypeDef.Name);
var genericArgs = type.GetGenericArguments(); var genericArgs = type.GetGenericArguments();
// Use the `T?` notation instead of Nullable<T> // Use the `T?` notation instead of Nullable<T>
if (genericTypeDef == typeof(Nullable<>)) { if (genericTypeDef == typeof(Nullable<>))
{
// ldoc supports the "?string" notation, which expands to "?|nil|string" // ldoc supports the "?string" notation, which expands to "?|nil|string"
if (useLuaTypes) { if (useLuaTypes)
{
return Namespaced("?" + TypeToString(genericArgs[0], useLuaTypes: false)); return Namespaced("?" + TypeToString(genericArgs[0], useLuaTypes: false));
} else { }
else
{
return Namespaced(TypeToString(genericArgs[0], useLuaTypes: false) + "?"); return Namespaced(TypeToString(genericArgs[0], useLuaTypes: false) + "?");
} }
} }
@@ -111,7 +133,8 @@ string TypeToString(Type type, bool useLuaTypes = true) {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append(genericTypeName); sb.Append(genericTypeName);
sb.Append("<"); sb.Append("<");
foreach (var genericArgType in genericArgs) { foreach (var genericArgType in genericArgs)
{
sb.Append(TypeToString(genericArgType, useLuaTypes: false)); sb.Append(TypeToString(genericArgType, useLuaTypes: false));
sb.Append(","); sb.Append(",");
} }
@@ -128,14 +151,19 @@ string TypeToString(Type type, bool useLuaTypes = true) {
return Impl(type.Namespace); return Impl(type.Namespace);
} }
static (bool Success, string Output, string Error) TryRunGitCommand(string args) { static (bool Success, string Output, string Error) TryRunGitCommand(string args)
static string? GetGitBinary() { {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { static string? GetGitBinary()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process) return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process)
?.Split(';') ?.Split(';')
.Select(x => Path.Join(x, "git.exe")) .Select(x => Path.Join(x, "git.exe"))
.FirstOrDefault(File.Exists); .FirstOrDefault(File.Exists);
} else { }
else
{
return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process) return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process)
?.Split(':') ?.Split(':')
.Select(x => Path.Join(x, "git")) .Select(x => Path.Join(x, "git"))
@@ -144,11 +172,13 @@ static (bool Success, string Output, string Error) TryRunGitCommand(string args)
} }
var gitBinary = GetGitBinary(); var gitBinary = GetGitBinary();
if (gitBinary == null) { if (gitBinary == null)
{
throw new InvalidOperationException("Failed to find git binary in PATH"); throw new InvalidOperationException("Failed to find git binary in PATH");
} }
using var process = Process.Start(new ProcessStartInfo(gitBinary, args) { using var process = Process.Start(new ProcessStartInfo(gitBinary, args)
{
WindowStyle = ProcessWindowStyle.Hidden, WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true, CreateNoWindow = true,
UseShellExecute = false, UseShellExecute = false,
@@ -170,25 +200,31 @@ static (bool Success, string Output, string Error) TryRunGitCommand(string args)
return (process.ExitCode == 0, stdOut.Result.TrimEnd('\r', '\n'), stdErr.Result); return (process.ExitCode == 0, stdOut.Result.TrimEnd('\r', '\n'), stdErr.Result);
} }
var gitDir = (new Func<String>(() => { var gitDir = (new Func<String>(() =>
{
var (success, gitDir, error) = TryRunGitCommand("rev-parse --show-toplevel"); var (success, gitDir, error) = TryRunGitCommand("rev-parse --show-toplevel");
if (!success) { if (!success)
{
throw new InvalidDataException($"Failed to determine the root of the git repo: {error}"); throw new InvalidDataException($"Failed to determine the root of the git repo: {error}");
} }
return gitDir; return gitDir;
}))(); }))();
void GenerateDocsImpl(Type type, string baseFile, string outFile, string? categoryName = null) { void GenerateDocsImpl(Type type, string baseFile, string outFile, string? categoryName = null)
{
categoryName ??= type.Name; categoryName ??= type.Name;
var sb = new StringBuilder(); var sb = new StringBuilder();
Console.WriteLine($"Generating docs for {type}"); Console.WriteLine($"Generating docs for {type}");
string baseLuaText; string baseLuaText;
try { try
{
baseLuaText = File.ReadAllText(baseFile); baseLuaText = File.ReadAllText(baseFile);
} catch (FileNotFoundException) { }
catch (FileNotFoundException)
{
baseLuaText = @$"-- luacheck: ignore 111 baseLuaText = @$"-- luacheck: ignore 111
--[[-- --[[--
@@ -205,7 +241,8 @@ local {type.Name} = {{}}".ReplaceLineEndings("\n");
var removed = new HashSet<string>(); var removed = new HashSet<string>();
var matches = removeTagPattern.Matches(baseLuaText); var matches = removeTagPattern.Matches(baseLuaText);
foreach (var match in matches.Cast<Match>()) { foreach (var match in matches.Cast<Match>())
{
removed.Add(match.Value); removed.Add(match.Value);
} }
@@ -214,41 +251,53 @@ local {type.Name} = {{}}".ReplaceLineEndings("\n");
sb.AppendLine(); sb.AppendLine();
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); var members = type.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
foreach (var member in members) { foreach (var member in members)
static string EscapeName(string n) { {
return n switch { static string EscapeName(string n)
{
return n switch
{
"end" => "endparam", "end" => "endparam",
_ => n _ => n
}; };
} }
switch (member.MemberType) { switch (member.MemberType)
case MemberTypes.Method: { {
case MemberTypes.Method:
{
var method = (MethodInfo)member; var method = (MethodInfo)member;
// Exclude property getters/setters // Exclude property getters/setters
if (method.IsSpecialName) { if (method.IsSpecialName)
{
continue; continue;
} }
var paramNames = new StringBuilder(); var paramNames = new StringBuilder();
foreach (var parameter in method.GetParameters()) { foreach (var parameter in method.GetParameters())
{
paramNames.Append(EscapeName(parameter.Name!)); paramNames.Append(EscapeName(parameter.Name!));
paramNames.Append(", "); paramNames.Append(", ");
} }
if (paramNames.Length > 0) { if (paramNames.Length > 0)
{
// Remove the last separator // Remove the last separator
paramNames.Length -= 2; paramNames.Length -= 2;
} }
string functionDecoration; string functionDecoration;
if (method.IsStatic) { if (method.IsStatic)
{
functionDecoration = $"function {type.Name}.{method.Name}({paramNames}) end"; functionDecoration = $"function {type.Name}.{method.Name}({paramNames}) end";
} else { }
else
{
functionDecoration = $"function {method.Name}({paramNames}) end"; functionDecoration = $"function {method.Name}({paramNames}) end";
} }
if (removed.Contains(functionDecoration)) { if (removed.Contains(functionDecoration))
{
continue; continue;
} }
@@ -257,11 +306,13 @@ local {type.Name} = {{}}".ReplaceLineEndings("\n");
sb.AppendLine($"--- {method.Name}"); sb.AppendLine($"--- {method.Name}");
sb.AppendLine("-- @realm shared"); sb.AppendLine("-- @realm shared");
foreach (var parameter in method.GetParameters()) { foreach (var parameter in method.GetParameters())
{
sb.AppendLine($"-- @tparam {TypeToString(parameter.ParameterType)} {EscapeName(parameter.Name!)}"); sb.AppendLine($"-- @tparam {TypeToString(parameter.ParameterType)} {EscapeName(parameter.Name!)}");
} }
if (method.ReturnType != typeof(void)) { if (method.ReturnType != typeof(void))
{
sb.AppendLine($"-- @treturn {TypeToString(method.ReturnType)}"); sb.AppendLine($"-- @treturn {TypeToString(method.ReturnType)}");
} }
@@ -270,17 +321,20 @@ local {type.Name} = {{}}".ReplaceLineEndings("\n");
break; break;
} }
case MemberTypes.Field: { case MemberTypes.Field:
{
var field = (FieldInfo)member; var field = (FieldInfo)member;
var name = EscapeName(field.Name); var name = EscapeName(field.Name);
var returnName = TypeToString(field.FieldType); var returnName = TypeToString(field.FieldType);
if (field.IsStatic) { if (field.IsStatic)
{
name = type.Name + "." + field.Name; name = type.Name + "." + field.Name;
} }
if (removed.Contains(name)) { if (removed.Contains(name))
{
continue; continue;
} }
@@ -297,17 +351,20 @@ local {type.Name} = {{}}".ReplaceLineEndings("\n");
break; break;
} }
case MemberTypes.Property: { case MemberTypes.Property:
{
var property = (PropertyInfo)member; var property = (PropertyInfo)member;
var name = EscapeName(property.Name); var name = EscapeName(property.Name);
var returnName = TypeToString(property.PropertyType); var returnName = TypeToString(property.PropertyType);
if (property.GetGetMethod()?.IsStatic == true || property.GetSetMethod()?.IsStatic == true) { if (property.GetGetMethod()?.IsStatic == true || property.GetSetMethod()?.IsStatic == true)
{
name = type.Name + "." + property.Name; name = type.Name + "." + property.Name;
} }
if (removed.Contains(name)) { if (removed.Contains(name))
{
continue; continue;
} }
@@ -333,13 +390,16 @@ local {type.Name} = {{}}".ReplaceLineEndings("\n");
var basePath = $"{gitDir}/luacs-docs/lua"; var basePath = $"{gitDir}/luacs-docs/lua";
var generatedDir = $"{basePath}/lua/generated"; var generatedDir = $"{basePath}/lua/generated";
var baseLuaDir = $"{basePath}/baseluadocs"; var baseLuaDir = $"{basePath}/baseluadocs";
void GenerateDocs(Type type, string file, string? categoryName = null) { void GenerateDocs(Type type, string file, string? categoryName = null)
{
GenerateDocsImpl(type, $"{baseLuaDir}/{file}", $"{generatedDir}/{file}", categoryName); GenerateDocsImpl(type, $"{baseLuaDir}/{file}", $"{generatedDir}/{file}", categoryName);
} }
try { try
{
Directory.Delete(generatedDir, true); Directory.Delete(generatedDir, true);
} catch (DirectoryNotFoundException) { } }
catch (DirectoryNotFoundException) { }
Directory.CreateDirectory(generatedDir); Directory.CreateDirectory(generatedDir);
Directory.CreateDirectory(baseLuaDir); Directory.CreateDirectory(baseLuaDir);