EntityDelegateDeclarationAnalyzer.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System;
  2. using System.Collections.Immutable;
  3. using Microsoft.CodeAnalysis;
  4. using Microsoft.CodeAnalysis.CSharp.Syntax;
  5. using Microsoft.CodeAnalysis.Diagnostics;
  6. namespace ET.Analyzer
  7. {
  8. [DiagnosticAnalyzer(LanguageNames.CSharp)]
  9. public class EntityDelegateDeclarationAnalyzer: DiagnosticAnalyzer
  10. {
  11. private const string Title = "实体类禁止声明委托字段或属性";
  12. private const string MessageFormat = "实体类: {0} 不能在类内部声明委托字段或属性: {1}";
  13. private const string Description = "实体类禁止声明委托字段或属性.";
  14. private const string EntityType = "ET.Entity";
  15. private static readonly DiagnosticDescriptor Rule =
  16. new DiagnosticDescriptor(DiagnosticIds.DelegateAnalyzerRuleId,
  17. Title,
  18. MessageFormat,
  19. DiagnosticCategories.Model,
  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() != EntityType)
  46. {
  47. return;
  48. }
  49. foreach (var member in namedTypeSymbol.GetMembers())
  50. {
  51. if (member is IFieldSymbol fieldSymbol && fieldSymbol.Type.BaseType?.ToString()==typeof(MulticastDelegate).FullName)
  52. {
  53. ReportDiagnostic(fieldSymbol,fieldSymbol.Name);
  54. continue;
  55. }
  56. if (member is IPropertySymbol propertySymbol && propertySymbol.Type.BaseType?.ToString()==typeof(MulticastDelegate).FullName)
  57. {
  58. ReportDiagnostic(propertySymbol,propertySymbol.Name);
  59. continue;
  60. }
  61. }
  62. void ReportDiagnostic(ISymbol symbol,string delegateName)
  63. {
  64. foreach (var syntaxReference in symbol.DeclaringSyntaxReferences)
  65. {
  66. var syntax = syntaxReference.GetSyntax();
  67. Diagnostic diagnostic = Diagnostic.Create(Rule, syntax.GetLocation(),namedTypeSymbol.Name,delegateName);
  68. context.ReportDiagnostic(diagnostic);
  69. }
  70. }
  71. }
  72. }
  73. }