74 lines
2.3 KiB
C#
74 lines
2.3 KiB
C#
using System.Text;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace ser;
|
|
|
|
public abstract class CodeGenerator
|
|
{
|
|
protected StringBuilder _sb = new StringBuilder();
|
|
protected int _indent = 0;
|
|
protected TypeStructureAnalyzer _analyzer;
|
|
protected CodeGenConfig _config;
|
|
protected HashSet<Type> _generatedTypes = new(); // Track to avoid re-generating
|
|
|
|
public CodeGenerator( CodeGenConfig config )
|
|
{
|
|
_config = config;
|
|
_analyzer = new TypeStructureAnalyzer( config );
|
|
}
|
|
|
|
// Main entry point
|
|
public string Generate( Type type, string ns = "GeneratedCode" )
|
|
{
|
|
_sb.Clear();
|
|
WriteLine( "using System;" );
|
|
WriteLine( "using System.Collections.Generic;" );
|
|
WriteLine( "using System.Linq;" );
|
|
WriteLine( "" );
|
|
WriteLine( $"namespace {ns};" );
|
|
WriteLine( "" );
|
|
GenerateForType( type );
|
|
return _sb.ToString();
|
|
}
|
|
|
|
// Core generation logic - needs to be recursive for dependencies
|
|
protected virtual void GenerateForType( Type type )
|
|
{
|
|
if( type == null || !CanGenerateFor( type ) || _generatedTypes.Contains( type ) )
|
|
return;
|
|
|
|
_generatedTypes.Add( type );
|
|
var info = _analyzer.Get( type );
|
|
|
|
// Generate dependencies first
|
|
foreach( var member in info.Members )
|
|
{
|
|
GenerateForType( member.Type );
|
|
if( member.IsCollection && member.CollectionElementType != null )
|
|
{
|
|
GenerateForType( member.CollectionElementType );
|
|
}
|
|
}
|
|
|
|
// Generate the actual code
|
|
GenerateClassHeader( info );
|
|
BeginBlock();
|
|
GenerateClassBody( info );
|
|
EndBlock();
|
|
}
|
|
|
|
// Abstract methods to be implemented by specific generators
|
|
protected abstract void GenerateClassHeader( TypeStructureInfo info );
|
|
protected abstract void GenerateClassBody( TypeStructureInfo info );
|
|
protected abstract bool CanGenerateFor( Type type ); // Check if we should generate for this type
|
|
|
|
// Helper methods
|
|
protected void WriteLine( string line = "" ) => _sb.AppendLine( new string( '\t', _indent ) + line );
|
|
protected void BeginBlock() { WriteLine( "{" ); _indent++; }
|
|
protected void EndBlock() { _indent--; WriteLine( "}" ); }
|
|
protected string GetTypeName( Type t ) => t.IsGenericType
|
|
? $"{t.Name.Split( '`' )[0]}<{string.Join( ", ", t.GetGenericArguments().Select( GetTypeName ) )}>"
|
|
: t.Name; // Basic handling, needs improvement for full names/namespaces
|
|
} |