EntityMethodDeclarationAnalyzer.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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 static readonly DiagnosticDescriptor Rule =
  16. new DiagnosticDescriptor(DiagnosticIds.EntityMethodDeclarationAnalyzerRuleId,
  17. Title,
  18. MessageFormat,
  19. DiagnosticCategories.Hotfix,
  20. DiagnosticSeverity.Error,
  21. true,
  22. Description);
  23. public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
  24. public override void Initialize(AnalysisContext context)
  25. {
  26. if (!AnalyzerGlobalSetting.EnableAnalyzer)
  27. {
  28. return;
  29. }
  30. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
  31. context.EnableConcurrentExecution();
  32. context.RegisterSymbolAction(this.Analyzer, SymbolKind.NamedType);
  33. }
  34. private void Analyzer(SymbolAnalysisContext context)
  35. {
  36. if (!AnalyzerHelper.IsAssemblyNeedAnalyze(context.Compilation.AssemblyName, AnalyzeAssembly.AllModel))
  37. {
  38. return;
  39. }
  40. if (!(context.Symbol is INamedTypeSymbol namedTypeSymbol))
  41. {
  42. return;
  43. }
  44. // 筛选出实体类
  45. if (namedTypeSymbol.BaseType?.ToString() != Definition.EntityType && namedTypeSymbol.BaseType?.ToString() != Definition.LSEntityType)
  46. {
  47. return;
  48. }
  49. // 忽略含有EnableMethod标签的实体类
  50. if (namedTypeSymbol.HasAttribute(Definition.EnableMethodAttribute))
  51. {
  52. return;
  53. }
  54. foreach (var syntaxReference in namedTypeSymbol.DeclaringSyntaxReferences)
  55. {
  56. var classSyntax = syntaxReference.GetSyntax();
  57. if (!(classSyntax is ClassDeclarationSyntax classDeclarationSyntax))
  58. {
  59. return;
  60. }
  61. foreach (var memberDeclarationSyntax in classDeclarationSyntax.Members)
  62. {
  63. // 筛选出类声明语法节点下的所有方法声明语法节点
  64. if (memberDeclarationSyntax is MethodDeclarationSyntax methodDeclarationSyntax)
  65. {
  66. Diagnostic diagnostic = Diagnostic.Create(Rule, methodDeclarationSyntax.GetLocation(),namedTypeSymbol.Name,methodDeclarationSyntax.Identifier.Text);
  67. context.ReportDiagnostic(diagnostic);
  68. }
  69. }
  70. }
  71. }
  72. }
  73. }