EntityDelegateDeclarationAnalyzer.cs 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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 static readonly DiagnosticDescriptor Rule =
  15. new DiagnosticDescriptor(DiagnosticIds.DelegateAnalyzerRuleId,
  16. Title,
  17. MessageFormat,
  18. DiagnosticCategories.Model,
  19. DiagnosticSeverity.Error,
  20. true,
  21. Description);
  22. public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>ImmutableArray.Create(Rule);
  23. public override void Initialize(AnalysisContext context)
  24. {
  25. if (!AnalyzerGlobalSetting.EnableAnalyzer)
  26. {
  27. return;
  28. }
  29. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
  30. context.EnableConcurrentExecution();
  31. context.RegisterSymbolAction(this.Analyzer, SymbolKind.NamedType);
  32. }
  33. private void Analyzer(SymbolAnalysisContext context)
  34. {
  35. if (!AnalyzerHelper.IsAssemblyNeedAnalyze(context.Compilation.AssemblyName, AnalyzeAssembly.AllModel))
  36. {
  37. return;
  38. }
  39. if (!(context.Symbol is INamedTypeSymbol namedTypeSymbol))
  40. {
  41. return;
  42. }
  43. // 筛选出实体类
  44. if (namedTypeSymbol.BaseType?.ToString() != Definition.EntityType)
  45. {
  46. return;
  47. }
  48. foreach (var member in namedTypeSymbol.GetMembers())
  49. {
  50. if (member is IFieldSymbol fieldSymbol && fieldSymbol.Type.BaseType?.ToString()==typeof(MulticastDelegate).FullName)
  51. {
  52. ReportDiagnostic(fieldSymbol,fieldSymbol.Name);
  53. continue;
  54. }
  55. if (member is IPropertySymbol propertySymbol && propertySymbol.Type.BaseType?.ToString()==typeof(MulticastDelegate).FullName)
  56. {
  57. ReportDiagnostic(propertySymbol,propertySymbol.Name);
  58. continue;
  59. }
  60. }
  61. void ReportDiagnostic(ISymbol symbol,string delegateName)
  62. {
  63. foreach (var syntaxReference in symbol.DeclaringSyntaxReferences)
  64. {
  65. var syntax = syntaxReference.GetSyntax();
  66. Diagnostic diagnostic = Diagnostic.Create(Rule, syntax.GetLocation(),namedTypeSymbol.Name,delegateName);
  67. context.ReportDiagnostic(diagnostic);
  68. }
  69. }
  70. }
  71. }
  72. }