简体   繁体   中英

What's the best way to check source code lines for exceeding line length with Roslyn Analyzer?

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.

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.

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);
            });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM