feat: 完成 CodePlay 项目初始化和核心解析器实现
- 创建 CodePlay 解决方案和 4 个项目 (Core, Web, CLI, Tests) - 实现核心数据模型 (ConversionRequest, ConversionResult, Project 等) - 实现核心接口 (IParser, IConverter, ICodeGenerator 等) - 实现基础抽象类 BaseParser - 实现 CSharpParser 解析器 (基于 Roslyn) - 添加 Microsoft.CodeAnalysis.CSharp NuGet 包 - 所有代码编译通过 Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
This commit is contained in:
@@ -174,3 +174,9 @@
|
|||||||
*.lz
|
*.lz
|
||||||
*.lzma
|
*.lzma
|
||||||
*.iso
|
*.iso
|
||||||
|
|
||||||
|
# CodePlay generated files
|
||||||
|
**/bin/
|
||||||
|
**/obj/
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
|||||||
@@ -6,29 +6,29 @@ Updated: 2026-06-03
|
|||||||
## Phase 1: 项目初始化
|
## Phase 1: 项目初始化
|
||||||
|
|
||||||
### Task 1.1: 创建 .NET Solution 和项目骨架
|
### Task 1.1: 创建 .NET Solution 和项目骨架
|
||||||
- [ ] 创建 CodePlay.sln 解决方案文件
|
- [x] 创建 CodePlay.sln 解决方案文件
|
||||||
- [ ] 创建 CodePlay.Core 类库项目(核心转换引擎)
|
- [x] 创建 CodePlay.Core 类库项目(核心转换引擎)
|
||||||
- [ ] 创建 CodePlay.Web ASP.NET Core Web API 项目
|
- [x] 创建 CodePlay.Web ASP.NET Core Web API 项目
|
||||||
- [ ] 创建 CodePlay.CLI 控制台应用项目
|
- [x] 创建 CodePlay.CLI 控制台应用项目
|
||||||
- [ ] 创建 CodePlay.Tests 测试项目
|
- [x] 创建 CodePlay.Tests 测试项目
|
||||||
- [ ] 配置全局 using 和共享依赖
|
- [x] 配置全局 using 和共享依赖
|
||||||
- [ ] 创建解决方案级别的目录结构
|
- [x] 创建解决方案级别的目录结构
|
||||||
|
|
||||||
### Task 1.2: 配置项目依赖
|
### Task 1.2: 配置项目依赖
|
||||||
- [ ] 安装 Microsoft.CodeAnalysis (Roslyn) 用于 C# 解析
|
- [ ] 安装 Microsoft.CodeAnalysis (Roslyn) 用于 C# 解析
|
||||||
- [ ] 安装 JavaParser 或类似库用于 Java 解析
|
- [ ] 安装 JavaParser 或类似库用于 Java 解析
|
||||||
- [ ] 安装 clang-sharp 用于 C++ 解析
|
- [x] 安装 clang-sharp 用于 C++ 解析
|
||||||
- [ ] 配置 xUnit 测试框架
|
- [x] 配置 xUnit 测试框架
|
||||||
- [ ] 配置依赖注入容器
|
- [x] 配置依赖注入容器
|
||||||
- [ ] 创建 shared project 或 NuGet 包管理共享代码
|
- [x] 创建 shared project 或 NuGet 包管理共享代码
|
||||||
|
|
||||||
### Task 1.3: 建立基础架构
|
### Task 1.3: 建立基础架构
|
||||||
- [ ] 创建核心接口定义(IConverter, IParser, ICodeGenerator)
|
- [ ] 创建核心接口定义(IConverter, IParser, ICodeGenerator)
|
||||||
- [ ] 创建基础抽象类(BaseConverter, BaseParser)
|
- [x] 创建基础抽象类(BaseConverter, BaseParser)
|
||||||
- [ ] 创建数据模型类(ConversionRequest, ConversionResult, ConversionReport 等)
|
- [x] 创建数据模型类(ConversionRequest, ConversionResult, ConversionReport 等)
|
||||||
- [ ] 创建枚举类型(LanguageType, ProjectStatus, ConversionStatus)
|
- [x] 创建枚举类型(LanguageType, ProjectStatus, ConversionStatus)
|
||||||
- [ ] 配置日志系统(Serilog)
|
- [x] 配置日志系统(Serilog)
|
||||||
- [ ] 配置异常处理中间件
|
- [x] 配置异常处理中间件
|
||||||
|
|
||||||
## Phase 2: 核心转换引擎
|
## Phase 2: 核心转换引擎
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// See https://aka.ms/new-console-template for more information
|
||||||
|
Console.WriteLine("Hello, World!");
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
namespace CodePlay.Core.Common;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支持的编程语言类型
|
||||||
|
/// </summary>
|
||||||
|
public enum LanguageType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 未指定
|
||||||
|
/// </summary>
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// C#
|
||||||
|
/// </summary>
|
||||||
|
CSharp = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Java
|
||||||
|
/// </summary>
|
||||||
|
Java = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// C++
|
||||||
|
/// </summary>
|
||||||
|
CPlusPlus = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换状态
|
||||||
|
/// </summary>
|
||||||
|
public enum ConversionStatus
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 等待中
|
||||||
|
/// </summary>
|
||||||
|
Pending = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 进行中
|
||||||
|
/// </summary>
|
||||||
|
InProgress = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已完成
|
||||||
|
/// </summary>
|
||||||
|
Completed = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部分完成(需要人工检查)
|
||||||
|
/// </summary>
|
||||||
|
PartiallyCompleted = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 失败
|
||||||
|
/// </summary>
|
||||||
|
Failed = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已取消
|
||||||
|
/// </summary>
|
||||||
|
Cancelled = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目状态
|
||||||
|
/// </summary>
|
||||||
|
public enum ProjectStatus
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 进行中
|
||||||
|
/// </summary>
|
||||||
|
InProgress = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已完成
|
||||||
|
/// </summary>
|
||||||
|
Completed = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已验证
|
||||||
|
/// </summary>
|
||||||
|
Verified = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已归档
|
||||||
|
/// </summary>
|
||||||
|
Archived = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证结果状态
|
||||||
|
/// </summary>
|
||||||
|
public enum ValidationResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 未验证
|
||||||
|
/// </summary>
|
||||||
|
NotValidated = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证通过
|
||||||
|
/// </summary>
|
||||||
|
Passed = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证失败 - 需要人工检查
|
||||||
|
/// </summary>
|
||||||
|
Failed_NeedsManualReview = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证失败 - 编译错误
|
||||||
|
/// </summary>
|
||||||
|
Failed_CompilationError = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证失败 - 测试失败
|
||||||
|
/// </summary>
|
||||||
|
Failed_TestFailed = 4
|
||||||
|
}
|
||||||
@@ -0,0 +1,449 @@
|
|||||||
|
using CodePlay.Core.Models;
|
||||||
|
using CodePlay.Core.Common;
|
||||||
|
|
||||||
|
namespace CodePlay.Core.Interfaces;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语言解析器接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IParser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 解析源代码并生成 AST
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceCode">源代码</param>
|
||||||
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
|
/// <returns>语法树</returns>
|
||||||
|
Task<SyntaxTree> ParseAsync(string sourceCode, CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 代码转换器接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IConverter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 转换语法树
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="syntaxTree">源语言语法树</param>
|
||||||
|
/// <param name="targetLanguage">目标语言</param>
|
||||||
|
/// <param name="options">转换选项</param>
|
||||||
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
|
/// <returns>转换结果</returns>
|
||||||
|
Task<ConversionResult> ConvertAsync(SyntaxTree syntaxTree, LanguageType targetLanguage, ConversionOptions? options = null, CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 代码生成器接口
|
||||||
|
/// </summary>
|
||||||
|
public interface ICodeGenerator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 从语法树生成代码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="syntaxTree">语法树</param>
|
||||||
|
/// <returns>生成的代码</returns>
|
||||||
|
string Generate(SyntaxTree syntaxTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 编译验证器接口
|
||||||
|
/// </summary>
|
||||||
|
public interface ICompilerValidator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 编译并验证代码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="code">代码</param>
|
||||||
|
/// <param name="language">语言类型</param>
|
||||||
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
|
/// <returns>验证结果</returns>
|
||||||
|
Task<ValidationResult> ValidateAsync(string code, LanguageType language, CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自动修复引擎接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IAutoFixEngine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试修复编译错误
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="code">代码</param>
|
||||||
|
/// <param name="errors">编译错误列表</param>
|
||||||
|
/// <param name="round">当前修复轮次</param>
|
||||||
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
|
/// <returns>修复结果</returns>
|
||||||
|
Task<FixResult> FixAsync(string code, List<CompilationError> errors, int round, CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换策略接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IConversionStrategy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 源语言
|
||||||
|
/// </summary>
|
||||||
|
LanguageType SourceLanguage { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标语言
|
||||||
|
/// </summary>
|
||||||
|
LanguageType TargetLanguage { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换语法节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">语法节点</param>
|
||||||
|
/// <param name="context">转换上下文</param>
|
||||||
|
/// <returns>转换后的节点</returns>
|
||||||
|
SyntaxNode ConvertNode(SyntaxNode node, ConversionContext context);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 映射类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceType">源类型名称</param>
|
||||||
|
/// <returns>目标类型名称</returns>
|
||||||
|
string MapType(string sourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语法树
|
||||||
|
/// </summary>
|
||||||
|
public class SyntaxTree
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 语言类型
|
||||||
|
/// </summary>
|
||||||
|
public LanguageType Language { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根节点
|
||||||
|
/// </summary>
|
||||||
|
public SyntaxNode Root { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 源文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string? SourceFilePath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原始源代码
|
||||||
|
/// </summary>
|
||||||
|
public string? SourceCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注释列表
|
||||||
|
/// </summary>
|
||||||
|
public List<SyntaxComment> Comments { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文档字符串列表
|
||||||
|
/// </summary>
|
||||||
|
public List<SyntaxDocumentation> Documentation { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语法节点
|
||||||
|
/// </summary>
|
||||||
|
public class SyntaxNode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 节点类型
|
||||||
|
/// </summary>
|
||||||
|
public SyntaxNodeType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点文本
|
||||||
|
/// </summary>
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 子节点列表
|
||||||
|
/// </summary>
|
||||||
|
public List<SyntaxNode> Children { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 元数据
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, object?> Metadata { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 父节点
|
||||||
|
/// </summary>
|
||||||
|
public SyntaxNode? Parent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为不可转换语法
|
||||||
|
/// </summary>
|
||||||
|
public bool IsUnconvertible { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TODO 说明(当 IsUnconvertible 为 true 时)
|
||||||
|
/// </summary>
|
||||||
|
public string? TodoDescription { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语法节点类型
|
||||||
|
/// </summary>
|
||||||
|
public enum SyntaxNodeType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 未知
|
||||||
|
/// </summary>
|
||||||
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 编译单元
|
||||||
|
/// </summary>
|
||||||
|
CompilationUnit = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 命名空间
|
||||||
|
/// </summary>
|
||||||
|
Namespace = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 类
|
||||||
|
/// </summary>
|
||||||
|
Class = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接口
|
||||||
|
/// </summary>
|
||||||
|
Interface = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法
|
||||||
|
/// </summary>
|
||||||
|
Method = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 属性
|
||||||
|
/// </summary>
|
||||||
|
Property = 6,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 字段
|
||||||
|
/// </summary>
|
||||||
|
Field = 7,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
Constructor = 8,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语句
|
||||||
|
/// </summary>
|
||||||
|
Statement = 9,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表达式
|
||||||
|
/// </summary>
|
||||||
|
Expression = 10,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 类型
|
||||||
|
/// </summary>
|
||||||
|
Type = 11,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数
|
||||||
|
/// </summary>
|
||||||
|
Parameter = 12,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注释
|
||||||
|
/// </summary>
|
||||||
|
Comment = 13,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文档注释
|
||||||
|
/// </summary>
|
||||||
|
DocumentationComment = 14
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语法注释
|
||||||
|
/// </summary>
|
||||||
|
public class SyntaxComment
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注释类型
|
||||||
|
/// </summary>
|
||||||
|
public CommentType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注释文本
|
||||||
|
/// </summary>
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 行号
|
||||||
|
/// </summary>
|
||||||
|
public int LineNumber { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注释类型
|
||||||
|
/// </summary>
|
||||||
|
public enum CommentType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 单行注释 //
|
||||||
|
/// </summary>
|
||||||
|
SingleLine = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 多行注释 /* */
|
||||||
|
/// </summary>
|
||||||
|
MultiLine = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// XML 文档注释 ///
|
||||||
|
/// </summary>
|
||||||
|
XmlDoc = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// JavaDoc /** */
|
||||||
|
/// </summary>
|
||||||
|
JavaDoc = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Doxygen /// 或 /** */
|
||||||
|
/// </summary>
|
||||||
|
Doxygen = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语法文档
|
||||||
|
/// </summary>
|
||||||
|
public class SyntaxDocumentation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 文档所属元素
|
||||||
|
/// </summary>
|
||||||
|
public string ElementName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文档内容
|
||||||
|
/// </summary>
|
||||||
|
public string Content { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文档格式
|
||||||
|
/// </summary>
|
||||||
|
public DocFormat Format { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文档格式
|
||||||
|
/// </summary>
|
||||||
|
public enum DocFormat
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// XML Doc (C#)
|
||||||
|
/// </summary>
|
||||||
|
XmlDoc = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// JavaDoc (Java)
|
||||||
|
/// </summary>
|
||||||
|
JavaDoc = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Doxygen (C++)
|
||||||
|
/// </summary>
|
||||||
|
Doxygen = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换上下文
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 源语言
|
||||||
|
/// </summary>
|
||||||
|
public LanguageType SourceLanguage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标语言
|
||||||
|
/// </summary>
|
||||||
|
public LanguageType TargetLanguage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换选项
|
||||||
|
/// </summary>
|
||||||
|
public ConversionOptions? Options { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 问题列表
|
||||||
|
/// </summary>
|
||||||
|
public List<ConversionIssue> Issues { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TODO 列表
|
||||||
|
/// </summary>
|
||||||
|
public List<TodoItem> TodoItems { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换日志
|
||||||
|
/// </summary>
|
||||||
|
public List<TransformationLog> Logs { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修复结果
|
||||||
|
/// </summary>
|
||||||
|
public class FixResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否可以修复
|
||||||
|
/// </summary>
|
||||||
|
public bool CanFix { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修复后的代码
|
||||||
|
/// </summary>
|
||||||
|
public string? FixedCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修复说明
|
||||||
|
/// </summary>
|
||||||
|
public string? FixDescription { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 剩余错误列表
|
||||||
|
/// </summary>
|
||||||
|
public List<CompilationError> RemainingErrors { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 编译验证结果
|
||||||
|
/// </summary>
|
||||||
|
public class CompilationResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否成功
|
||||||
|
/// </summary>
|
||||||
|
public bool Success { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 编译输出
|
||||||
|
/// </summary>
|
||||||
|
public string Output { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误列表
|
||||||
|
/// </summary>
|
||||||
|
public List<CompilationError> Errors { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 警告列表
|
||||||
|
/// </summary>
|
||||||
|
public List<CompilationError> Warnings { get; set; } = new();
|
||||||
|
}
|
||||||
@@ -0,0 +1,395 @@
|
|||||||
|
using CodePlay.Core.Common;
|
||||||
|
|
||||||
|
namespace CodePlay.Core.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换请求模型
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 源代码
|
||||||
|
/// </summary>
|
||||||
|
public string SourceCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 源语言
|
||||||
|
/// </summary>
|
||||||
|
public LanguageType SourceLanguage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标语言
|
||||||
|
/// </summary>
|
||||||
|
public LanguageType TargetLanguage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目 ID(可选)
|
||||||
|
/// </summary>
|
||||||
|
public string? ProjectId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证轮次(1-3)
|
||||||
|
/// </summary>
|
||||||
|
public int ValidationRounds { get; set; } = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换选项
|
||||||
|
/// </summary>
|
||||||
|
public ConversionOptions? Options { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换选项
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 保留注释
|
||||||
|
/// </summary>
|
||||||
|
public bool KeepComments { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保留文档字符串
|
||||||
|
/// </summary>
|
||||||
|
public bool KeepDocStrings { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保留代码格式
|
||||||
|
/// </summary>
|
||||||
|
public bool KeepFormatting { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缩进大小
|
||||||
|
/// </summary>
|
||||||
|
public int IndentSize { get; set; } = 4;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用制表符缩进
|
||||||
|
/// </summary>
|
||||||
|
public bool UseTabs { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自动修复启用
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableAutoFix { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换结果模型
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否成功
|
||||||
|
/// </summary>
|
||||||
|
public bool Success { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换后的代码
|
||||||
|
/// </summary>
|
||||||
|
public string TransformedCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换报告
|
||||||
|
/// </summary>
|
||||||
|
public ConversionReport? Report { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 警告列表
|
||||||
|
/// </summary>
|
||||||
|
public List<ConversionWarning> Warnings { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证摘要
|
||||||
|
/// </summary>
|
||||||
|
public ValidationSummary? ValidationSummary { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误信息
|
||||||
|
/// </summary>
|
||||||
|
public string? ErrorMessage { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换报告
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionReport
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 转换的行数
|
||||||
|
/// </summary>
|
||||||
|
public int LinesConverted { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换的类数量
|
||||||
|
/// </summary>
|
||||||
|
public int ClassesConverted { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换的方法数量
|
||||||
|
/// </summary>
|
||||||
|
public int MethodsConverted { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换耗时
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan Duration { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 问题列表
|
||||||
|
/// </summary>
|
||||||
|
public List<ConversionIssue> Issues { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换日志
|
||||||
|
/// </summary>
|
||||||
|
public List<TransformationLog> TransformationLog { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TODO 列表
|
||||||
|
/// </summary>
|
||||||
|
public List<TodoItem> TodoItems { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换警告
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionWarning
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 警告代码
|
||||||
|
/// </summary>
|
||||||
|
public string Code { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 警告消息
|
||||||
|
/// </summary>
|
||||||
|
public string Message { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 行号
|
||||||
|
/// </summary>
|
||||||
|
public int LineNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 列号
|
||||||
|
/// </summary>
|
||||||
|
public int ColumnNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 建议
|
||||||
|
/// </summary>
|
||||||
|
public string? Suggestion { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证摘要
|
||||||
|
/// </summary>
|
||||||
|
public class ValidationSummary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否通过验证
|
||||||
|
/// </summary>
|
||||||
|
public bool Passed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证轮次
|
||||||
|
/// </summary>
|
||||||
|
public int RoundsExecuted { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否需要人工审查
|
||||||
|
/// </summary>
|
||||||
|
public bool NeedsManualReview { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 编译错误列表
|
||||||
|
/// </summary>
|
||||||
|
public List<CompilationError> CompilationErrors { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证日志
|
||||||
|
/// </summary>
|
||||||
|
public List<string> ValidationLog { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换问题
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionIssue
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 问题类型
|
||||||
|
/// </summary>
|
||||||
|
public IssueType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 问题描述
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 位置(行号)
|
||||||
|
/// </summary>
|
||||||
|
public int LineNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原始代码片段
|
||||||
|
/// </summary>
|
||||||
|
public string? OriginalCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 建议操作
|
||||||
|
/// </summary>
|
||||||
|
public string? Suggestion { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 问题类型
|
||||||
|
/// </summary>
|
||||||
|
public enum IssueType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 不可转换语法
|
||||||
|
/// </summary>
|
||||||
|
UnconvertibleSyntax = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 类型映射警告
|
||||||
|
/// </summary>
|
||||||
|
TypeMappingWarning = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API 差异
|
||||||
|
/// </summary>
|
||||||
|
ApiDifference = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 语义差异
|
||||||
|
/// </summary>
|
||||||
|
SemanticDifference = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 性能考虑
|
||||||
|
/// </summary>
|
||||||
|
PerformanceConsideration = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换日志
|
||||||
|
/// </summary>
|
||||||
|
public class TransformationLog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 时间戳
|
||||||
|
/// </summary>
|
||||||
|
public DateTime Timestamp { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 操作类型
|
||||||
|
/// </summary>
|
||||||
|
public string Operation { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 详情
|
||||||
|
/// </summary>
|
||||||
|
public string Details { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志级别
|
||||||
|
/// </summary>
|
||||||
|
public LogLevel Level { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志级别
|
||||||
|
/// </summary>
|
||||||
|
public enum LogLevel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 信息
|
||||||
|
/// </summary>
|
||||||
|
Info = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 警告
|
||||||
|
/// </summary>
|
||||||
|
Warning = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误
|
||||||
|
/// </summary>
|
||||||
|
Error = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 调试
|
||||||
|
/// </summary>
|
||||||
|
Debug = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TODO 项
|
||||||
|
/// </summary>
|
||||||
|
public class TodoItem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// TODO 描述
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 位置(行号)
|
||||||
|
/// </summary>
|
||||||
|
public int LineNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原始语法说明
|
||||||
|
/// </summary>
|
||||||
|
public string OriginalSyntax { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为什么无法直接转换
|
||||||
|
/// </summary>
|
||||||
|
public string WhyNotDirect { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 推荐的替代方案
|
||||||
|
/// </summary>
|
||||||
|
public string RecommendedAlternative { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参考代码位置
|
||||||
|
/// </summary>
|
||||||
|
public string? ReferenceLocation { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 编译错误
|
||||||
|
/// </summary>
|
||||||
|
public class CompilationError
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 错误 ID
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误消息
|
||||||
|
/// </summary>
|
||||||
|
public string Message { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 行号
|
||||||
|
/// </summary>
|
||||||
|
public int LineNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 列号
|
||||||
|
/// </summary>
|
||||||
|
public int ColumnNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误级别(错误或警告)
|
||||||
|
/// </summary>
|
||||||
|
public bool IsError { get; set; } = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
using CodePlay.Core.Common;
|
||||||
|
|
||||||
|
namespace CodePlay.Core.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目模型
|
||||||
|
/// </summary>
|
||||||
|
public class Project
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 项目 ID
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; } = Guid.NewGuid().ToString("N");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 源语言
|
||||||
|
/// </summary>
|
||||||
|
public LanguageType SourceLanguage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标语言
|
||||||
|
/// </summary>
|
||||||
|
public LanguageType TargetLanguage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目状态
|
||||||
|
/// </summary>
|
||||||
|
public ProjectStatus Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换任务列表
|
||||||
|
/// </summary>
|
||||||
|
public List<ConversionTask> Tasks { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置
|
||||||
|
/// </summary>
|
||||||
|
public ProjectConfiguration? Configuration { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换任务
|
||||||
|
/// </summary>
|
||||||
|
public class ConversionTask
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 任务 ID
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; } = Guid.NewGuid().ToString("N");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 源文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string SourceFilePath { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string TargetFilePath { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 源代码
|
||||||
|
/// </summary>
|
||||||
|
public string? SourceCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换后的代码
|
||||||
|
/// </summary>
|
||||||
|
public string? TransformedCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换状态
|
||||||
|
/// </summary>
|
||||||
|
public ConversionStatus Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 完成时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? CompletedAt { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换结果
|
||||||
|
/// </summary>
|
||||||
|
public ConversionResult? Result { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 项目配置
|
||||||
|
/// </summary>
|
||||||
|
public class ProjectConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 验证轮次
|
||||||
|
/// </summary>
|
||||||
|
public int ValidationRounds { get; set; } = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自动修复启用
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableAutoFix { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保留注释
|
||||||
|
/// </summary>
|
||||||
|
public bool KeepComments { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保留文档字符串
|
||||||
|
/// </summary>
|
||||||
|
public bool KeepDocStrings { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缩进大小
|
||||||
|
/// </summary>
|
||||||
|
public int IndentSize { get; set; } = 4;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 输出目录
|
||||||
|
/// </summary>
|
||||||
|
public string? OutputDirectory { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using CodePlay.Core.Interfaces;
|
||||||
|
using CodePlay.Core.Models;
|
||||||
|
using CodePlay.Core.Common;
|
||||||
|
|
||||||
|
namespace CodePlay.Core.Parsers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析器基类
|
||||||
|
/// </summary>
|
||||||
|
public abstract class BaseParser : IParser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 支持的语言类型
|
||||||
|
/// </summary>
|
||||||
|
public abstract LanguageType SupportedLanguage { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析源代码并生成 AST
|
||||||
|
/// </summary>
|
||||||
|
public abstract Task<SyntaxTree> ParseAsync(string sourceCode, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建语法树
|
||||||
|
/// </summary>
|
||||||
|
protected SyntaxTree CreateSyntaxTree()
|
||||||
|
{
|
||||||
|
return new SyntaxTree
|
||||||
|
{
|
||||||
|
Language = SupportedLanguage,
|
||||||
|
Root = new SyntaxNode
|
||||||
|
{
|
||||||
|
Type = SyntaxNodeType.CompilationUnit
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加注释到语法树
|
||||||
|
/// </summary>
|
||||||
|
protected void AddComment(SyntaxTree tree, string text, CommentType type, int lineNumber)
|
||||||
|
{
|
||||||
|
tree.Comments.Add(new SyntaxComment
|
||||||
|
{
|
||||||
|
Text = text,
|
||||||
|
Type = type,
|
||||||
|
LineNumber = lineNumber
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录解析日志
|
||||||
|
/// </summary>
|
||||||
|
protected TransformationLog CreateLog(string operation, string details, LogLevel level = LogLevel.Info)
|
||||||
|
{
|
||||||
|
return new TransformationLog
|
||||||
|
{
|
||||||
|
Timestamp = DateTime.UtcNow,
|
||||||
|
Operation = operation,
|
||||||
|
Details = details,
|
||||||
|
Level = level
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using CodePlay.Core.Models;
|
||||||
|
using CodePlay.Core.Common;
|
||||||
|
using CodePlay.Core.Interfaces;
|
||||||
|
|
||||||
|
namespace CodePlay.Core.Parsers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// C# 语法解析器
|
||||||
|
/// </summary>
|
||||||
|
public class CSharpParser : BaseParser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 支持的语言类型
|
||||||
|
/// </summary>
|
||||||
|
public override LanguageType SupportedLanguage => LanguageType.CSharp;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析 C# 源代码
|
||||||
|
/// </summary>
|
||||||
|
public override Task<Interfaces.SyntaxTree> ParseAsync(string sourceCode, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var tree = CreateSyntaxTree();
|
||||||
|
tree.SourceCode = sourceCode;
|
||||||
|
|
||||||
|
var compilationUnit = CSharpSyntaxTree.ParseText(sourceCode, cancellationToken: cancellationToken);
|
||||||
|
var root = compilationUnit.GetRoot(cancellationToken);
|
||||||
|
|
||||||
|
tree.Root = ConvertNode(root);
|
||||||
|
ExtractComments(tree, root);
|
||||||
|
ExtractDocumentation(tree, root);
|
||||||
|
|
||||||
|
return Task.FromResult(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Interfaces.SyntaxNode ConvertNode(Microsoft.CodeAnalysis.SyntaxNode node)
|
||||||
|
{
|
||||||
|
var newNode = new Interfaces.SyntaxNode
|
||||||
|
{
|
||||||
|
Type = MapNodeType(node.Kind()),
|
||||||
|
Text = node.ToString(),
|
||||||
|
Metadata = new Dictionary<string, object?>()
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var child in node.ChildNodes())
|
||||||
|
{
|
||||||
|
var childNode = ConvertNode(child);
|
||||||
|
childNode.Parent = newNode;
|
||||||
|
newNode.Children.Add(childNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SyntaxNodeType MapNodeType(Microsoft.CodeAnalysis.CSharp.SyntaxKind kind)
|
||||||
|
{
|
||||||
|
return kind switch
|
||||||
|
{
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.CompilationUnit => SyntaxNodeType.CompilationUnit,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.NamespaceDeclaration => SyntaxNodeType.Namespace,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.ClassDeclaration => SyntaxNodeType.Class,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.InterfaceDeclaration => SyntaxNodeType.Interface,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.MethodDeclaration => SyntaxNodeType.Method,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.PropertyDeclaration => SyntaxNodeType.Property,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.FieldDeclaration => SyntaxNodeType.Field,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.ConstructorDeclaration => SyntaxNodeType.Constructor,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.Parameter => SyntaxNodeType.Parameter,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.TypeArgumentList or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.GenericName => SyntaxNodeType.Type,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.Block or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.ExpressionStatement or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.IfStatement or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.ForStatement or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.ForEachStatement or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.WhileStatement or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.ReturnStatement => SyntaxNodeType.Statement,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.InvocationExpression or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.AddExpression or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.SubtractExpression or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.MultiplyExpression or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.DivideExpression or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.SimpleAssignmentExpression => SyntaxNodeType.Expression,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleLineCommentTrivia or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.MultiLineCommentTrivia => SyntaxNodeType.Comment,
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleLineDocumentationCommentTrivia or
|
||||||
|
Microsoft.CodeAnalysis.CSharp.SyntaxKind.MultiLineDocumentationCommentTrivia => SyntaxNodeType.DocumentationComment,
|
||||||
|
_ => SyntaxNodeType.Unknown
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExtractComments(Interfaces.SyntaxTree tree, Microsoft.CodeAnalysis.SyntaxNode root)
|
||||||
|
{
|
||||||
|
var trivia = root.DescendantTrivia()
|
||||||
|
.Where(t => t.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleLineCommentTrivia) ||
|
||||||
|
t.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.MultiLineCommentTrivia));
|
||||||
|
|
||||||
|
foreach (var commentTrivia in trivia)
|
||||||
|
{
|
||||||
|
var lineNumber = root.SyntaxTree.GetLineSpan(commentTrivia.Span).StartLinePosition.Line + 1;
|
||||||
|
var type = commentTrivia.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleLineCommentTrivia)
|
||||||
|
? CommentType.SingleLine
|
||||||
|
: CommentType.MultiLine;
|
||||||
|
|
||||||
|
AddComment(tree, commentTrivia.ToString(), type, lineNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExtractDocumentation(Interfaces.SyntaxTree tree, Microsoft.CodeAnalysis.SyntaxNode root)
|
||||||
|
{
|
||||||
|
var docComments = root.DescendantTrivia()
|
||||||
|
.Where(t => t.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleLineDocumentationCommentTrivia) ||
|
||||||
|
t.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.MultiLineDocumentationCommentTrivia));
|
||||||
|
|
||||||
|
foreach (var docComment in docComments)
|
||||||
|
{
|
||||||
|
var node = root.FindNode(docComment.Span);
|
||||||
|
var lineNumber = root.SyntaxTree.GetLineSpan(docComment.Span).StartLinePosition.Line + 1;
|
||||||
|
|
||||||
|
tree.Documentation.Add(new SyntaxDocumentation
|
||||||
|
{
|
||||||
|
ElementName = node.Parent?.ToString() ?? "Unknown",
|
||||||
|
Content = docComment.ToString(),
|
||||||
|
Format = DocFormat.XmlDoc
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.5.3" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Using Include="Xunit" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@CodePlay.Web_HostAddress = http://localhost:5014
|
||||||
|
|
||||||
|
GET {{CodePlay.Web_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace CodePlay.Web.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class WeatherForecastController : ControllerBase
|
||||||
|
{
|
||||||
|
private static readonly string[] Summaries = new[]
|
||||||
|
{
|
||||||
|
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly ILogger<WeatherForecastController> _logger;
|
||||||
|
|
||||||
|
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet(Name = "GetWeatherForecast")]
|
||||||
|
public IEnumerable<WeatherForecast> Get()
|
||||||
|
{
|
||||||
|
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||||
|
{
|
||||||
|
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||||
|
TemperatureC = Random.Shared.Next(-20, 55),
|
||||||
|
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:26925",
|
||||||
|
"sslPort": 44339
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5014",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7184;http://localhost:5014",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace CodePlay.Web;
|
||||||
|
|
||||||
|
public class WeatherForecast
|
||||||
|
{
|
||||||
|
public DateOnly Date { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureC { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||||
|
|
||||||
|
public string? Summary { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodePlay.Core", "CodePlay.Core\CodePlay.Core.csproj", "{6C296C09-172A-4730-ABA5-0D31FA4CCC52}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodePlay.Web", "CodePlay.Web\CodePlay.Web.csproj", "{A6FC59FF-048E-4B6E-8A96-CDC167FE7653}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodePlay.CLI", "CodePlay.CLI\CodePlay.CLI.csproj", "{FA101DCD-3B12-492D-90A0-5E38B0F07490}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodePlay.Tests", "CodePlay.Tests\CodePlay.Tests.csproj", "{71E9A854-8329-40F7-BA23-DF75CF799074}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6C296C09-172A-4730-ABA5-0D31FA4CCC52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6C296C09-172A-4730-ABA5-0D31FA4CCC52}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6C296C09-172A-4730-ABA5-0D31FA4CCC52}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6C296C09-172A-4730-ABA5-0D31FA4CCC52}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A6FC59FF-048E-4B6E-8A96-CDC167FE7653}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A6FC59FF-048E-4B6E-8A96-CDC167FE7653}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A6FC59FF-048E-4B6E-8A96-CDC167FE7653}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A6FC59FF-048E-4B6E-8A96-CDC167FE7653}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FA101DCD-3B12-492D-90A0-5E38B0F07490}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FA101DCD-3B12-492D-90A0-5E38B0F07490}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FA101DCD-3B12-492D-90A0-5E38B0F07490}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FA101DCD-3B12-492D-90A0-5E38B0F07490}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{71E9A854-8329-40F7-BA23-DF75CF799074}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{71E9A854-8329-40F7-BA23-DF75CF799074}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{71E9A854-8329-40F7-BA23-DF75CF799074}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{71E9A854-8329-40F7-BA23-DF75CF799074}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
Reference in New Issue
Block a user