AnalyzerHelper.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System.Linq;
  2. using Microsoft.CodeAnalysis;
  3. using Microsoft.CodeAnalysis.CSharp.Syntax;
  4. namespace ET.Analyzer
  5. {
  6. public static class AnalyzerHelper
  7. {
  8. /// <summary>
  9. /// 获取语法树节点的子节点中第一个指定类型节点
  10. /// </summary>
  11. /// <param name="syntaxNode">语法树节点</param>
  12. /// <typeparam name="T">指定语法节点类型</typeparam>
  13. /// <returns>第一个指定类型节点</returns>
  14. public static T? GetFirstChild<T>(this SyntaxNode syntaxNode) where T : SyntaxNode
  15. {
  16. foreach (SyntaxNode? childNode in syntaxNode.ChildNodes())
  17. {
  18. if (childNode.GetType() == typeof (T))
  19. {
  20. return childNode as T;
  21. }
  22. }
  23. return null;
  24. }
  25. /// <summary>
  26. /// 获取语法树节点的子节点中最后一个指定类型节点
  27. /// </summary>
  28. /// <param name="syntaxNode">语法树节点</param>
  29. /// <typeparam name="T">指定语法节点类型</typeparam>
  30. /// <returns>最后一个指定类型节点</returns>
  31. public static T? GetLastChild<T>(this SyntaxNode syntaxNode) where T : SyntaxNode
  32. {
  33. foreach (SyntaxNode? childNode in syntaxNode.ChildNodes().Reverse())
  34. {
  35. if (childNode.GetType() == typeof (T))
  36. {
  37. return childNode as T;
  38. }
  39. }
  40. return null;
  41. }
  42. /// <summary>
  43. /// 获取语法节点所属的ClassDeclarationSyntax
  44. /// </summary>
  45. public static ClassDeclarationSyntax? GetParentClassDeclaration(this SyntaxNode syntaxNode)
  46. {
  47. SyntaxNode? parentNode = syntaxNode.Parent;
  48. while (parentNode != null)
  49. {
  50. if (parentNode is ClassDeclarationSyntax classDeclarationSyntax)
  51. {
  52. return classDeclarationSyntax;
  53. }
  54. parentNode = parentNode.Parent;
  55. }
  56. return null;
  57. }
  58. /// <summary>
  59. /// INamedTypeSymbol 是否有指定的Attribute
  60. /// </summary>
  61. public static bool HasAttribute(this INamedTypeSymbol namedTypeSymbol, string AttributeName)
  62. {
  63. foreach (AttributeData? attributeData in namedTypeSymbol.GetAttributes())
  64. {
  65. if (attributeData.AttributeClass?.ToString() == AttributeName)
  66. {
  67. return true;
  68. }
  69. }
  70. return false;
  71. }
  72. /// <summary>
  73. /// INamedTypeSymbol 是否有指定的基类Attribute
  74. /// </summary>
  75. public static bool HasBaseAttribute(this INamedTypeSymbol namedTypeSymbol, string AttributeName)
  76. {
  77. foreach (AttributeData? attributeData in namedTypeSymbol.GetAttributes())
  78. {
  79. INamedTypeSymbol? attributeType = attributeData.AttributeClass?.BaseType;
  80. while (attributeType != null)
  81. {
  82. if (attributeType.ToString() == AttributeName)
  83. {
  84. return true;
  85. }
  86. attributeType = attributeType.BaseType;
  87. }
  88. }
  89. return false;
  90. }
  91. /// <summary>
  92. /// INamedTypeSymbol 获取指定类型的第一个Attribute
  93. /// </summary>
  94. public static AttributeData? GetFirstAttribute(this INamedTypeSymbol namedTypeSymbol, string AttributeName)
  95. {
  96. foreach (AttributeData? attributeData in namedTypeSymbol.GetAttributes())
  97. {
  98. if (attributeData.AttributeClass?.ToString() == AttributeName)
  99. {
  100. return attributeData;
  101. }
  102. }
  103. return null;
  104. }
  105. /// <summary>
  106. /// INamedTypeSymbol 是否含有指定接口
  107. /// </summary>
  108. public static bool HasInterface(this INamedTypeSymbol namedTypeSymbol, string InterfaceName)
  109. {
  110. foreach (INamedTypeSymbol? iInterface in namedTypeSymbol.AllInterfaces)
  111. {
  112. if (iInterface.ToString() == InterfaceName)
  113. {
  114. return true;
  115. }
  116. }
  117. return false;
  118. }
  119. /// <summary>
  120. /// 判断指定的程序集是否需要分析
  121. /// </summary>
  122. public static bool IsAssemblyNeedAnalyze(string? assemblyName, params string[] analyzeAssemblyNames)
  123. {
  124. if (assemblyName == null)
  125. {
  126. return false;
  127. }
  128. foreach (string analyzeAssemblyName in analyzeAssemblyNames)
  129. {
  130. if (assemblyName == analyzeAssemblyName)
  131. {
  132. return true;
  133. }
  134. }
  135. return false;
  136. }
  137. }
  138. }