使用 Roslyn 分析器检查源代码行是否超出行长度的最佳方法是什么?

发布于 2025-01-17 08:12:20 字数 87 浏览 4 评论 0原文

我想对代码线长度执行一些硬限制。

我应该使用什么Roslyn的API?

为每个语法节点注册操作并检查节点的位置似乎不是最有效的方法。

I'd like to enforce some hard limits to code line length.

What Roslyn's API should I use for it?

Registering action for every syntax node and checking node's location seems to be not the most efficient approach.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泛滥成性 2025-01-24 08:12:20

不完美的解决方案:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class LineMaxLengthAnalyzer : DiagnosticAnalyzer
{
    public const int LineMaxLength = 150;
    public const string DiagnosticId = nameof(LineMaxLengthAnalyzer);

    private static readonly LocalizableString Title = new LocalizableResourceString(
        nameof(Resources.LineMaxLengthAnalyzerTitle), Resources.ResourceManager, typeof(Resources));
    private static readonly LocalizableString MessageFormat = new LocalizableResourceString(
        nameof(Resources.LineMaxLengthAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
    private static readonly LocalizableString Description = new LocalizableResourceString(
        nameof(Resources.LineMaxLengthAnalyzerDescription), Resources.ResourceManager, typeof(Resources));
    private const string Category = "Readability";

    private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
        DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description);

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);

    public override void Initialize(AnalysisContext context)
    {
        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
        context.EnableConcurrentExecution();

        var nodeTypes = Enum.GetValues(typeof(SyntaxKind)).Cast<SyntaxKind>().ToArray();
        context.RegisterSyntaxTreeAction(VerifyLines);
    }

    private void VerifyLines(SyntaxTreeAnalysisContext context)
    {
        var text = context.Tree.GetText();
        text.Lines.Where(line => line.End - line.Start + 1 > LineMaxLength).ToList()
            .ForEach(line =>
            {
                var location = Location.Create(context.Tree, line.Span);
                var diagnostic = Diagnostic.Create(Rule, location, LineMaxLength);
                context.ReportDiagnostic(diagnostic);
            });
    }
}

Not perfect solution:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class LineMaxLengthAnalyzer : DiagnosticAnalyzer
{
    public const int LineMaxLength = 150;
    public const string DiagnosticId = nameof(LineMaxLengthAnalyzer);

    private static readonly LocalizableString Title = new LocalizableResourceString(
        nameof(Resources.LineMaxLengthAnalyzerTitle), Resources.ResourceManager, typeof(Resources));
    private static readonly LocalizableString MessageFormat = new LocalizableResourceString(
        nameof(Resources.LineMaxLengthAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
    private static readonly LocalizableString Description = new LocalizableResourceString(
        nameof(Resources.LineMaxLengthAnalyzerDescription), Resources.ResourceManager, typeof(Resources));
    private const string Category = "Readability";

    private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
        DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description);

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);

    public override void Initialize(AnalysisContext context)
    {
        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
        context.EnableConcurrentExecution();

        var nodeTypes = Enum.GetValues(typeof(SyntaxKind)).Cast<SyntaxKind>().ToArray();
        context.RegisterSyntaxTreeAction(VerifyLines);
    }

    private void VerifyLines(SyntaxTreeAnalysisContext context)
    {
        var text = context.Tree.GetText();
        text.Lines.Where(line => line.End - line.Start + 1 > LineMaxLength).ToList()
            .ForEach(line =>
            {
                var location = Location.Create(context.Tree, line.Span);
                var diagnostic = Diagnostic.Create(Rule, location, LineMaxLength);
                context.ReportDiagnostic(diagnostic);
            });
    }
}
把人绕傻吧 2025-01-24 08:12:20

一种简单的方法可能是注册语法树,然后立即在语法树上调用 GetText() ;从那里您可以直接查看文本的行,并且至少找到“长”行,因为您可以通过这种方式直接获取行跨度和长度。您仍然可能需要过滤掉长字符串文字之类的东西。

An easy approach might be to register for syntax trees, but then immediately just call GetText() on the syntax tree; from there you can look at the lines of the text directly and at least find "long" lines since you can directly get line spans and lengths that way. You'll still potentially need to filter out things though like long string literals or something.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文