rj-action-library-godot-dev.../Scripts/Doc-Generator/ClassDocGenerator.cs

185 lines
4.9 KiB
C#

using Godot;
using Rokojori;
using System.Collections.Generic;
using System;
using System.Reflection;
using System.Text.RegularExpressions;
namespace Rokojori.DocGenerator
{
public class ClassDocGenerator
{
ClassDocInfo info = new ClassDocInfo();
public string GetIcon( string classFile, string name, List<string> baseTypes, List<string> icons )
{
var iconMatcher = new Regex( "Icon\\(\"res://Scripts/Rokojori/Rokojori-Action-Library/Icons/(\\w+\\.svg)" );
var result = iconMatcher.Matches( classFile );
if ( result != null && result.Count == 1 )
{
return result[ 0 ].Groups[ 1 ].Value;
}
if ( icons.IndexOf( name + ".svg" ) != -1 )
{
return name + ".svg";
}
foreach ( var bt in baseTypes )
{
if ( icons.IndexOf( bt + ".svg" ) != -1 )
{
return bt + ".svg";
}
}
return "CSharp.svg";
}
public ClassDocInfo Create( string filePath, Type type, List<string> icons )
{
var data = filePath == null ? "" : FilesSync.LoadUTF8( filePath );
var comments = new DocComments();
comments.Grab( data );
RJLog.Log( type.Name, "Comments:", comments.entries.Count );
info.name = type.Name;
info.csNameSpace = type.Namespace;
info.doc = comments.FindDoc( "class", type.Name );
info.generics = Lists.Map( type.GenericTypeArguments, t => t + "" );
var allBindings = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
var fields = Lists.ToList( type.GetFields( allBindings ) );
fields = Lists.Filter( fields, f => ! f.IsPrivate );
var godotTypes = new List<string>()
{
"Node", "Resource"
};
var it = type.BaseType;
while ( it != null )
{
if ( godotTypes.IndexOf( it.Name) != -1 )
{
if ( "Node" == it.Name )
{
info.extendingClasses.AddRange( new string[]{ "Node", "Object" } );
}
else if ( "Resource" == it.Name )
{
info.extendingClasses.AddRange( new string[]{ "Resource", "RefCounted", "Object" } );
}
it = null;
}
else
{
info.extendingClasses.Add( it.Name );
it = it.BaseType;
}
}
info.icon = GetIcon( data, info.name, info.extendingClasses, icons );
fields.ForEach(
( f )=>
{
var memberInfo = MemberInfo.CreateField();
memberInfo.name = f.Name;
memberInfo.csNameSpace = f.FieldType.Namespace;
memberInfo.dataType = f.FieldType.Name;
memberInfo.generics = Lists.Map( f.FieldType.GetGenericArguments(), t => t + "" );
memberInfo.doc = comments.FindDoc( "field", f.Name );
if ( f.IsStatic )
{
memberInfo.modifiers.Add( "static" );
}
memberInfo.modifiers.Add( f.IsPublic ? "public" : "protected" );
info.memberInfos.Add( memberInfo );
}
);
var methods = Lists.ToList( type.GetMethods( allBindings ) );
methods = Lists.Filter( methods, m => ! m.IsPrivate );
var godotInternalMethods = new List<string>()
{
"GetGodotMethodList",
"InvokeGodotClassMethod",
"HasGodotClassMethod",
"SetGodotClassPropertyValue",
"GetGodotClassPropertyValue",
"GetGodotPropertyList",
"GetGodotPropertyDefaultValues",
"SaveGodotObjectData",
"RestoreGodotObjectData"
};
methods.ForEach(
m =>
{
if ( godotInternalMethods.IndexOf( m.Name ) != -1 )
{
return;
}
var memberInfo = MemberInfo.CreateMethod();
memberInfo.name = m.Name;
memberInfo.dataType = m.ReturnType.Name;
memberInfo.csNameSpace = m.ReturnType.Namespace;
memberInfo.generics = Lists.Map( m.GetGenericArguments(), t => t + "" );
memberInfo.doc = comments.FindDoc( "method", m.Name );
if ( m.IsStatic )
{
memberInfo.modifiers.Add( "static" );
}
memberInfo.modifiers.Add( m.IsPublic ? "public" : "protected" );
var parameters = Lists.ToList( m.GetParameters() );
parameters.ForEach(
( p )=>
{
var parameterType = new ParameterType();
parameterType.name = p.Name;
parameterType.type = p.ParameterType.Name;
parameterType.csNameSpace = p.ParameterType.Namespace;
parameterType.generics = Lists.Map( p.ParameterType.GenericTypeArguments, t => t + "" );
memberInfo.parameters.Add( parameterType );
}
);
info.memberInfos.Add( memberInfo );
}
);
return info;
}
}
}