如何在Visual Studio中统计IIncrementalGenerator生成代码的SLOC?
统计IIncrementalGenerator生成代码的SLOC方案
针对你需要区分手写代码与Roslyn增量生成代码的SLOC统计需求,这里有几个实用的落地方法:
1. 自定义Roslyn生成过程统计
直接在你的IIncrementalGenerator实现中嵌入行数统计逻辑:
- 在生成代码后,遍历输出的
SyntaxTree,通过GetText().Lines获取所有行,过滤空行、仅含注释的行,统计有效代码行数。 - 将统计结果写入项目目录下的日志或文本文件,每次生成后累加更新,最终汇总所有生成代码的SLOC。
- 核心代码片段:
public void Initialize(IncrementalGeneratorInitializationContext context) { // 你的生成逻辑... context.RegisterSourceOutput(source, (spc, output) => { var syntaxTree = output.SyntaxTree; var validLineCount = syntaxTree.GetText().Lines.Count(line => !string.IsNullOrWhiteSpace(line.ToString()) && !line.ToString().TrimStart().StartsWith("//") && !line.ToString().TrimStart().StartsWith("/*")); // 写入统计文件,可根据需求调整存储格式 File.AppendAllText("generated_sloc.log", $"{syntaxTree.FilePath}: {validLineCount}\n"); }); }
2. 用MSBuild任务单独统计生成文件
Roslyn增量生成的代码默认存放在项目obj/[Configuration]/Generated目录下(如obj/Debug/net8.0/Generated),可通过自定义MSBuild任务统计这些文件的行数:
- 在项目csproj文件中添加构建后目标,遍历生成目录下的.cs文件并统计有效行数。
- 示例MSBuild配置:
<Target Name="CountGeneratedSLOC" AfterTargets="CoreCompile"> <ItemGroup> <GeneratedFiles Include="$(IntermediateOutputPath)Generated\**\*.cs" /> </ItemGroup> <ReadLinesFromFile File="@(GeneratedFiles)" > <Output TaskParameter="Lines" ItemName="AllLines" /> </ReadLinesFromFile> <PropertyGroup> <GeneratedSLOC>$([System.Linq.Enumerable]::Count($(AllLines), l => !string.IsNullOrWhiteSpace(l) and not l.TrimStart().StartsWith('//') and not l.TrimStart().StartsWith('/*')))</GeneratedSLOC> </PropertyGroup> <Message Text="Generated SLOC: $(GeneratedSLOC)" Importance="High" /> <WriteLinesToFile File="generated_sloc_summary.txt" Lines="Generated SLOC: $(GeneratedSLOC)" Overwrite="true" /> </Target>
3. 过滤VS Code Metrics的输出结果
如果已经在用VS Code Metrics,可以通过文件路径筛选分离生成代码的统计:
- 运行Metrics时指定仅分析
obj目录下的生成文件,或先统计所有代码,再用脚本从结果中提取生成文件的行数。 - 示例PowerShell脚本片段:
# 假设Metrics输出为metrics.json格式 $metricsData = Get-Content "metrics.json" | ConvertFrom-Json $generatedTotalSLOC = ($metricsData.Where({$_.FilePath -like "*obj\Generated*"})).Sum({$_.LinesOfCode}) Write-Host "Generated SLOC: $generatedTotalSLOC"
4. 利用生成代码的专属注释标记
在生成的代码开头统一添加特定注释(如// <auto-generated>),再用工具扫描所有.cs文件统计符合标记的文件行数:
- 生成代码时添加头部注释:
var sourceText = SourceText.From($@"// <auto-generated> {generatedCodeContent}", Encoding.UTF8);
- 用PowerShell批量统计:
$generatedFiles = Get-ChildItem -Recurse -Filter *.cs | Where-Object { Get-Content $_.FullName -TotalCount 5 | Select-String -Pattern "<auto-generated>" } $totalGeneratedSLOC = 0 foreach ($file in $generatedFiles) { $validLines = Get-Content $file.FullName | Where-Object { !string.IsNullOrWhiteSpace($_) -and !$_.TrimStart().StartsWith("//") -and !$_.TrimStart().StartsWith("/*") } $totalGeneratedSLOC += $validLines.Count } Write-Host "Total Generated SLOC: $totalGeneratedSLOC"
内容的提问来源于stack exchange,提问作者Kevin Krumwiede
相关产品推荐
相关产品推荐

