翼度科技»论坛 编程开发 .net 查看内容

使用 `Roslyn` 分析器和修复器对.cs源代码添加头部注释

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
之前写过两篇关于Roslyn源生成器生成源代码的用例,今天使用Roslyn的代码修复器CodeFixProvider实现一个cs文件头部注释的功能,
代码修复器会同时涉及到CodeFixProvider和DiagnosticAnalyzer,
实现FileHeaderAnalyzer

首先我们知道修复器的先决条件是分析器,比如这里,如果要对代码添加头部注释,那么分析器必须要给出对应的分析提醒:
我们首先实现实现名为FileHeaderAnalyzer的分析器:
  1. [DiagnosticAnalyzer(LanguageNames.CSharp)]
  2. public class FileHeaderAnalyzer : DiagnosticAnalyzer
  3. {
  4.     public const string DiagnosticId = "GEN050";
  5.     private static readonly LocalizableString Title = "文件缺少头部信息";
  6.     private static readonly LocalizableString MessageFormat = "文件缺少头部信息";
  7.     private static readonly LocalizableString Description = "每个文件应包含头部信息.";
  8.     private const string Category = "Document";
  9.     private static readonly DiagnosticDescriptor Rule = new(
  10.         DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
  11.     public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Rule];
  12.     public override void Initialize(AnalysisContext context)
  13.     {
  14.         if (context is null)
  15.             return;
  16.         context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
  17.         context.EnableConcurrentExecution();
  18.         context.RegisterSyntaxTreeAction(AnalyzeSyntaxTree);
  19.     }
  20.     private static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context)
  21.     {
  22.         var root = context.Tree.GetRoot(context.CancellationToken);
  23.         var firstToken = root.GetFirstToken();
  24.         // 检查文件是否以注释开头
  25.         var hasHeaderComment = firstToken.LeadingTrivia.Any(trivia => trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) || trivia.IsKind(SyntaxKind.MultiLineCommentTrivia));
  26.         if (!hasHeaderComment)
  27.         {
  28.             var diagnostic = Diagnostic.Create(Rule, Location.Create(context.Tree, TextSpan.FromBounds(0, 0)));
  29.             context.ReportDiagnostic(diagnostic);
  30.         }
  31.     }
  32. }
复制代码
FileHeaderAnalyzer分析器的原理很简单,需要重载几个方法,重点是Initialize方法,这里的RegisterSyntaxTreeAction即核心代码,SyntaxTreeAnalysisContext对象取到当前源代码的SyntaxNode根节点,然后判断TA的第一个SyntaxToken是否为注释行(SyntaxKind.SingleLineCommentTrivia|SyntaxKind.MultiLineCommentTrivia)
如果不为注释行,那么就通知分析器!
实现了上面的代码我们看一下效果:

并且编译的时候分析器将会在错误面板中显示警告清单:

实现CodeFixProvider

分析器完成了,现在我们就来实现名为AddFileHeaderCodeFixProvider的修复器,
[code]/// /// 自动给文件添加头部注释/// [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AddFileHeaderCodeFixProvider))][Shared]public class AddFileHeaderCodeFixProvider : CodeFixProvider{    private const string Title = "添加文件头部信息";    //约定模板文件的名称    private const string ConfigFileName = "Biwen.AutoClassGen.Comment";    private const string VarPrefix = "$";//变量前缀    //如果模板不存在的时候的默认注释文本    private const string DefaultComment = """        // Licensed to the {Product} under one or more agreements.        // The {Product} licenses this file to you under the MIT license.        // See the LICENSE file in the project root for more information.        """;    #region regex    private const RegexOptions ROptions = RegexOptions.Compiled | RegexOptions.Singleline;    private static readonly Regex VersionRegex = new(@"(.*?)", ROptions);    private static readonly Regex CopyrightRegex = new(@"(.*?)", ROptions);    private static readonly Regex CompanyRegex = new(@"(.*?)", ROptions);    private static readonly Regex DescriptionRegex = new(@"(.*?)", ROptions);    private static readonly Regex AuthorsRegex = new(@"(.*?)", ROptions);    private static readonly Regex ProductRegex = new(@"(.*?)", ROptions);    private static readonly Regex TargetFrameworkRegex = new(@"(.*?)", ROptions);    private static readonly Regex TargetFrameworksRegex = new(@"(.*?)", ROptions);    private static readonly Regex ImportRegex = new(@"

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具