Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
 public PredicateSymbolFilterRule(Func <ISymbol, bool> isMatch, Func <ISymbol, bool> isApplicable, SymbolFilterReason reason)
 {
     _isMatch      = isMatch;
     _isApplicable = isApplicable;
     Reason        = reason;
 }