Improved docs: Members now have their realm set automatically and server-only members are now also included
This commit is contained in:
@@ -10,33 +10,8 @@ Barotrauma source code: [Character.cs](https://github.com/evilfactory/LuaCsForBa
|
|||||||
|
|
||||||
local Character = {}
|
local Character = {}
|
||||||
|
|
||||||
-- @remove function Character.Create(characterInfo, position, seed, id, isRemotePlayer, hasAi, ragdoll) end
|
|
||||||
-- @remove function TeleportTo(worldPos) end
|
|
||||||
-- @remove Character.CharacterList
|
-- @remove Character.CharacterList
|
||||||
|
|
||||||
--- Creates a Character using CharacterInfo.
|
|
||||||
-- @realm server
|
|
||||||
-- @tparam CharacterInfo characterInfo
|
|
||||||
-- @tparam Vector2 position
|
|
||||||
-- @tparam string seed
|
|
||||||
-- @tparam number id
|
|
||||||
-- @tparam bool isRemotePlayer
|
|
||||||
-- @tparam bool hasAi
|
|
||||||
-- @tparam RagdollParams ragdoll
|
|
||||||
-- @treturn Character
|
|
||||||
-- @usage
|
|
||||||
-- local vsauce = CharacterInfo("human", "custom name")
|
|
||||||
-- local character = Character.Create(vsauce, Vector2(0, 0), "some random characters")
|
|
||||||
-- print(character)
|
|
||||||
function Character.Create(characterInfo, position, seed, id, isRemotePlayer, hasAi, ragdoll) end
|
|
||||||
|
|
||||||
|
|
||||||
--- Teleports a character to a position.
|
|
||||||
-- @realm server
|
|
||||||
-- @tparam Vector2 worldPos
|
|
||||||
-- @usage
|
|
||||||
-- Character.CharacterList[1].TeleportTo(Vector2(0, 0)) -- teleports first created characters to 0, 0
|
|
||||||
function TeleportTo(worldPos) end
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Character.CharacterList, Table containing all characters.
|
-- Character.CharacterList, Table containing all characters.
|
||||||
|
|||||||
@@ -0,0 +1,597 @@
|
|||||||
|
using FarseerPhysics.Collision.Shapes;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.Metrics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LuaDocsGenerator
|
||||||
|
{
|
||||||
|
public class DocsGenerator
|
||||||
|
{
|
||||||
|
private static HashSet<string> removed = new HashSet<string>();
|
||||||
|
|
||||||
|
public static string NormalizeGenericTypeName(string s)
|
||||||
|
{
|
||||||
|
var idx = s.LastIndexOf('`');
|
||||||
|
|
||||||
|
if (idx != -1)
|
||||||
|
{
|
||||||
|
return s[..idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string TypeToString(Type type, bool useLuaTypes = true)
|
||||||
|
{
|
||||||
|
// Return "T" for unresolved type params
|
||||||
|
if (type.IsGenericParameter)
|
||||||
|
{
|
||||||
|
return type.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var genericType = type.IsGenericType
|
||||||
|
? type.GetGenericTypeDefinition()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (type == typeof(bool))
|
||||||
|
{
|
||||||
|
return "bool";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == typeof(string))
|
||||||
|
{
|
||||||
|
return "string";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useLuaTypes)
|
||||||
|
{
|
||||||
|
if (type == typeof(sbyte)
|
||||||
|
|| type == typeof(byte)
|
||||||
|
|| type == typeof(short)
|
||||||
|
|| type == typeof(ushort)
|
||||||
|
|| type == typeof(int)
|
||||||
|
|| type == typeof(uint)
|
||||||
|
|| type == typeof(long)
|
||||||
|
|| type == typeof(ulong)
|
||||||
|
|| type == typeof(float)
|
||||||
|
|| type == typeof(double))
|
||||||
|
{
|
||||||
|
return "number";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genericType == typeof(List<>)
|
||||||
|
|| genericType == typeof(Dictionary<,>))
|
||||||
|
{
|
||||||
|
return "table";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genericType == typeof(Action<,>)
|
||||||
|
|| genericType == typeof(Func<,>))
|
||||||
|
{
|
||||||
|
return "function";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var nsToRemove = new[] {
|
||||||
|
"Barotrauma",
|
||||||
|
"System",
|
||||||
|
"System.Collections",
|
||||||
|
"System.Collections.Generic",
|
||||||
|
};
|
||||||
|
|
||||||
|
string Namespaced(string typeName)
|
||||||
|
{
|
||||||
|
if (type.Namespace == null)
|
||||||
|
{
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full namespace match
|
||||||
|
if (nsToRemove.Contains(type.Namespace))
|
||||||
|
{
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Partial namespace match
|
||||||
|
foreach (var ns in nsToRemove)
|
||||||
|
{
|
||||||
|
if (ns == type.Namespace)
|
||||||
|
{
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.Namespace.StartsWith(ns + "."))
|
||||||
|
{
|
||||||
|
var shortNs = type.Namespace.Remove(0, ns.Length + 1);
|
||||||
|
return $"{shortNs}.{typeName}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"{type.Namespace}.{typeName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
string Impl(string? ns)
|
||||||
|
{
|
||||||
|
if (type.IsGenericType)
|
||||||
|
{
|
||||||
|
var genericTypeDef = type.GetGenericTypeDefinition();
|
||||||
|
var genericTypeName = NormalizeGenericTypeName(genericTypeDef.Name);
|
||||||
|
|
||||||
|
var genericArgs = type.GetGenericArguments();
|
||||||
|
|
||||||
|
// Use the `T?` notation instead of Nullable<T>
|
||||||
|
if (genericTypeDef == typeof(Nullable<>))
|
||||||
|
{
|
||||||
|
// ldoc supports the "?string" notation, which expands to "?|nil|string"
|
||||||
|
if (useLuaTypes)
|
||||||
|
{
|
||||||
|
return Namespaced("?" + TypeToString(genericArgs[0], useLuaTypes: false));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Namespaced(TypeToString(genericArgs[0], useLuaTypes: false) + "?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append(genericTypeName);
|
||||||
|
sb.Append("<");
|
||||||
|
foreach (var genericArgType in genericArgs)
|
||||||
|
{
|
||||||
|
sb.Append(TypeToString(genericArgType, useLuaTypes: false));
|
||||||
|
sb.Append(",");
|
||||||
|
}
|
||||||
|
// Remove the last separator
|
||||||
|
sb.Length--;
|
||||||
|
sb.Append(">");
|
||||||
|
|
||||||
|
return Namespaced(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Namespaced(type.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Impl(type.Namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (bool Success, string Output, string Error) TryRunGitCommand(string args)
|
||||||
|
{
|
||||||
|
static string? GetGitBinary()
|
||||||
|
{
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process)
|
||||||
|
?.Split(';')
|
||||||
|
.Select(x => Path.Join(x, "git.exe"))
|
||||||
|
.FirstOrDefault(File.Exists);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process)
|
||||||
|
?.Split(':')
|
||||||
|
.Select(x => Path.Join(x, "git"))
|
||||||
|
.FirstOrDefault(File.Exists);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var gitBinary = GetGitBinary();
|
||||||
|
if (gitBinary == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Failed to find git binary in PATH");
|
||||||
|
}
|
||||||
|
|
||||||
|
using var process = Process.Start(new ProcessStartInfo(gitBinary, args)
|
||||||
|
{
|
||||||
|
WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardInput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process == null)
|
||||||
|
throw new InvalidOperationException($"Failed to run git command: {args}");
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
|
||||||
|
var stdOut = process.StandardOutput.ReadToEndAsync();
|
||||||
|
var stdErr = process.StandardError.ReadToEndAsync();
|
||||||
|
Task.WhenAll(stdOut, stdErr).GetAwaiter().GetResult();
|
||||||
|
process.WaitForExit();
|
||||||
|
|
||||||
|
return (process.ExitCode == 0, stdOut.Result.TrimEnd('\r', '\n'), stdErr.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string EscapeName(string n)
|
||||||
|
{
|
||||||
|
return n switch
|
||||||
|
{
|
||||||
|
"end" => "endparam",
|
||||||
|
_ => n
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? ConvertAnnotation(Type type, MemberInfo member, string realm)
|
||||||
|
{
|
||||||
|
switch (member.MemberType)
|
||||||
|
{
|
||||||
|
case MemberTypes.Method:
|
||||||
|
return ConvertAnnotation(type, (MethodInfo)member, realm);
|
||||||
|
case MemberTypes.Field:
|
||||||
|
return ConvertAnnotation(type, (FieldInfo)member, realm);
|
||||||
|
case MemberTypes.Property:
|
||||||
|
return ConvertAnnotation(type, (PropertyInfo)member, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? ConvertAnnotation(Type type, MethodInfo method, string realm)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
// Exclude property getters/setters
|
||||||
|
if (method.IsSpecialName)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var paramNames = new StringBuilder();
|
||||||
|
foreach (var parameter in method.GetParameters())
|
||||||
|
{
|
||||||
|
paramNames.Append(EscapeName(parameter.Name!));
|
||||||
|
paramNames.Append(", ");
|
||||||
|
}
|
||||||
|
if (paramNames.Length > 0)
|
||||||
|
{
|
||||||
|
// Remove the last separator
|
||||||
|
paramNames.Length -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
string functionDecoration;
|
||||||
|
if (method.IsStatic)
|
||||||
|
{
|
||||||
|
functionDecoration = $"function {type.Name}.{method.Name}({paramNames}) end";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
functionDecoration = $"function {method.Name}({paramNames}) end";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removed.Contains("-- @remove " + functionDecoration))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"removed {functionDecoration}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($" - METHOD: {method}");
|
||||||
|
|
||||||
|
sb.AppendLine($"--- {method.Name}");
|
||||||
|
sb.AppendLine($"-- @realm {realm}");
|
||||||
|
|
||||||
|
foreach (var parameter in method.GetParameters())
|
||||||
|
{
|
||||||
|
sb.AppendLine($"-- @tparam {TypeToString(parameter.ParameterType)} {EscapeName(parameter.Name!)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.ReturnType != typeof(void))
|
||||||
|
{
|
||||||
|
sb.AppendLine($"-- @treturn {TypeToString(method.ReturnType)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendLine(functionDecoration);
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? ConvertAnnotation(Type type, FieldInfo field, string realm)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
var name = EscapeName(field.Name);
|
||||||
|
var returnName = TypeToString(field.FieldType);
|
||||||
|
|
||||||
|
if (field.IsStatic)
|
||||||
|
{
|
||||||
|
name = type.Name + "." + field.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removed.Contains("-- @remove " + name))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"removed {name}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($" - FIELD: {name}");
|
||||||
|
|
||||||
|
sb.AppendLine("---");
|
||||||
|
sb.Append("-- ");
|
||||||
|
sb.Append(name);
|
||||||
|
sb.AppendLine($", field of type {returnName}");
|
||||||
|
sb.AppendLine($"-- @realm {realm}");
|
||||||
|
sb.AppendLine($"-- @field {name}");
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? ConvertAnnotation(Type type, PropertyInfo property, string realm)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
var name = EscapeName(property.Name);
|
||||||
|
var returnName = TypeToString(property.PropertyType);
|
||||||
|
|
||||||
|
if (property.GetGetMethod()?.IsStatic == true || property.GetSetMethod()?.IsStatic == true)
|
||||||
|
{
|
||||||
|
name = type.Name + "." + property.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removed.Contains("-- @remove " + name))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"removed {name}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($" - PROPERTY: {name}");
|
||||||
|
|
||||||
|
sb.AppendLine("---");
|
||||||
|
sb.Append("-- ");
|
||||||
|
sb.Append(name);
|
||||||
|
sb.AppendLine($", field of type {returnName}");
|
||||||
|
sb.AppendLine("-- @realm shared");
|
||||||
|
sb.AppendLine($"-- @field {name}");
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetSignature(MemberInfo member)
|
||||||
|
{
|
||||||
|
switch (member.MemberType)
|
||||||
|
{
|
||||||
|
case MemberTypes.Method:
|
||||||
|
return GetSignature((MethodInfo)member);
|
||||||
|
case MemberTypes.Field:
|
||||||
|
return GetSignature((FieldInfo)member);
|
||||||
|
case MemberTypes.Property:
|
||||||
|
return GetSignature((PropertyInfo)member);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetSignature(FieldInfo field)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.Append(field.FieldType.Name);
|
||||||
|
sb.Append(" ");
|
||||||
|
sb.Append(field.Name);
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetSignature(PropertyInfo property)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.Append(property.PropertyType.Name);
|
||||||
|
sb.Append(" ");
|
||||||
|
sb.Append(property.Name);
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetSignature(MethodInfo method)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
bool firstParam = true;
|
||||||
|
|
||||||
|
sb.Append(method.ReturnType.Name);
|
||||||
|
sb.Append(' ');
|
||||||
|
sb.Append(method.Name);
|
||||||
|
|
||||||
|
// Add method generics
|
||||||
|
if (method.IsGenericMethod)
|
||||||
|
{
|
||||||
|
sb.Append("<");
|
||||||
|
foreach (var g in method.GetGenericArguments())
|
||||||
|
{
|
||||||
|
if (firstParam)
|
||||||
|
{
|
||||||
|
firstParam = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(", ");
|
||||||
|
}
|
||||||
|
sb.Append(g.Name);
|
||||||
|
}
|
||||||
|
sb.Append(">");
|
||||||
|
}
|
||||||
|
sb.Append("(");
|
||||||
|
firstParam = true;
|
||||||
|
foreach (var param in method.GetParameters())
|
||||||
|
{
|
||||||
|
if (firstParam)
|
||||||
|
{
|
||||||
|
firstParam = false;
|
||||||
|
if (method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false))
|
||||||
|
{
|
||||||
|
sb.Append("this ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append(", ");
|
||||||
|
|
||||||
|
if (param.ParameterType.IsByRef)
|
||||||
|
{
|
||||||
|
sb.Append("ref ");
|
||||||
|
}
|
||||||
|
else if (param.IsOut)
|
||||||
|
{
|
||||||
|
sb.Append("out ");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append(param.ParameterType.Name);
|
||||||
|
sb.Append(' ');
|
||||||
|
|
||||||
|
sb.Append(param.Name);
|
||||||
|
}
|
||||||
|
sb.Append(")");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GenerateBaseDoc(Type type, string categoryName, string baseFile)
|
||||||
|
{
|
||||||
|
string baseLuaText;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
baseLuaText = File.ReadAllText(baseFile);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
baseLuaText = @$"-- luacheck: ignore 111
|
||||||
|
|
||||||
|
--[[--
|
||||||
|
{type.FullName}
|
||||||
|
]]
|
||||||
|
-- @code {categoryName}
|
||||||
|
-- @pragma nostrip
|
||||||
|
local {type.Name} = {{}}".ReplaceLineEndings("\n");
|
||||||
|
|
||||||
|
File.WriteAllText(baseFile, baseLuaText);
|
||||||
|
}
|
||||||
|
|
||||||
|
removed = new HashSet<string>();
|
||||||
|
var removeTagPattern = new Regex("^-- @remove (.*)$", RegexOptions.Multiline);
|
||||||
|
var matches = removeTagPattern.Matches(baseLuaText);
|
||||||
|
|
||||||
|
foreach (var match in matches.Cast<Match>())
|
||||||
|
{
|
||||||
|
removed.Add(match.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseLuaText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GenerateDocs(Type type, string baseFile, string outFile, string? categoryName = null)
|
||||||
|
{
|
||||||
|
categoryName ??= type.Name;
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
Console.WriteLine($"Generating docs for {type}");
|
||||||
|
|
||||||
|
string baseDoc = GenerateBaseDoc(type, categoryName, baseFile);
|
||||||
|
|
||||||
|
sb.Append(baseDoc);
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.AppendLine();
|
||||||
|
|
||||||
|
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
foreach (var member in members)
|
||||||
|
{
|
||||||
|
switch (member.MemberType)
|
||||||
|
{
|
||||||
|
case MemberTypes.Method:
|
||||||
|
{
|
||||||
|
sb.Append(ConvertAnnotation(type, (MethodInfo)member, "shared"));
|
||||||
|
sb.AppendLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MemberTypes.Field:
|
||||||
|
{
|
||||||
|
sb.Append(ConvertAnnotation(type, (FieldInfo)member, "shared"));
|
||||||
|
sb.AppendLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MemberTypes.Property:
|
||||||
|
{
|
||||||
|
sb.Append(ConvertAnnotation(type, (PropertyInfo)member, "shared"));
|
||||||
|
sb.AppendLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new FileInfo(outFile).Directory.Create();
|
||||||
|
File.WriteAllText(outFile, sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GenerateDocs(Type clientType, Type serverType, string baseFile, string outFile, string? categoryName = null)
|
||||||
|
{
|
||||||
|
categoryName ??= clientType.Name;
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
Console.WriteLine($"Generating docs for {clientType} and {serverType}");
|
||||||
|
|
||||||
|
sb.Append(GenerateBaseDoc(clientType, categoryName, baseFile));
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.AppendLine();
|
||||||
|
|
||||||
|
List<(string?, MemberInfo)> clientTypes = new List<(string?, MemberInfo)>();
|
||||||
|
List<(string?, MemberInfo)> serverTypes = new List<(string?, MemberInfo)>();
|
||||||
|
|
||||||
|
var clientMembers = clientType.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
var serverMembers = serverType.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
|
||||||
|
foreach (var member in clientMembers)
|
||||||
|
{
|
||||||
|
clientTypes.Add((GetSignature(member), member));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var member in serverMembers)
|
||||||
|
{
|
||||||
|
serverTypes.Add((GetSignature(member), member));
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids = clientTypes.Select(x => x.Item1).Intersect(serverTypes.Select(x => x.Item1));
|
||||||
|
List<(string?, MemberInfo)> sharedTypes = clientTypes.Where(x => ids.Contains(x.Item1)).ToList();
|
||||||
|
|
||||||
|
foreach (var type in sharedTypes)
|
||||||
|
{
|
||||||
|
string? result = ConvertAnnotation(clientType, type.Item2, "shared");
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
sb.Append(result);
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var type in clientTypes)
|
||||||
|
{
|
||||||
|
string? result = ConvertAnnotation(clientType, type.Item2, "client");
|
||||||
|
|
||||||
|
if (result != null && !sharedTypes.Select(x => x.Item1).Contains(type.Item1))
|
||||||
|
{
|
||||||
|
sb.Append(result);
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var type in serverTypes)
|
||||||
|
{
|
||||||
|
string? result = ConvertAnnotation(clientType, type.Item2, "server");
|
||||||
|
|
||||||
|
if (result != null && !sharedTypes.Select(x => x.Item1).Contains(type.Item1))
|
||||||
|
{
|
||||||
|
sb.Append(result);
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new FileInfo(outFile).Directory.Create();
|
||||||
|
File.WriteAllText(outFile, sb.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,13 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../../../Barotrauma/BarotraumaClient/LinuxClient.csproj" PrivateAssets="false" />
|
<ProjectReference Include="../../../../Barotrauma/BarotraumaClient/LinuxClient.csproj" PrivateAssets="false">
|
||||||
|
<Private></Private>
|
||||||
|
<Aliases>BarotraumaClient</Aliases>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="../../../../Barotrauma\BarotraumaServer\LinuxServer.csproj">
|
||||||
|
<Aliases>BarotraumaServer</Aliases>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="../../../../Libraries/Farseer Physics Engine 3.5/Farseer.NetStandard.csproj" PrivateAssets="false" />
|
<ProjectReference Include="../../../../Libraries/Farseer Physics Engine 3.5/Farseer.NetStandard.csproj" PrivateAssets="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,34 +1,102 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.30114.105
|
VisualStudioVersion = 17.4.33122.133
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaDocsGenerator", "LuaDocsGenerator.csproj", "{F1961973-E69E-41A7-BE13-4F931890BC70}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinuxClient", "..\..\..\..\Barotrauma\BarotraumaClient\LinuxClient.csproj", "{426071C4-6668-4CF9-A44C-5FBEB72C469B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinuxClient", "..\..\..\..\Barotrauma\BarotraumaClient\LinuxClient.csproj", "{426071C4-6668-4CF9-A44C-5FBEB72C469B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Farseer.NetStandard", "..\..\..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj", "{F8F85D52-11B5-4177-914C-9AC75345D089}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Farseer.NetStandard", "..\..\..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj", "{F8F85D52-11B5-4177-914C-9AC75345D089}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinuxServer", "..\..\..\..\Barotrauma\BarotraumaServer\LinuxServer.csproj", "{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LuaDocsGenerator", "LuaDocsGenerator.csproj", "{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Unstable|Any CPU = Unstable|Any CPU
|
||||||
|
Unstable|x64 = Unstable|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Release|x64.Build.0 = Release|x64
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Unstable|Any CPU.ActiveCfg = Unstable|Any CPU
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Unstable|Any CPU.Build.0 = Unstable|Any CPU
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Unstable|x64.ActiveCfg = Unstable|x64
|
||||||
|
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Unstable|x64.Build.0 = Unstable|x64
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Release|x64.Build.0 = Release|x64
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Unstable|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Unstable|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Unstable|x64.ActiveCfg = Debug|x64
|
||||||
|
{F8F85D52-11B5-4177-914C-9AC75345D089}.Unstable|x64.Build.0 = Debug|x64
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Release|x64.Build.0 = Release|x64
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Unstable|Any CPU.ActiveCfg = Unstable|Any CPU
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Unstable|Any CPU.Build.0 = Unstable|Any CPU
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Unstable|x64.ActiveCfg = Unstable|x64
|
||||||
|
{562EDFE0-7AEB-4F1E-BC26-148DF42F4186}.Unstable|x64.Build.0 = Unstable|x64
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Unstable|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Unstable|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Unstable|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{FDB16AC2-7947-4DCC-A46F-E9D1B05C0A1E}.Unstable|x64.Build.0 = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Unstable|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Unstable|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Unstable|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{49C8C464-A381-4FDD-AB52-80BB9FE35DDB}.Unstable|x64.Build.0 = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Unstable|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Unstable|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Unstable|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{6E36A474-29B7-4F0C-96CE-79F11BF6C0A4}.Unstable|x64.Build.0 = Debug|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
{F1961973-E69E-41A7-BE13-4F931890BC70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
SolutionGuid = {681C79BD-27C3-4CAF-9622-A425B77CF1CD}
|
||||||
{F1961973-E69E-41A7-BE13-4F931890BC70}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F1961973-E69E-41A7-BE13-4F931890BC70}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F1961973-E69E-41A7-BE13-4F931890BC70}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{426071C4-6668-4CF9-A44C-5FBEB72C469B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F8F85D52-11B5-4177-914C-9AC75345D089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F8F85D52-11B5-4177-914C-9AC75345D089}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F8F85D52-11B5-4177-914C-9AC75345D089}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F8F85D52-11B5-4177-914C-9AC75345D089}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -1,437 +1,87 @@
|
|||||||
using System.Diagnostics;
|
extern alias BarotraumaClient;
|
||||||
using System.Reflection;
|
extern alias BarotraumaServer;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Barotrauma;
|
|
||||||
using Barotrauma.Networking;
|
|
||||||
|
|
||||||
string NormalizeGenericTypeName(string s)
|
namespace LuaDocsGenerator
|
||||||
{
|
{
|
||||||
var idx = s.LastIndexOf('`');
|
|
||||||
|
|
||||||
if (idx != -1)
|
internal class Program
|
||||||
{
|
{
|
||||||
return s[..idx];
|
private static string basePath = "";
|
||||||
}
|
private static string generatedDir = "";
|
||||||
|
private static string baseLuaDir = "";
|
||||||
|
|
||||||
return s;
|
private static void GenerateDocs<T>(string file, string? categoryName = null)
|
||||||
|
{
|
||||||
|
DocsGenerator.GenerateDocs(typeof(T), $"{baseLuaDir}/{file}", $"{generatedDir}/{file}", categoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GenerateDocs<T1, T2>(string file, string? categoryName = null)
|
||||||
|
{
|
||||||
|
DocsGenerator.GenerateDocs(typeof(T1), typeof(T2), $"{baseLuaDir}/{file}", $"{generatedDir}/{file}", categoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GenerateDocs(Type clientType, Type serverType, string file, string? categoryName = null)
|
||||||
|
{
|
||||||
|
DocsGenerator.GenerateDocs(clientType, serverType, $"{baseLuaDir}/{file}", $"{generatedDir}/{file}", categoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var gitDir = (new Func<String>(() =>
|
||||||
|
{
|
||||||
|
var (success, gitDir, error) = DocsGenerator.TryRunGitCommand("rev-parse --show-toplevel");
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
throw new InvalidDataException($"Failed to determine the root of the git repo: {error}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitDir;
|
||||||
|
}))();
|
||||||
|
|
||||||
|
basePath = $"{gitDir}/luacs-docs/lua";
|
||||||
|
generatedDir = $"{basePath}/lua/generated";
|
||||||
|
baseLuaDir = $"{basePath}/baseluadocs";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.Delete(generatedDir, true);
|
||||||
|
}
|
||||||
|
catch (DirectoryNotFoundException) { }
|
||||||
|
|
||||||
|
Directory.CreateDirectory(generatedDir);
|
||||||
|
Directory.CreateDirectory(baseLuaDir);
|
||||||
|
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Character, BarotraumaServer::Barotrauma.Character>("Character.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.CharacterInfo, BarotraumaServer::Barotrauma.CharacterInfo>("CharacterInfo.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.CharacterHealth, BarotraumaServer::Barotrauma.CharacterHealth>("CharacterHealth.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.AnimController, BarotraumaServer::Barotrauma.AnimController>("AnimController.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Networking.Client, BarotraumaServer::Barotrauma.Networking.Client>("Client.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Entity, BarotraumaServer::Barotrauma.Entity>("Entity.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.EntitySpawner, BarotraumaServer::Barotrauma.EntitySpawner>("Entity.Spawner.lua", "Entity.Spawner");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Item, BarotraumaServer::Barotrauma.Item>("Item.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.ItemPrefab, BarotraumaServer::Barotrauma.ItemPrefab>("ItemPrefab.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Submarine, BarotraumaServer::Barotrauma.Submarine>("Submarine.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.SubmarineInfo, BarotraumaServer::Barotrauma.SubmarineInfo>("SubmarineInfo.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Job, BarotraumaServer::Barotrauma.Job>("Job.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.JobPrefab, BarotraumaServer::Barotrauma.JobPrefab>("JobPrefab.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.GameSession, BarotraumaServer::Barotrauma.GameSession>("GameSession.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.NetLobbyScreen, BarotraumaServer::Barotrauma.NetLobbyScreen>("NetLobbyScreen.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.GameScreen, BarotraumaServer::Barotrauma.GameScreen>("GameScreen.lua");
|
||||||
|
GenerateDocs<FarseerPhysics.Dynamics.World>("World.lua", "Game.World");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Inventory, BarotraumaServer::Barotrauma.Inventory>("Inventory.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.ItemInventory, BarotraumaServer::Barotrauma.ItemInventory>("ItemInventory.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.CharacterInventory, BarotraumaServer::Barotrauma.CharacterInventory>("CharacterInventory.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Hull, BarotraumaServer::Barotrauma.Hull>("Hull.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Level, BarotraumaServer::Barotrauma.Level>("Level.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Affliction, BarotraumaServer::Barotrauma.Affliction>("Affliction.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.AfflictionPrefab, BarotraumaServer::Barotrauma.AfflictionPrefab>("AfflictionPrefab.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.WayPoint, BarotraumaServer::Barotrauma.WayPoint>("WayPoint.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Networking.ServerSettings, BarotraumaServer::Barotrauma.Networking.ServerSettings>("ServerSettings.lua", "Game.ServerSettings");
|
||||||
|
GenerateDocs(typeof(BarotraumaClient::Barotrauma.GameSettings), typeof(BarotraumaServer::Barotrauma.GameSettings), "GameSettings.lua", "Game.Settings");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Structure, BarotraumaServer::Barotrauma.Structure>("Structure.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.StructurePrefab, BarotraumaServer::Barotrauma.StructurePrefab>("StructurePrefab.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.PhysicsBody, BarotraumaServer::Barotrauma.PhysicsBody>("PhysicsBody.lua");
|
||||||
|
GenerateDocs<BarotraumaClient::Barotrauma.Limb, BarotraumaServer::Barotrauma.Limb>("Limb.lua");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string TypeToString(Type type, bool useLuaTypes = true)
|
|
||||||
{
|
|
||||||
// Return "T" for unresolved type params
|
|
||||||
if (type.IsGenericParameter)
|
|
||||||
{
|
|
||||||
return type.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
var genericType = type.IsGenericType
|
|
||||||
? type.GetGenericTypeDefinition()
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (type == typeof(bool))
|
|
||||||
{
|
|
||||||
return "bool";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == typeof(string))
|
|
||||||
{
|
|
||||||
return "string";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useLuaTypes)
|
|
||||||
{
|
|
||||||
if (type == typeof(sbyte)
|
|
||||||
|| type == typeof(byte)
|
|
||||||
|| type == typeof(short)
|
|
||||||
|| type == typeof(ushort)
|
|
||||||
|| type == typeof(int)
|
|
||||||
|| type == typeof(uint)
|
|
||||||
|| type == typeof(long)
|
|
||||||
|| type == typeof(ulong)
|
|
||||||
|| type == typeof(float)
|
|
||||||
|| type == typeof(double))
|
|
||||||
{
|
|
||||||
return "number";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (genericType == typeof(List<>)
|
|
||||||
|| genericType == typeof(Dictionary<,>))
|
|
||||||
{
|
|
||||||
return "table";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (genericType == typeof(Action<,>)
|
|
||||||
|| genericType == typeof(Func<,>))
|
|
||||||
{
|
|
||||||
return "function";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var nsToRemove = new[] {
|
|
||||||
"Barotrauma",
|
|
||||||
"System",
|
|
||||||
"System.Collections",
|
|
||||||
"System.Collections.Generic",
|
|
||||||
};
|
|
||||||
|
|
||||||
string Namespaced(string typeName)
|
|
||||||
{
|
|
||||||
if (type.Namespace == null)
|
|
||||||
{
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Full namespace match
|
|
||||||
if (nsToRemove.Contains(type.Namespace))
|
|
||||||
{
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partial namespace match
|
|
||||||
foreach (var ns in nsToRemove)
|
|
||||||
{
|
|
||||||
if (ns == type.Namespace)
|
|
||||||
{
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.Namespace.StartsWith(ns + "."))
|
|
||||||
{
|
|
||||||
var shortNs = type.Namespace.Remove(0, ns.Length + 1);
|
|
||||||
return $"{shortNs}.{typeName}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $"{type.Namespace}.{typeName}";
|
|
||||||
}
|
|
||||||
|
|
||||||
string Impl(string? ns)
|
|
||||||
{
|
|
||||||
if (type.IsGenericType)
|
|
||||||
{
|
|
||||||
var genericTypeDef = type.GetGenericTypeDefinition();
|
|
||||||
var genericTypeName = NormalizeGenericTypeName(genericTypeDef.Name);
|
|
||||||
|
|
||||||
var genericArgs = type.GetGenericArguments();
|
|
||||||
|
|
||||||
// Use the `T?` notation instead of Nullable<T>
|
|
||||||
if (genericTypeDef == typeof(Nullable<>))
|
|
||||||
{
|
|
||||||
// ldoc supports the "?string" notation, which expands to "?|nil|string"
|
|
||||||
if (useLuaTypes)
|
|
||||||
{
|
|
||||||
return Namespaced("?" + TypeToString(genericArgs[0], useLuaTypes: false));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Namespaced(TypeToString(genericArgs[0], useLuaTypes: false) + "?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.Append(genericTypeName);
|
|
||||||
sb.Append("<");
|
|
||||||
foreach (var genericArgType in genericArgs)
|
|
||||||
{
|
|
||||||
sb.Append(TypeToString(genericArgType, useLuaTypes: false));
|
|
||||||
sb.Append(",");
|
|
||||||
}
|
|
||||||
// Remove the last separator
|
|
||||||
sb.Length--;
|
|
||||||
sb.Append(">");
|
|
||||||
|
|
||||||
return Namespaced(sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Namespaced(type.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Impl(type.Namespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
static (bool Success, string Output, string Error) TryRunGitCommand(string args)
|
|
||||||
{
|
|
||||||
static string? GetGitBinary()
|
|
||||||
{
|
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
||||||
{
|
|
||||||
return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process)
|
|
||||||
?.Split(';')
|
|
||||||
.Select(x => Path.Join(x, "git.exe"))
|
|
||||||
.FirstOrDefault(File.Exists);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process)
|
|
||||||
?.Split(':')
|
|
||||||
.Select(x => Path.Join(x, "git"))
|
|
||||||
.FirstOrDefault(File.Exists);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var gitBinary = GetGitBinary();
|
|
||||||
if (gitBinary == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Failed to find git binary in PATH");
|
|
||||||
}
|
|
||||||
|
|
||||||
using var process = Process.Start(new ProcessStartInfo(gitBinary, args)
|
|
||||||
{
|
|
||||||
WindowStyle = ProcessWindowStyle.Hidden,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
RedirectStandardInput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (process == null)
|
|
||||||
throw new InvalidOperationException($"Failed to run git command: {args}");
|
|
||||||
|
|
||||||
process.Start();
|
|
||||||
|
|
||||||
var stdOut = process.StandardOutput.ReadToEndAsync();
|
|
||||||
var stdErr = process.StandardError.ReadToEndAsync();
|
|
||||||
Task.WhenAll(stdOut, stdErr).GetAwaiter().GetResult();
|
|
||||||
process.WaitForExit();
|
|
||||||
|
|
||||||
return (process.ExitCode == 0, stdOut.Result.TrimEnd('\r', '\n'), stdErr.Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
var gitDir = (new Func<String>(() =>
|
|
||||||
{
|
|
||||||
var (success, gitDir, error) = TryRunGitCommand("rev-parse --show-toplevel");
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
throw new InvalidDataException($"Failed to determine the root of the git repo: {error}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return gitDir;
|
|
||||||
}))();
|
|
||||||
|
|
||||||
void GenerateDocsImpl(Type type, string baseFile, string outFile, string? categoryName = null)
|
|
||||||
{
|
|
||||||
categoryName ??= type.Name;
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
Console.WriteLine($"Generating docs for {type}");
|
|
||||||
|
|
||||||
string baseLuaText;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
baseLuaText = File.ReadAllText(baseFile);
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException)
|
|
||||||
{
|
|
||||||
baseLuaText = @$"-- luacheck: ignore 111
|
|
||||||
|
|
||||||
--[[--
|
|
||||||
{type.FullName}
|
|
||||||
]]
|
|
||||||
-- @code {categoryName}
|
|
||||||
-- @pragma nostrip
|
|
||||||
local {type.Name} = {{}}".ReplaceLineEndings("\n");
|
|
||||||
|
|
||||||
File.WriteAllText(baseFile, baseLuaText);
|
|
||||||
}
|
|
||||||
|
|
||||||
var removeTagPattern = new Regex("^-- @remove (.*)$", RegexOptions.Multiline);
|
|
||||||
var removed = new HashSet<string>();
|
|
||||||
var matches = removeTagPattern.Matches(baseLuaText);
|
|
||||||
|
|
||||||
foreach (var match in matches.Cast<Match>())
|
|
||||||
{
|
|
||||||
removed.Add(match.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append(baseLuaText);
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine();
|
|
||||||
|
|
||||||
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
|
||||||
foreach (var member in members)
|
|
||||||
{
|
|
||||||
static string EscapeName(string n)
|
|
||||||
{
|
|
||||||
return n switch
|
|
||||||
{
|
|
||||||
"end" => "endparam",
|
|
||||||
_ => n
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (member.MemberType)
|
|
||||||
{
|
|
||||||
case MemberTypes.Method:
|
|
||||||
{
|
|
||||||
var method = (MethodInfo)member;
|
|
||||||
|
|
||||||
// Exclude property getters/setters
|
|
||||||
if (method.IsSpecialName)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var paramNames = new StringBuilder();
|
|
||||||
foreach (var parameter in method.GetParameters())
|
|
||||||
{
|
|
||||||
paramNames.Append(EscapeName(parameter.Name!));
|
|
||||||
paramNames.Append(", ");
|
|
||||||
}
|
|
||||||
if (paramNames.Length > 0)
|
|
||||||
{
|
|
||||||
// Remove the last separator
|
|
||||||
paramNames.Length -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
string functionDecoration;
|
|
||||||
if (method.IsStatic)
|
|
||||||
{
|
|
||||||
functionDecoration = $"function {type.Name}.{method.Name}({paramNames}) end";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
functionDecoration = $"function {method.Name}({paramNames}) end";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removed.Contains(functionDecoration))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($" - METHOD: {method}");
|
|
||||||
|
|
||||||
sb.AppendLine($"--- {method.Name}");
|
|
||||||
sb.AppendLine("-- @realm shared");
|
|
||||||
|
|
||||||
foreach (var parameter in method.GetParameters())
|
|
||||||
{
|
|
||||||
sb.AppendLine($"-- @tparam {TypeToString(parameter.ParameterType)} {EscapeName(parameter.Name!)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method.ReturnType != typeof(void))
|
|
||||||
{
|
|
||||||
sb.AppendLine($"-- @treturn {TypeToString(method.ReturnType)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine(functionDecoration);
|
|
||||||
sb.AppendLine();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MemberTypes.Field:
|
|
||||||
{
|
|
||||||
var field = (FieldInfo)member;
|
|
||||||
|
|
||||||
var name = EscapeName(field.Name);
|
|
||||||
var returnName = TypeToString(field.FieldType);
|
|
||||||
|
|
||||||
if (field.IsStatic)
|
|
||||||
{
|
|
||||||
name = type.Name + "." + field.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removed.Contains(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($" - FIELD: {name}");
|
|
||||||
|
|
||||||
sb.AppendLine("---");
|
|
||||||
sb.Append("-- ");
|
|
||||||
sb.Append(name);
|
|
||||||
sb.AppendLine($", field of type {returnName}");
|
|
||||||
sb.AppendLine("-- @realm shared");
|
|
||||||
sb.AppendLine($"-- @field {name}");
|
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MemberTypes.Property:
|
|
||||||
{
|
|
||||||
var property = (PropertyInfo)member;
|
|
||||||
|
|
||||||
var name = EscapeName(property.Name);
|
|
||||||
var returnName = TypeToString(property.PropertyType);
|
|
||||||
|
|
||||||
if (property.GetGetMethod()?.IsStatic == true || property.GetSetMethod()?.IsStatic == true)
|
|
||||||
{
|
|
||||||
name = type.Name + "." + property.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removed.Contains(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($" - PROPERTY: {name}");
|
|
||||||
|
|
||||||
sb.AppendLine("---");
|
|
||||||
sb.Append("-- ");
|
|
||||||
sb.Append(name);
|
|
||||||
sb.AppendLine($", field of type {returnName}");
|
|
||||||
sb.AppendLine("-- @realm shared");
|
|
||||||
sb.AppendLine($"-- @field {name}");
|
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new FileInfo(outFile).Directory.Create();
|
|
||||||
File.WriteAllText(outFile, sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
var basePath = $"{gitDir}/luacs-docs/lua";
|
|
||||||
var generatedDir = $"{basePath}/lua/generated";
|
|
||||||
var baseLuaDir = $"{basePath}/baseluadocs";
|
|
||||||
void GenerateDocs(Type type, string file, string? categoryName = null)
|
|
||||||
{
|
|
||||||
GenerateDocsImpl(type, $"{baseLuaDir}/{file}", $"{generatedDir}/{file}", categoryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Directory.Delete(generatedDir, true);
|
|
||||||
}
|
|
||||||
catch (DirectoryNotFoundException) { }
|
|
||||||
|
|
||||||
Directory.CreateDirectory(generatedDir);
|
|
||||||
Directory.CreateDirectory(baseLuaDir);
|
|
||||||
|
|
||||||
GenerateDocs(typeof(Character), "Character.lua");
|
|
||||||
GenerateDocs(typeof(CharacterInfo), "CharacterInfo.lua");
|
|
||||||
GenerateDocs(typeof(CharacterHealth), "CharacterHealth.lua");
|
|
||||||
GenerateDocs(typeof(AnimController), "AnimController.lua");
|
|
||||||
GenerateDocs(typeof(Client), "Client.lua");
|
|
||||||
GenerateDocs(typeof(Entity), "Entity.lua");
|
|
||||||
GenerateDocs(typeof(EntitySpawner), "Entity.Spawner.lua", "Entity.Spawner");
|
|
||||||
GenerateDocs(typeof(Item), "Item.lua");
|
|
||||||
GenerateDocs(typeof(ItemPrefab), "ItemPrefab.lua");
|
|
||||||
GenerateDocs(typeof(Submarine), "Submarine.lua");
|
|
||||||
GenerateDocs(typeof(SubmarineInfo), "SubmarineInfo.lua");
|
|
||||||
GenerateDocs(typeof(Job), "Job.lua");
|
|
||||||
GenerateDocs(typeof(JobPrefab), "JobPrefab.lua");
|
|
||||||
GenerateDocs(typeof(GameSession), "GameSession.lua", "Game.GameSession");
|
|
||||||
GenerateDocs(typeof(NetLobbyScreen), "NetLobbyScreen.lua", "Game.NetLobbyScreen");
|
|
||||||
GenerateDocs(typeof(GameScreen), "GameScreen.lua", "Game.GameScreen");
|
|
||||||
GenerateDocs(typeof(FarseerPhysics.Dynamics.World), "World.lua", "Game.World");
|
|
||||||
GenerateDocs(typeof(Inventory), "Inventory.lua", "Inventory");
|
|
||||||
GenerateDocs(typeof(ItemInventory), "ItemInventory.lua", "ItemInventory");
|
|
||||||
GenerateDocs(typeof(CharacterInventory), "CharacterInventory.lua", "CharacterInventory");
|
|
||||||
GenerateDocs(typeof(Hull), "Hull.lua", "Hull");
|
|
||||||
GenerateDocs(typeof(Level), "Level.lua", "Level");
|
|
||||||
GenerateDocs(typeof(Affliction), "Affliction.lua", "Affliction");
|
|
||||||
GenerateDocs(typeof(AfflictionPrefab), "AfflictionPrefab.lua", "AfflictionPrefab");
|
|
||||||
GenerateDocs(typeof(WayPoint), "WayPoint.lua", "WayPoint");
|
|
||||||
GenerateDocs(typeof(ServerSettings), "ServerSettings.lua", "Game.ServerSettings");
|
|
||||||
GenerateDocs(typeof(GameSettings), "GameSettings.lua", "Game.Settings");
|
|
||||||
GenerateDocs(typeof(Structure), "Structure.lua", "Structure");
|
|
||||||
GenerateDocs(typeof(StructurePrefab), "StructurePrefab.lua", "StructurePrefab");
|
|
||||||
GenerateDocs(typeof(Limb), "Limb.lua", "Limb");
|
|
||||||
GenerateDocs(typeof(PhysicsBody), "PhysicsBody.lua", "PhysicsBody");
|
|
||||||
|
|||||||
Reference in New Issue
Block a user