EntityMethodDeclarationAnalyzer.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System.Collections.Immutable;
  2. using System.Linq;
  3. using Microsoft.CodeAnalysis;
  4. using Microsoft.CodeAnalysis.CSharp;
  5. using Microsoft.CodeAnalysis.CSharp.Syntax;
  6. using Microsoft.CodeAnalysis.Diagnostics;
  7. namespace ET.Analyzer
  8. {
  9. [DiagnosticAnalyzer(LanguageNames.CSharp)]
  10. public class EntityMethodDeclarationAnalyzer : DiagnosticAnalyzer
  11. {
  12. private const string Title = "实体类禁止声明方法";
  13. private const string MessageFormat = "实体类: {0} 不能在类内部声明方法: {1}";
  14. private const string Description = "实体类禁止声明方法.";
  15. private const string EntityType = "ET.Entity";
  16. private const string EnableMethodAttribute = "ET.EnableMethodAttribute";
  17. private static readonly DiagnosticDescriptor Rule =
  18. new DiagnosticDescriptor(DiagnosticIds.EntityMethodDeclarationAnalyzerRuleId,
  19. Title,
  20. MessageFormat,
  21. DiagnosticCategories.Hotfix,
  22. DiagnosticSeverity.Error,
  23. true,
  24. Description);
  25. public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
  26. public override void Initialize(AnalysisContext context)
  27. {
  28. if (!AnalyzerGlobalSetting.EnableAnalyzer)
  29. {
  30. return;
  31. }
  32. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
  33. context.EnableConcurrentExecution();
  34. context.RegisterSymbolAction(this.Analyzer, SymbolKind.NamedType);
  35. }
  36. private void Analyzer(SymbolAnalysisContext context)
  37. {
  38. if (!AnalyzerHelper.IsAssemblyNeedAnalyze(context.Compilation.AssemblyName, AnalyzeAssembly.AllModel))
  39. {
  40. return;
  41. }
  42. if (!(context.Symbol is INamedTypeSymbol namedTypeSymbol))
  43. {
  44. return;
  45. }
  46. // 筛选出实体类
  47. if (namedTypeSymbol.BaseType?.ToString() != EntityType)
  48. {
  49. return;
  50. }
  51. // 忽略含有EnableMethod标签的实体类
  52. if (namedTypeSymbol.HasAttribute(EnableMethodAttribute))
  53. {
  54. return;
  55. }
  56. foreach (var syntaxReference in namedTypeSymbol.DeclaringSyntaxReferences)
  57. {
  58. var classSyntax = syntaxReference.GetSyntax();
  59. if (!(classSyntax is ClassDeclarationSyntax classDeclarationSyntax))
  60. {
  61. return;
  62. }
  63. foreach (var memberDeclarationSyntax in classDeclarationSyntax.Members)
  64. {
  65. // 筛选出类声明语法节点下的所有方法声明语法节点
  66. if (memberDeclarationSyntax is MethodDeclarationSyntax methodDeclarationSyntax)
  67. {
  68. Diagnostic diagnostic = Diagnostic.Create(Rule, methodDeclarationSyntax.GetLocation(),namedTypeSymbol.Name,methodDeclarationSyntax.Identifier.Text);
  69. context.ReportDiagnostic(diagnostic);
  70. }
  71. }
  72. }
  73. }
  74. }
  75. }