public static bool ShouldProceedWithChecks(SyntaxList <SwitchSectionSyntax> caseSyntaxes) { if (PatternMatchingHelper.HasVarDeclaration(caseSyntaxes)) { return(false); } return(DefaultCaseCheck.ShouldProceedWithDefault(caseSyntaxes)); }
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); }
private static bool HasSameClassDeclaration(SyntaxList <SwitchSectionSyntax> caseSyntaxes, string className) { return(PatternMatchingHelper.GetCaseValues(caseSyntaxes).Any(x => x == className)); }