Files
monkeycode-ai 2fcc22b501 PythonToCSharpConverter.cs:36 -- 移除未使用的 indentLevel 变量
Program.test.cs -- 将顶层语句改为 ManualTest.RunAsync() 方法,消除入口点冲突
BatchConversionService.cs:96 -- options 可空参数添加 ?? new ConversionOptions() 空值回退
Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
2026-06-16 17:06:24 +08:00

196 lines
7.7 KiB
C#

using CodePlay.Core.Models;
using CodePlay.Core.Common;
namespace CodePlay.Core.Services;
public interface IBatchConversionService
{
Task<BatchConversionResult> ConvertDirectoryAsync(string sourceDirectory, string targetDirectory,
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
CancellationToken cancellationToken = default);
Task<BatchConversionResult> ConvertFilesAsync(IEnumerable<string> sourceFiles, string targetDirectory,
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
CancellationToken cancellationToken = default);
}
public class BatchConversionService : IBatchConversionService
{
private readonly ConversionService _conversionService;
private readonly IReportStorageService _reportStorageService;
public BatchConversionService(ConversionService conversionService, IReportStorageService reportStorageService)
{
_conversionService = conversionService;
_reportStorageService = reportStorageService;
}
public async Task<BatchConversionResult> ConvertDirectoryAsync(string sourceDirectory, string targetDirectory,
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
CancellationToken cancellationToken = default)
{
var result = new BatchConversionResult
{
SourceDirectory = sourceDirectory,
TargetDirectory = targetDirectory,
SourceLanguage = sourceLanguage,
TargetLanguage = targetLanguage,
StartedAt = DateTime.UtcNow
};
if (!Directory.Exists(sourceDirectory))
{
result.Success = false;
result.ErrorMessage = $"Source directory not found: {sourceDirectory}";
return result;
}
var fileExtension = GetFileExtension(sourceLanguage);
var sourceFiles = Directory.GetFiles(sourceDirectory, $"*{fileExtension}", SearchOption.AllDirectories);
return await ConvertFilesAsync(sourceFiles, targetDirectory, sourceLanguage, targetLanguage, options, cancellationToken);
}
public async Task<BatchConversionResult> ConvertFilesAsync(IEnumerable<string> sourceFiles, string targetDirectory,
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
CancellationToken cancellationToken = default)
{
var result = new BatchConversionResult
{
TargetDirectory = targetDirectory,
SourceLanguage = sourceLanguage,
TargetLanguage = targetLanguage,
StartedAt = DateTime.UtcNow,
TotalFiles = sourceFiles.Count()
};
if (!Directory.Exists(targetDirectory))
{
Directory.CreateDirectory(targetDirectory);
}
var targetExtension = GetFileExtension(targetLanguage);
foreach (var sourceFile in sourceFiles)
{
if (cancellationToken.IsCancellationRequested)
{
result.CancelledAt = DateTime.UtcNow;
break;
}
try
{
var relativePath = Path.GetRelativePath(Path.GetDirectoryName(sourceFile)!, sourceFile);
var targetFileName = Path.ChangeExtension(relativePath, targetExtension);
var targetFilePath = Path.Combine(targetDirectory, targetFileName);
var targetFileDir = Path.GetDirectoryName(targetFilePath)!;
if (!Directory.Exists(targetFileDir))
{
Directory.CreateDirectory(targetFileDir);
}
var sourceCode = await File.ReadAllTextAsync(sourceFile, cancellationToken);
var conversionResult = await _conversionService.ConvertAsync(
sourceCode, sourceLanguage.ToName(), targetLanguage.ToName(), options ?? new ConversionOptions());
if (conversionResult.Success)
{
await File.WriteAllTextAsync(targetFilePath, conversionResult.TransformedCode, cancellationToken);
result.SuccessfulFiles++;
result.ConvertedFiles.Add(new ConvertedFileInfo
{
SourceFile = sourceFile,
TargetFile = targetFilePath,
LinesConverted = conversionResult.Report?.LinesConverted ?? 0,
ClassesConverted = conversionResult.Report?.ClassesConverted ?? 0,
MethodsConverted = conversionResult.Report?.MethodsConverted ?? 0,
Warnings = conversionResult.Warnings.Count,
Issues = conversionResult.Report?.Issues.Count ?? 0
});
if (conversionResult.Report != null)
{
conversionResult.Report.ProjectId = "batch-" + DateTime.UtcNow.ToString("yyyyMMdd");
await _reportStorageService.SaveReportAsync(conversionResult.Report);
}
}
else
{
result.FailedFiles++;
result.FailedFileList.Add(new FailedFileInfo
{
SourceFile = sourceFile,
ErrorMessage = conversionResult.ErrorMessage ?? "Unknown error"
});
}
}
catch (Exception ex)
{
result.FailedFiles++;
result.FailedFileList.Add(new FailedFileInfo
{
SourceFile = sourceFile,
ErrorMessage = ex.Message
});
}
}
result.CompletedAt = DateTime.UtcNow;
result.Duration = result.CompletedAt - result.StartedAt;
result.Success = result.FailedFiles == 0;
return result;
}
private string GetFileExtension(LanguageType language)
{
return language switch
{
LanguageType.CSharp => ".cs",
LanguageType.Java => ".java",
LanguageType.CPlusPlus => ".cpp",
_ => throw new ArgumentException($"Unsupported language: {language}")
};
}
}
public class BatchConversionResult
{
public bool Success { get; set; }
public string? ErrorMessage { get; set; }
public string SourceDirectory { get; set; } = string.Empty;
public string TargetDirectory { get; set; } = string.Empty;
public LanguageType SourceLanguage { get; set; }
public LanguageType TargetLanguage { get; set; }
public int TotalFiles { get; set; }
public int SuccessfulFiles { get; set; }
public int FailedFiles { get; set; }
public DateTime StartedAt { get; set; }
public DateTime? CompletedAt { get; set; }
public DateTime? CancelledAt { get; set; }
public TimeSpan? Duration { get; set; }
public List<ConvertedFileInfo> ConvertedFiles { get; set; } = new();
public List<FailedFileInfo> FailedFileList { get; set; } = new();
}
public class ConvertedFileInfo
{
public string SourceFile { get; set; } = string.Empty;
public string TargetFile { get; set; } = string.Empty;
public int LinesConverted { get; set; }
public int ClassesConverted { get; set; }
public int MethodsConverted { get; set; }
public int Warnings { get; set; }
public int Issues { get; set; }
}
public class FailedFileInfo
{
public string SourceFile { get; set; } = string.Empty;
public string? TargetFile { get; set; }
public string ErrorMessage { get; set; } = string.Empty;
}