feat: 实现 Task 3.2 Java 编译验证和 Task 4.4 前端代码编辑器
Task 3.2 - Java 编译验证: - JavaCompilerValidator: 使用 javac 进行编译验证 - 支持临时文件编译和清理 - 集成到 ICompilerValidator 接口 - 单元测试 (需要 javac 环境) Task 4.4 - 前端代码编辑器: - CodeEditor.vue: Monaco Editor 集成 - 支持 C#/Java/C++ 语法高亮 - 智能代码补全 (main 方法,System.out.println 等) - 支持主题切换 (vs-dark/vs/hc-black) - 支持只读模式、最小化地图、自动布局 - 暴露 API: setValue, getValue, focus, layout 测试状态: - 总测试数: 42 - 通过: 41 ✅ - 跳过: 1 (Java 编译器测试需要 javac 环境) 前端依赖: - 需安装 monaco-editor: npm install monaco-editor Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using CodePlay.Core.Models;
|
||||
using CodePlay.Core.Common;
|
||||
using CodePlay.Core.Interfaces;
|
||||
|
||||
namespace CodePlay.Core.Validators;
|
||||
|
||||
public class JavaCompilerValidator : ICompilerValidator
|
||||
{
|
||||
private readonly string _javaVersion;
|
||||
private readonly string? _classpath;
|
||||
|
||||
public JavaCompilerValidator(string javaVersion = "11", string? classpath = null)
|
||||
{
|
||||
_javaVersion = javaVersion;
|
||||
_classpath = classpath;
|
||||
}
|
||||
|
||||
public LanguageType SupportedLanguage => LanguageType.Java;
|
||||
|
||||
public async Task<ValidationSummary> ValidateAsync(string code, LanguageType language, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var summary = new ValidationSummary
|
||||
{
|
||||
Passed = false,
|
||||
RoundsExecuted = 1
|
||||
};
|
||||
|
||||
var javacPath = FindJavaCompiler();
|
||||
if (string.IsNullOrEmpty(javacPath))
|
||||
{
|
||||
summary.Passed = true;
|
||||
summary.NeedsManualReview = true;
|
||||
return summary;
|
||||
}
|
||||
|
||||
var tempFile = await CreateTempJavaFile(code);
|
||||
|
||||
try
|
||||
{
|
||||
var compileResult = await CompileJavaFile(javacPath, tempFile, cancellationToken);
|
||||
var hasErrors = !string.IsNullOrEmpty(compileResult.Error) && compileResult.Error.Contains(" error:");
|
||||
summary.Passed = !hasErrors;
|
||||
summary.NeedsManualReview = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CleanupTempFiles(tempFile);
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
private string? FindJavaCompiler()
|
||||
{
|
||||
var javaHome = Environment.GetEnvironmentVariable("JAVA_HOME");
|
||||
if (!string.IsNullOrEmpty(javaHome))
|
||||
{
|
||||
var javacPath = Path.Combine(javaHome, "bin", "javac");
|
||||
if (File.Exists(javacPath)) return javacPath;
|
||||
}
|
||||
|
||||
return "javac";
|
||||
}
|
||||
|
||||
private async Task<string> CreateTempJavaFile(string code)
|
||||
{
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), "codeplay_java_" + Guid.NewGuid().ToString("N")[..8]);
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var className = ExtractClassName(code) ?? "TempClass";
|
||||
var filePath = Path.Combine(tempDir, $"{className}.java");
|
||||
await File.WriteAllTextAsync(filePath, code);
|
||||
return filePath;
|
||||
}
|
||||
|
||||
private string? ExtractClassName(string code)
|
||||
{
|
||||
var match = Regex.Match(code, @"(?:public\s+)?class\s+(\w+)");
|
||||
return match.Success ? match.Groups[1].Value : null;
|
||||
}
|
||||
|
||||
private async Task<(string Output, string Error)> CompileJavaFile(
|
||||
string javacPath, string sourceFile, CancellationToken cancellationToken)
|
||||
{
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = javacPath,
|
||||
Arguments = $"-source {_javaVersion} -encoding UTF-8 \"{sourceFile}\"",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = startInfo };
|
||||
process.Start();
|
||||
|
||||
var output = await process.StandardOutput.ReadToEndAsync();
|
||||
var error = await process.StandardError.ReadToEndAsync();
|
||||
await process.WaitForExitAsync(cancellationToken);
|
||||
|
||||
return (output, error);
|
||||
}
|
||||
|
||||
private void CleanupTempFiles(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dir = Path.GetDirectoryName(filePath);
|
||||
if (Directory.Exists(dir)) Directory.Delete(dir, true);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user