public override SymbolFilterReason GetReason(ISymbol symbol, AttributeData attribute) { SymbolFilterReason reason = base.GetReason(symbol, attribute); if (reason != SymbolFilterReason.None) { return(reason); } if (symbol.IsKind(SymbolKind.NamedType) && attribute.AttributeClass.HasMetadataName(_defaultMemberAttribute)) { var namedType = (INamedTypeSymbol)symbol; if (namedType.GetMembers().Any(f => f.IsKind(SymbolKind.Property) && ((IPropertySymbol)f).IsIndexer)) { return(SymbolFilterReason.Ignored); } } #if DEBUG switch (attribute.AttributeClass.MetadataName) { case "FooAttribute": case "BarAttribute": return(SymbolFilterReason.None); } if (_knownVisibleAttributes.Contains(attribute.AttributeClass)) { return(SymbolFilterReason.None); } Debug.Fail(attribute.AttributeClass.ToDisplayString()); #endif return(reason); }
internal static async Task <ImmutableArray <ISymbol> > FindSymbolsAsync( Project project, SymbolFinderOptions options = null, IFindSymbolsProgress progress = null, CancellationToken cancellationToken = default) { Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); INamedTypeSymbol generatedCodeAttribute = compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute"); ImmutableArray <ISymbol> .Builder symbols = null; var namespaceOrTypeSymbols = new Stack <INamespaceOrTypeSymbol>(); namespaceOrTypeSymbols.Push(compilation.Assembly.GlobalNamespace); while (namespaceOrTypeSymbols.Count > 0) { INamespaceOrTypeSymbol namespaceOrTypeSymbol = namespaceOrTypeSymbols.Pop(); foreach (ISymbol symbol in namespaceOrTypeSymbol.GetMembers()) { SymbolKind kind = symbol.Kind; if (kind == SymbolKind.Namespace) { var namespaceSymbol = (INamespaceSymbol)symbol; SymbolFilterReason reason = options.GetReason(namespaceSymbol); if (reason == SymbolFilterReason.None) { namespaceOrTypeSymbols.Push(namespaceSymbol); } continue; } var isUnused = false; if (!options.UnusedOnly || UnusedSymbolUtility.CanBeUnusedSymbol(symbol)) { SymbolFilterReason reason = options.GetReason(symbol); switch (reason) { case SymbolFilterReason.None: { if (options.IgnoreGeneratedCode && GeneratedCodeUtility.IsGeneratedCode(symbol, generatedCodeAttribute, f => MefWorkspaceServices.Default.GetService <ISyntaxFactsService>(compilation.Language).IsComment(f), cancellationToken)) { continue; } if (options.UnusedOnly && !symbol.IsImplicitlyDeclared) { isUnused = await UnusedSymbolUtility.IsUnusedSymbolAsync(symbol, project.Solution, cancellationToken).ConfigureAwait(false); } if (!options.UnusedOnly || isUnused) { progress?.OnSymbolFound(symbol); (symbols ??= ImmutableArray.CreateBuilder <ISymbol>()).Add(symbol); } break; } case SymbolFilterReason.Visibility: case SymbolFilterReason.WithoutAttribute: case SymbolFilterReason.ImplicitlyDeclared: { continue; } case SymbolFilterReason.SymbolGroup: case SymbolFilterReason.Ignored: case SymbolFilterReason.WithAttribute: case SymbolFilterReason.Other: { break; } default: { Debug.Fail(reason.ToString()); break; } } } if (!isUnused && kind == SymbolKind.NamedType) { namespaceOrTypeSymbols.Push((INamedTypeSymbol)symbol); } } } return(symbols?.ToImmutableArray() ?? ImmutableArray <ISymbol> .Empty); }
public PredicateSymbolFilterRule(Func <ISymbol, bool> isMatch, Func <ISymbol, bool> isApplicable, SymbolFilterReason reason) { _isMatch = isMatch; _isApplicable = isApplicable; Reason = reason; }