コード例 #1
0
        private static void Analyze(
            SyntaxNodeAnalysisContext context,
            SymbolInterfaceInfo interfaceInfo,
            SymbolInterfaceInfo interfaceInfo2,
            INamedTypeSymbol typeSymbol = null)
        {
            foreach (INamedTypeSymbol interfaceSymbol in interfaceInfo2.Interfaces)
            {
                if (interfaceInfo.Symbol.Equals(interfaceSymbol))
                {
                    if (typeSymbol == null ||
                        !typeSymbol.IsAnyInterfaceMemberExplicitlyImplemented(interfaceInfo.Symbol))
                    {
                        BaseTypeSyntax baseType = interfaceInfo.BaseType;

                        context.ReportDiagnostic(
                            DiagnosticDescriptors.RemoveRedundantBaseInterface,
                            baseType,
                            SymbolDisplay.GetMinimalString(interfaceInfo.Symbol, context.SemanticModel, baseType.SpanStart),
                            SymbolDisplay.GetMinimalString(interfaceInfo2.Symbol, context.SemanticModel, baseType.SpanStart));

                        return;
                    }
                }
            }
        }
コード例 #2
0
        public static void AnalyzeBaseList(SyntaxNodeAnalysisContext context)
        {
            var baseList = (BaseListSyntax)context.Node;

            if (baseList.IsParentKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration) &&
                !baseList.ContainsDiagnostics &&
                !baseList.SpanContainsDirectives())
            {
                SeparatedSyntaxList <BaseTypeSyntax> baseTypes = baseList.Types;

                if (baseTypes.Count > 1)
                {
                    bool             isFirst    = true;
                    INamedTypeSymbol typeSymbol = null;
                    var baseClassInfo           = default(SymbolInterfaceInfo);
                    List <SymbolInterfaceInfo> baseInterfaceInfos = null;

                    foreach (BaseTypeSyntax baseType in baseTypes)
                    {
                        TypeSyntax type = baseType.Type;

                        if (type?.IsMissing == false)
                        {
                            var baseSymbol = context.SemanticModel.GetSymbol(type, context.CancellationToken) as INamedTypeSymbol;

                            if (baseSymbol != null)
                            {
                                TypeKind typeKind = baseSymbol.TypeKind;

                                ImmutableArray <INamedTypeSymbol> allInterfaces = baseSymbol.AllInterfaces;

                                if (typeKind == TypeKind.Class)
                                {
                                    if (!isFirst)
                                    {
                                        break;
                                    }

                                    if (allInterfaces.Any())
                                    {
                                        baseClassInfo = new SymbolInterfaceInfo(baseType, baseSymbol, allInterfaces);
                                    }
                                }
                                else if (typeKind == TypeKind.Interface)
                                {
                                    var baseInterfaceInfo = new SymbolInterfaceInfo(baseType, baseSymbol, allInterfaces);

                                    if (baseInterfaceInfos == null)
                                    {
                                        if (allInterfaces.Any())
                                        {
                                            baseInterfaceInfos = new List <SymbolInterfaceInfo>()
                                            {
                                                baseInterfaceInfo
                                            }
                                        }
                                        ;
                                    }
                                    else
                                    {
                                        foreach (SymbolInterfaceInfo baseInterfaceInfo2 in baseInterfaceInfos)
                                        {
                                            Analyze(context, baseInterfaceInfo, baseInterfaceInfo2);
                                            Analyze(context, baseInterfaceInfo2, baseInterfaceInfo);
                                        }
                                    }

                                    if (baseClassInfo.IsValid)
                                    {
                                        if (typeSymbol == null)
                                        {
                                            typeSymbol = context.SemanticModel.GetDeclaredSymbol((TypeDeclarationSyntax)baseList.Parent, context.CancellationToken);
                                        }

                                        Analyze(context, baseInterfaceInfo, baseClassInfo, typeSymbol);
                                    }
                                }
                            }
                        }

                        if (isFirst)
                        {
                            isFirst = false;
                        }
                    }
                }
            }
        }
