using Godot; using Rokojori; using System.Collections.Generic; using System; using Microsoft.VisualBasic; using Rokojori.Tools; using System.Threading.Tasks; namespace Rokojori.DocGenerator { public class ClassTypeEntry { public Type type; public string definitionType; public string path; } public class ShaderTypeEntry { public string path; } public class DocGenerator { string path = ""; string outputPath = ""; List icons = new List(); public bool checkChangeTime = false; public DateTimeOffset changeTime; public List classFiles = new List(); public List classTypes = new List(); public List shaderTypes = new List(); public bool shaders = true; public bool cSharp = true; public async void Generate( string path, string outputPath, List icons ) { this.path = path; this.outputPath = outputPath; this.icons = icons; await GetFiles(); CreateTypesFromFiles(); // IncludeDefaultTypes(); GenerateDocsFromTypes(); } async Task GetFiles() { classFiles = FilesSync.GetFiles( path, f => { var isCS = f.fileExtension == ".cs"; var isShader = f.fileExtension == ".gdshader" || f.fileExtension == ".gdshaderinc"; if ( isShader ) { RJLog.Log( "SHADER: FILE", f.absolutePath ); } return ( cSharp && isCS ) || ( shaders && isShader ); }, true ); if ( checkChangeTime ) { classFiles = await classFiles.FilterAsync( async ( f ) => { return await Git.IsFileNewerThan( f.absolutePath, changeTime ); } ); } } void IncludeDefaultTypes() { var defaultTypes = new List() { typeof( NetworkNode ), typeof( Action ), typeof( Sensor ), typeof( Selector ) }; defaultTypes.ForEach( ( dt )=> { var entry = new ClassTypeEntry(); entry.type = dt; entry.path = null; classTypes.Add( entry); } ); } void CreateTypesFromFiles() { var genericType = new EventSlot().GetType(); var namespaceLabel = "Rokojori"; var assembly = genericType.Assembly; classFiles.ForEach( ( cf )=> { var name = cf.fileName; if ( cf.fileExtension == ".cs" ) { var fileContent = FilesSync.LoadUTF8( cf.fullPath ); var definitions = CSharpLexer.GetAllObjectDefinitions( fileContent ); RJLog.Log( cf.fileName, ">>", definitions.Join( "," ) ); for ( int i = 0; i < definitions.Count; i++ ) { var sequence = definitions[ i ]; var definitionType = sequence[ 0 ]; var definitionName = sequence[ 1 ]; RJLog.Log( "Adding definition:", definitionName.match ); AddCSharpsClassType( cf, definitionName.match, definitionType.match, namespaceLabel, assembly ); } } else if ( cf.fileExtension == ".gdshader" || cf.fileExtension == ".gdshaderinc" ) { var shaderType = new ShaderTypeEntry(); shaderType.path = cf.absolutePath; shaderTypes.Add( shaderType ); RJLog.Log( "SHADER: Adding definition:", cf.absolutePath ); } } ); } void AddCSharpsClassType( FilePath cf, string name, string definitionType, string namespaceLabel, System.Reflection.Assembly assembly ) { // var name = cf.fileName; var type = ReflectionHelper.GetTypeByName( namespaceLabel + "." + name ); if ( type == null ) { type = ReflectionHelper.GetTypeByNameFromAssembly( name, assembly ); } if ( type == null ) { return; } var entry = new ClassTypeEntry(); entry.type = type; entry.path = cf.fullPath; entry.definitionType = definitionType; classTypes.Add( entry); } void GenerateDocsFromTypes() { FilesSync.EnsureDirectoryExists( outputPath ); classTypes.ForEach( ( c )=> { var cdg = new ClassDocGenerator(); var cinfo = cdg.Create( c.path, c.type, c.definitionType, icons ); var outputPathName = cinfo.name.Replace( "`", "-" ).Replace( "<", "-" ).Replace( ">", "-" ); var outputPath = FilePath.Join( this.outputPath, outputPathName + ".json" ); FilesSync.SaveJSON( outputPath, cinfo ); } ); RJLog.Log( "SHADER: shaderTypes", shaderTypes.Count ); shaderTypes.ForEach( ( s ) => { try { RJLog.Log( "SHADER: DOC", s.path ); var sdg = new ShaderDocGenerator(); var cinfo = sdg.Create( s.path ); var prefix = cinfo.definitionType + "." ; var outputPathName = prefix + cinfo.name; var outputPath = FilePath.Join( this.outputPath, outputPathName + ".json" ); RJLog.Log( "SHADER: SAVING", s.path, ">>", outputPathName ); FilesSync.SaveJSON( outputPath, cinfo ); } catch ( System.Exception e ) { RJLog.Error( s.path ); RJLog.Error( e ); } } ); } } }