예제 #1
0
        public static bool CanBeUnusedSymbol(ISymbol symbol)
        {
            switch (symbol.Kind)
            {
            case SymbolKind.Namespace:
            {
                return(false);
            }

            case SymbolKind.NamedType:
            {
                var namedType = (INamedTypeSymbol)symbol;

                if ((namedType.TypeKind == TypeKind.Class || namedType.TypeKind == TypeKind.Module) &&
                    namedType.IsStatic)
                {
                    foreach (ISymbol member in namedType.GetMembers())
                    {
                        switch (member.Kind)
                        {
                        case SymbolKind.NamedType:
                        {
                            return(false);
                        }

                        case SymbolKind.Method:
                        {
                            if (((IMethodSymbol)member).IsExtensionMethod)
                            {
                                return(false);
                            }

                            break;
                        }
                        }
                    }
                }

                return(true);
            }

            case SymbolKind.Event:
            {
                if (symbol.IsOverride)
                {
                    return(false);
                }

                var eventSymbol = (IEventSymbol)symbol;

                return(eventSymbol.ExplicitInterfaceImplementations.IsDefaultOrEmpty &&
                       !eventSymbol.ImplementsInterfaceMember(allInterfaces: true));
            }

            case SymbolKind.Field:
            {
                var fieldSymbol = (IFieldSymbol)symbol;

                return(!fieldSymbol.ImplementsInterfaceMember(allInterfaces: true));
            }

            case SymbolKind.Property:
            {
                if (symbol.IsOverride)
                {
                    return(false);
                }

                var propertySymbol = (IPropertySymbol)symbol;

                return(propertySymbol.ExplicitInterfaceImplementations.IsDefaultOrEmpty &&
                       !propertySymbol.ImplementsInterfaceMember(allInterfaces: true));
            }

            case SymbolKind.Method:
            {
                if (symbol.IsOverride)
                {
                    return(false);
                }

                var methodSymbol = (IMethodSymbol)symbol;

                switch (methodSymbol.MethodKind)
                {
                case MethodKind.Ordinary:
                {
                    return(methodSymbol.ExplicitInterfaceImplementations.IsDefaultOrEmpty &&
                           !SymbolUtility.CanBeEntryPoint(methodSymbol) &&
                           !methodSymbol.ImplementsInterfaceMember(allInterfaces: true));
                }

                case MethodKind.Constructor:
                {
                    return(methodSymbol.Parameters.Any() ||
                           !methodSymbol.ContainingType.IsAbstract);
                }
                }

                return(false);
            }

            default:
            {
                Debug.Fail(symbol.Kind.ToString());
                return(false);
            }
            }
        }
예제 #2
0
        public static async Task <bool> IsUnusedSymbolAsync(
            ISymbol symbol,
            Solution solution,
            CancellationToken cancellationToken = default)
        {
            ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

            Debug.Assert(syntaxReferences.Any(), $"No syntax references for {symbol.ToDisplayString()}");

            if (!syntaxReferences.Any())
            {
                return(false);
            }

            if (IsReferencedInDebuggerDisplayAttribute(symbol))
            {
                return(false);
            }

            IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

            foreach (ReferencedSymbol referencedSymbol in referencedSymbols)
            {
                foreach (ReferenceLocation referenceLocation in referencedSymbol.Locations)
                {
                    if (referenceLocation.IsImplicit)
                    {
                        continue;
                    }

                    if (referenceLocation.IsCandidateLocation)
                    {
                        return(false);
                    }

                    Location location = referenceLocation.Location;

                    if (!location.IsInSource)
                    {
                        continue;
                    }

                    foreach (SyntaxReference syntaxReference in syntaxReferences)
                    {
                        if (syntaxReference.SyntaxTree != location.SourceTree ||
                            !syntaxReference.Span.Contains(location.SourceSpan))
                        {
                            return(false);
                        }
                    }
                }
            }

            if (symbol.Kind == SymbolKind.Field)
            {
                INamedTypeSymbol containingType = symbol.ContainingType;

                if (containingType.TypeKind == TypeKind.Enum &&
                    containingType.HasAttribute(MetadataNames.System_FlagsAttribute))
                {
                    var fieldSymbol = (IFieldSymbol)symbol;

                    if (fieldSymbol.HasConstantValue)
                    {
                        ulong value = SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, containingType);

                        if (value == 0)
                        {
                            return(false);
                        }
                    }
                }
            }

            if (symbol.Kind == SymbolKind.NamedType)
            {
                var namedType = (INamedTypeSymbol)symbol;

                if (namedType.TypeKind.Is(TypeKind.Class, TypeKind.Struct))
                {
                    foreach (ISymbol member in namedType.GetMembers())
                    {
                        if (member.Kind == SymbolKind.Method)
                        {
                            var methodSymbol = (IMethodSymbol)member;

                            if (SymbolUtility.CanBeEntryPoint(methodSymbol))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            return(true);
        }