UniqueIdAnalyzer.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Immutable;
  4. using Microsoft.CodeAnalysis;
  5. using Microsoft.CodeAnalysis.Diagnostics;
  6. namespace ET.Analyzer
  7. {
  8. [DiagnosticAnalyzer(LanguageNames.CSharp)]
  9. public class UniqueIdAnalyzer : DiagnosticAnalyzer
  10. {
  11. public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>ImmutableArray.Create(UniqueIdRangeAnaluzerRule.Rule,UniqueIdDuplicateAnalyzerRule.Rule);
  12. public override void Initialize(AnalysisContext context)
  13. {
  14. if (!AnalyzerGlobalSetting.EnableAnalyzer)
  15. {
  16. return;
  17. }
  18. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
  19. context.EnableConcurrentExecution();
  20. context.RegisterSymbolAction(this.Analyzer, SymbolKind.NamedType);
  21. }
  22. private void Analyzer(SymbolAnalysisContext context)
  23. {
  24. if (!AnalyzerHelper.IsAssemblyNeedAnalyze(context.Compilation.AssemblyName, AnalyzeAssembly.All))
  25. {
  26. return;
  27. }
  28. if (!(context.Symbol is INamedTypeSymbol namedTypeSymbol))
  29. {
  30. return;
  31. }
  32. // 筛选出含有UniqueId标签的类
  33. var attr = namedTypeSymbol.GetFirstAttribute(Definition.UniqueIdAttribute);
  34. if (attr==null)
  35. {
  36. return;
  37. }
  38. // 获取id 最小值最大值
  39. var minIdValue = attr.ConstructorArguments[0].Value;
  40. var maxIdValue = attr.ConstructorArguments[1].Value;
  41. if (minIdValue==null || maxIdValue==null)
  42. {
  43. return;
  44. }
  45. int minId = (int)minIdValue;
  46. int maxId = (int)maxIdValue;
  47. HashSet<int> IdSet = new HashSet<int>();
  48. foreach (var member in namedTypeSymbol.GetMembers())
  49. {
  50. if (member is IFieldSymbol { IsConst: true, ConstantValue: int id } fieldSymbol)
  51. {
  52. if (id<minId || id>maxId)
  53. {
  54. ReportDiagnostic(fieldSymbol,id, UniqueIdRangeAnaluzerRule.Rule);
  55. }else if (IdSet.Contains(id))
  56. {
  57. ReportDiagnostic(fieldSymbol,id,UniqueIdDuplicateAnalyzerRule.Rule);
  58. }
  59. else
  60. {
  61. IdSet.Add(id);
  62. }
  63. }
  64. }
  65. void ReportDiagnostic(IFieldSymbol fieldSymbol, int idValue, DiagnosticDescriptor rule)
  66. {
  67. ET.Analyzer.ClientClassInServerAnalyzer analyzer = new ClientClassInServerAnalyzer();
  68. foreach (var syntaxReference in fieldSymbol.DeclaringSyntaxReferences)
  69. {
  70. var syntax = syntaxReference.GetSyntax();
  71. Diagnostic diagnostic = Diagnostic.Create(rule, syntax.GetLocation(),namedTypeSymbol.Name,fieldSymbol.Name,idValue.ToString());
  72. context.ReportDiagnostic(diagnostic);
  73. }
  74. }
  75. }
  76. }
  77. }