コード例 #3
0
        public static void AnalyzeBaseList(SyntaxNodeAnalysisContext context)
        {
            var baseList = (BaseListSyntax)context.Node;

            if (!baseList.IsParentKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration))
            {
                return;
            }

            if (baseList.ContainsDiagnostics)
            {
                return;
            }

            if (baseList.SpanContainsDirectives())
            {
                return;
            }

            SeparatedSyntaxList <BaseTypeSyntax> baseTypes = baseList.Types;

            if (baseTypes.Count <= 1)
            {
                return;
            }

            bool                       isFirst            = true;
            INamedTypeSymbol           typeSymbol         = null;
            SymbolInterfaceInfo        baseClassInfo      = default;
            List <SymbolInterfaceInfo> baseInterfaceInfos = null;

            foreach (BaseTypeSyntax baseType in baseTypes)
            {
                TypeSyntax type = baseType.Type;

                if (type?.IsMissing == false &&
                    (context.SemanticModel.GetSymbol(type, context.CancellationToken) is INamedTypeSymbol baseSymbol))
                {
                    TypeKind typeKind = baseSymbol.TypeKind;

                    ImmutableArray <INamedTypeSymbol> allInterfaces = baseSymbol.AllInterfaces;

                    if (typeKind == TypeKind.Class)
                    {
                        if (!isFirst)
                        {
                            break;
                        }

                        if (allInterfaces.Any())
                        {
                            baseClassInfo = new SymbolInterfaceInfo(baseType, baseSymbol, allInterfaces);
                        }
                    }
                    else if (typeKind == TypeKind.Interface)
                    {
                        var baseInterfaceInfo = new SymbolInterfaceInfo(baseType, baseSymbol, allInterfaces);

                        if (baseInterfaceInfos == null)
                        {
                            if (allInterfaces.Any())
                            {
                                baseInterfaceInfos = new List <SymbolInterfaceInfo>()
                                {
                                    baseInterfaceInfo
                                }
                            }
                            ;
                        }
                        else
                        {
                            foreach (SymbolInterfaceInfo baseInterfaceInfo2 in baseInterfaceInfos)
                            {
                                Analyze(baseInterfaceInfo, baseInterfaceInfo2);
                                Analyze(baseInterfaceInfo2, baseInterfaceInfo);
                            }
                        }

                        if (baseClassInfo.Symbol != null)
                        {
                            if (typeSymbol == null)
                            {
                                typeSymbol = context.SemanticModel.GetDeclaredSymbol((TypeDeclarationSyntax)baseList.Parent, context.CancellationToken);
                            }

                            Analyze(baseInterfaceInfo, baseClassInfo);
                        }
                    }
                }

                if (isFirst)
                {
                    isFirst = false;
                }
            }

            void Analyze(
                in SymbolInterfaceInfo interfaceInfo,
                in SymbolInterfaceInfo interfaceInfo2)
            {
                ImmutableArray <ISymbol> members = default;

                foreach (INamedTypeSymbol interfaceSymbol in interfaceInfo2.Interfaces)
                {
                    if (interfaceInfo.Symbol.Equals(interfaceSymbol))
                    {
                        if (typeSymbol != null)
                        {
                            if (members.IsDefault)
                            {
                                members = typeSymbol.GetMembers();
                            }

                            if (IsExplicitlyImplemented(interfaceInfo, members))
                            {
                                continue;
                            }

                            if (IsImplementedWithNewKeyword(interfaceInfo, typeSymbol, context.CancellationToken))
                            {
                                continue;
                            }
                        }

                        BaseTypeSyntax baseType = interfaceInfo.BaseType;

                        DiagnosticHelpers.ReportDiagnostic(context,
                                                           DiagnosticDescriptors.RemoveRedundantBaseInterface,
                                                           baseType,
                                                           SymbolDisplay.ToMinimalDisplayString(interfaceInfo.Symbol, context.SemanticModel, baseType.SpanStart, SymbolDisplayFormats.Default),
                                                           SymbolDisplay.ToMinimalDisplayString(interfaceInfo2.Symbol, context.SemanticModel, baseType.SpanStart, SymbolDisplayFormats.Default));

                        return;
                    }
                }
            }
        }