一、创建项目(注意这里不要选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