using System.Text; using CodePlay.Core.Interfaces; using CodePlay.Core.Common; namespace CodePlay.Core.Converters; /// /// C# 代码生成器 /// public class CSharpCodeGenerator : ICodeGenerator { private readonly StringBuilder _output = new(); private int _indentLevel; /// /// 从语法树生成 C# 代码 /// public string Generate(Interfaces.SyntaxTree syntaxTree) { _output.Clear(); _indentLevel = 0; // 生成 using 指令 GenerateUsings(syntaxTree); // 生成代码 GenerateNode(syntaxTree.Root); return _output.ToString(); } private void GenerateUsings(Interfaces.SyntaxTree tree) { _output.AppendLine("using System;"); _output.AppendLine("using System.Collections.Generic;"); _output.AppendLine(); } private void GenerateNode(Interfaces.SyntaxNode node) { switch (node.Type) { case SyntaxNodeType.CompilationUnit: GenerateCompilationUnit(node); break; case SyntaxNodeType.Namespace: GenerateNamespace(node); break; case SyntaxNodeType.Class: GenerateClass(node); break; case SyntaxNodeType.Method: GenerateMethod(node); break; case SyntaxNodeType.Property: GenerateProperty(node); break; case SyntaxNodeType.Field: GenerateField(node); break; default: GenerateDefault(node); break; } } private void GenerateCompilationUnit(Interfaces.SyntaxNode node) { foreach (var child in node.Children) { GenerateNode(child); } } private void GenerateNamespace(Interfaces.SyntaxNode node) { var namespaceName = ExtractNamespaceName(node.Text); _output.AppendLine($"namespace {namespaceName}"); _output.AppendLine("{"); _indentLevel++; foreach (var child in node.Children) { if (child.Type != SyntaxNodeType.Unknown) { GenerateNode(child); } } _indentLevel--; _output.AppendLine("}"); _output.AppendLine(); } private void GenerateClass(Interfaces.SyntaxNode node) { var classDeclaration = node.Text.Split('{')[0].Trim(); _output.AppendLine(Indent(classDeclaration)); _output.AppendLine(Indent("{")); _indentLevel++; foreach (var child in node.Children) { if (child.Type != SyntaxNodeType.Unknown && child.Type != SyntaxNodeType.CompilationUnit) { GenerateNode(child); } } _indentLevel--; _output.AppendLine(Indent("}")); _output.AppendLine(); } private void GenerateMethod(Interfaces.SyntaxNode node) { var methodSignature = ExtractMethodSignature(node.Text); _output.AppendLine(Indent(methodSignature)); _output.AppendLine(Indent("{")); _indentLevel++; var methodBody = ExtractMethodBody(node.Text); if (!string.IsNullOrWhiteSpace(methodBody)) { var lines = methodBody.Split('\n'); foreach (var line in lines) { if (!string.IsNullOrWhiteSpace(line.Trim())) { _output.AppendLine(Indent(line.Trim())); } } } _indentLevel--; _output.AppendLine(Indent("}")); _output.AppendLine(); } private void GenerateProperty(Interfaces.SyntaxNode node) { var propertyDeclaration = node.Text.Trim(); if (!string.IsNullOrWhiteSpace(propertyDeclaration)) { _output.AppendLine(Indent(propertyDeclaration.EndsWith(";") ? propertyDeclaration : propertyDeclaration + ";")); } } private void GenerateField(Interfaces.SyntaxNode node) { var fieldDeclaration = node.Text.Trim(); if (!string.IsNullOrWhiteSpace(fieldDeclaration)) { _output.AppendLine(Indent(fieldDeclaration.EndsWith(";") ? fieldDeclaration : fieldDeclaration + ";")); } } private void GenerateDefault(Interfaces.SyntaxNode node) { if (!string.IsNullOrWhiteSpace(node.Text) && node.Type != SyntaxNodeType.Comment) { var lines = node.Text.Split('\n'); foreach (var line in lines) { var trimmed = line.Trim(); if (!string.IsNullOrWhiteSpace(trimmed) && trimmed != "{" && trimmed != "}") { _output.AppendLine(Indent(trimmed)); } } } foreach (var child in node.Children) { GenerateNode(child); } } private string Indent(string text) { var indent = new string(' ', _indentLevel * 4); return indent + text; } private string ExtractNamespaceName(string text) { if (text.StartsWith("namespace ")) { var match = System.Text.RegularExpressions.Regex.Match(text, @"namespace\s+([\w.]+)"); return match.Success ? match.Groups[1].Value : "CodePlay.Converted"; } return "CodePlay.Converted"; } private string ExtractMethodSignature(string text) { var lines = text.Split('\n'); foreach (var line in lines) { var trimmed = line.Trim(); if (trimmed.Length > 0 && !trimmed.StartsWith("{") && !trimmed.StartsWith("}") && (trimmed.Contains("(") || trimmed.Contains("void") || trimmed.Contains("public") || trimmed.Contains("private"))) { return trimmed.EndsWith("{") ? trimmed.Substring(0, trimmed.Length - 1).Trim() : trimmed; } } return text; } private string ExtractMethodBody(string text) { var startIndex = text.IndexOf('{'); var endIndex = text.LastIndexOf('}'); if (startIndex >= 0 && endIndex > startIndex) { return text.Substring(startIndex + 1, endIndex - startIndex - 1).Trim(); } return string.Empty; } }