public static bool ShouldProceedWithChecks(SyntaxList <SwitchSectionSyntax> caseSyntaxes)
        {
            if (PatternMatchingHelper.HasVarDeclaration(caseSyntaxes))
            {
                return(false);
            }

            return(DefaultCaseCheck.ShouldProceedWithDefault(caseSyntaxes));
        }
Пример #2
0
        public static bool ShouldProceedWithChecks(SyntaxList <SwitchSectionSyntax> caseSyntaxes, string expressionTypeName)
        {
            if (PatternMatchingHelper.HasVarDeclaration(caseSyntaxes))
            {
                return(false);
            }

            if (expressionTypeName == "Object")
            {
                // todo: maybe show warning or info message in this case?
                return(false);
            }

            if (HasSameClassDeclaration(caseSyntaxes, expressionTypeName))
            {
                return(false);
            }

            return(DefaultCaseCheck.ShouldProceedWithDefault(caseSyntaxes));
        }
        private static void CheckSwitch(SwitchStatementSyntax switchStatement, CodeBlockAnalysisContext context)
        {
            var expression          = switchStatement.Expression;
            var typeInfo            = context.SemanticModel.GetTypeInfo(expression);
            var expressionType      = typeInfo.ConvertedType;
            var switchCases         = switchStatement.Sections;
            var switchLocationStart = switchStatement.GetLocation().SourceSpan.Start;

            if (expressionType.TypeKind == TypeKind.Enum)
            {
                bool ShouldProceed() => EnumAnalyzer.ShouldProceedWithChecks(switchCases);
                IEnumerable <string> CaseImplementations() => EnumAnalyzer.CaseIdentifiers(switchCases);

                var namedType = expressionType as INamedTypeSymbol;
                switch (namedType.EnumUnderlyingType.Name)
                {
                case "Int32":
                {
                    IEnumerable <SwitchArgumentTypeItem <int> > AllImplementations() => EnumAnalyzer.AllEnumValues <int>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }

                case "UInt32":
                {
                    IEnumerable <SwitchArgumentTypeItem <uint> > AllImplementations() => EnumAnalyzer.AllEnumValues <uint>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }

                case "Int64":
                {
                    IEnumerable <SwitchArgumentTypeItem <long> > AllImplementations() => EnumAnalyzer.AllEnumValues <long>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }

                case "UInt64":
                {
                    IEnumerable <SwitchArgumentTypeItem <ulong> > AllImplementations() => EnumAnalyzer.AllEnumValues <ulong>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }

                case "Byte":
                {
                    IEnumerable <SwitchArgumentTypeItem <byte> > AllImplementations() => EnumAnalyzer.AllEnumValues <byte>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }

                case "SByte":
                {
                    IEnumerable <SwitchArgumentTypeItem <sbyte> > AllImplementations() => EnumAnalyzer.AllEnumValues <sbyte>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }

                case "Int16":
                {
                    IEnumerable <SwitchArgumentTypeItem <short> > AllImplementations() => EnumAnalyzer.AllEnumValues <short>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }

                case "UInt16":
                {
                    IEnumerable <SwitchArgumentTypeItem <ushort> > AllImplementations() => EnumAnalyzer.AllEnumValues <ushort>(expressionType);

                    ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, EnumAnalyzer.Rule);
                    break;
                }
                }
            }

            if (expressionType.TypeKind == TypeKind.Interface)
            {
                bool ShouldProceed() => InterfaceAnalyzer.ShouldProceedWithChecks(switchCases);
                IEnumerable <SwitchArgumentTypeItem <string> > AllImplementations() => InterfaceAnalyzer.GetAllImplementationNames(switchLocationStart, expressionType, context.SemanticModel);
                IEnumerable <string> CaseImplementations() => PatternMatchingHelper.GetCaseValues(switchCases);

                ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, InterfaceAnalyzer.Rule);
            }

            if (expressionType.TypeKind == TypeKind.Class)
            {
                bool ShouldProceed() => ClassAnalyzer.ShouldProceedWithChecks(switchCases, expressionType.Name);
                IEnumerable <SwitchArgumentTypeItem <string> > AllImplementations() => ClassAnalyzer.GetAllImplementationNames(switchLocationStart, expressionType, context.SemanticModel);
                IEnumerable <string> CaseImplementations() => PatternMatchingHelper.GetCaseValues(switchCases);

                ProcessSwitch(ShouldProceed, AllImplementations, CaseImplementations, ClassAnalyzer.Rule);
            }

            void ProcessSwitch <T>(Func <bool> shouldProceedFunc,
                                   Func <IEnumerable <SwitchArgumentTypeItem <T> > > allImplementationsFunc,
                                   Func <IEnumerable <string> > caseImplementationFunc,
                                   DiagnosticDescriptor rule) where T : IComparable => ProcessSwitchCases(
                shouldProceedFunc : shouldProceedFunc,
                allImplementationsFunc : allImplementationsFunc,
                caseImplementationFunc : caseImplementationFunc,
                rule : rule,
                location : switchStatement.GetLocation(),
                context : context,
                switchStatementLocation : switchLocationStart);
        }
Пример #4
0
 private static bool HasSameClassDeclaration(SyntaxList <SwitchSectionSyntax> caseSyntaxes, string className)
 {
     return(PatternMatchingHelper.GetCaseValues(caseSyntaxes).Any(x => x == className));
 }