Unity使用代码分析Roslyn Analyzers

发布于:2025-06-09 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、创建项目(注意这里不要选netstandard2.1会有报错)

在这里插入图片描述

二、NuGet上安装Microsoft.CodeAnalysis.CSharp

在这里插入图片描述

三、实现[Partial]特性标注的类,结构体,record必须要partial关键字修饰

需要继承DiagnosticAnalyzer
注意一定要加特性DiagnosticAnalyzer

using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;

namespace CodeAnalysic
{
    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class PartialAnalyzer : DiagnosticAnalyzer
    {
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            // 注册语义分析完成时要执行的回调
            context.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.ClassDeclaration);
            context.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.StructDeclaration);
            context.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.RecordDeclaration);
        }

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

        private static void AnalyzeType(SyntaxNodeAnalysisContext context)
        {
            //类型声明 的语法树(Syntax Tree)节点的一个基础抽象类
            var decl = (TypeDeclarationSyntax)context.Node;

            // 检查是否有 [Partial] 特性
            bool hasAttr = decl.AttributeLists
                .SelectMany(a => a.Attributes)
                .Any(attr =>
                    attr.Name.ToString() == "Partial");

            if (!hasAttr)
                return;

            // 检查是否使用 partial
            bool isPartial = decl.Modifiers
                .Any(m => m.IsKind(SyntaxKind.PartialKeyword));

            if (!isPartial)
            {
                var kind = decl switch
                {
                    ClassDeclarationSyntax _ => "类",
                    StructDeclarationSyntax _ => "结构体",
                    _ => "record"
                };
                var diag = Diagnostic.Create(Rule,
                    decl.Identifier.GetLocation(),
                    kind,
                    decl.Identifier.Text);

                context.ReportDiagnostic(diag);
            }
        }
        
        private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
            id: "P0001",
            title: "类型标记了 [Partial],应声明为 partial",
            messageFormat: "{0} '{1}' 标记了 Partial 特性,但未声明为 partial",
            category: "Usage",
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        
    }
}
public class PartialAttribute: Attribute
    {
        
    }

四、构建 (VS:生成)

在这里插入图片描述

五、将dll拖入Unity

在这里插入图片描述

在这里插入图片描述

六、拖入发现出现报错,需要将Platform勾选全部去掉

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、测试代码

在这里插入图片描述

八、这时发现没有检查效果。需要添加标签RoslynAnalyzer

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

九、如果这里你在开始创建时没有选择netstandard2.1,那么忽略

在这里插入图片描述
右键解决方案=>属性
在这里插入图片描述
重新导入并添加标签RoslynAnalyzer
在这里插入图片描述
在这里插入图片描述

10、最终控制台已经出现效果

在这里插入图片描述

官方文档