| File: Utilities\SymbolExtensions.cs | Web Access |
| Project: src\src\Analyzers\Microsoft.Analyzers.Local\Microsoft.Analyzers.Local.csproj (Microsoft.Analyzers.Local) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.CodeAnalysis; namespace Microsoft.Extensions.LocalAnalyzers.Utilities; internal static class SymbolExtensions { /// <summary> /// True if the symbol is externally visible outside this assembly. /// </summary> public static bool IsExternallyVisible(this ISymbol symbol) { while (symbol.Kind != SymbolKind.Namespace) { switch (symbol.DeclaredAccessibility) { // If we see anything private, then the symbol is private. case Accessibility.NotApplicable: case Accessibility.Private: return false; // If we see anything internal, then knock it down from public to // internal. case Accessibility.Internal: case Accessibility.ProtectedAndInternal: return false; } symbol = symbol.ContainingSymbol; } return true; } public static bool HasAttribute(this ISymbol sym, INamedTypeSymbol attribute) { foreach (var a in sym.GetAttributes()) { if (SymbolEqualityComparer.Default.Equals(a.AttributeClass, attribute)) { return true; } } return false; } public static bool HasAttribute(this ISymbol sym, string attributeName) { foreach (var a in sym.GetAttributes()) { var attrType = a.AttributeClass?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); if (attrType == attributeName) { return true; } } return false; } public static bool IsContaminated(this ISymbol symbol, INamedTypeSymbol? contaminationAttribute) { return (contaminationAttribute != null) && IsContaminated(symbol); bool IsContaminated(ISymbol symbol) { if (symbol.HasAttribute(contaminationAttribute)) { // symbol is annotated return true; } if (symbol.ContainingAssembly != null && symbol.ContainingAssembly.HasAttribute(contaminationAttribute)) { // symbol's assembly is annotated return true; } var container = symbol.ContainingType; while (container != null) { if (IsContaminated(container)) { // symbol's container is annotated return true; } container = container.ContainingType; } if (symbol is INamedTypeSymbol type) { var baseType = type.BaseType; while (baseType != null) { if (IsContaminated(baseType)) { // symbol's base type is annotated return true; } baseType = baseType.BaseType; } } return false; } } public static bool IsContaminated(this ISymbol symbol, string attributeName) { return IsContaminated(symbol); bool IsContaminated(ISymbol symbol) { if (symbol.HasAttribute(attributeName)) { // symbol is annotated return true; } if (symbol.ContainingAssembly != null && symbol.ContainingAssembly.HasAttribute(attributeName)) { // symbol's assembly is annotated return true; } var container = symbol.ContainingType; while (container != null) { if (IsContaminated(container)) { // symbol's container is annotated return true; } container = container.ContainingType; } if (symbol is INamedTypeSymbol type) { var baseType = type.BaseType; while (baseType != null) { if (IsContaminated(baseType)) { // symbol's base type is annotated return true; } baseType = baseType.BaseType; } } return false; } } internal static ITypeSymbol? GetFieldOrPropertyType(this ISymbol symbol) { if (symbol is IFieldSymbol fieldSymbol) { return fieldSymbol.Type; } else if (symbol is IPropertySymbol propertySymbol) { return propertySymbol.Type; } else { return null; } } }