diff --git a/src/Meziantou.Analyzer/Internals/CultureSensitiveFormattingContext.cs b/src/Meziantou.Analyzer/Internals/CultureSensitiveFormattingContext.cs index 8a8d6f1a3..748f11e02 100755 --- a/src/Meziantou.Analyzer/Internals/CultureSensitiveFormattingContext.cs +++ b/src/Meziantou.Analyzer/Internals/CultureSensitiveFormattingContext.cs @@ -113,6 +113,30 @@ public bool IsCultureSensitiveOperation(IOperation operation, CultureSensitiveOp if (invocation.Arguments.Length == 1 && invocation.Arguments[0].Value.Type.IsEqualTo(StringBuilder_AppendInterpolatedStringHandlerSymbol) && !IsCultureSensitiveOperation(invocation.Arguments[0].Value, options)) return false; } + else if (methodName is "AppendFormat" && invocation.TargetMethod.ContainingType.IsEqualTo(StringBuilderSymbol) && invocation.Arguments.Length > 0) + { + if (invocation.Arguments.Length == 1) + return false; + + if (invocation.TargetMethod.Parameters.Length == 2 && invocation.Arguments[1].Parameter?.Type is IArrayTypeSymbol && invocation.Arguments[1].Value is IArrayCreationOperation appendFormatArrayCreation) + { + var initializer = appendFormatArrayCreation.Initializer; + if (initializer is null) + return true; + + return initializer.ElementValues.Any(arg => IsCultureSensitiveOperation(arg.UnwrapImplicitConversionOperations(), options)); + } +#if ROSLYN_4_14_OR_GREATER + else if (invocation.TargetMethod.Parameters.Length == 2 && invocation.Arguments[1].Value is ICollectionExpressionOperation appendFormatCollectionExpression) + { + return appendFormatCollectionExpression.Elements.Any(arg => IsCultureSensitiveOperation(arg.UnwrapImplicitConversionOperations(), options)); + } +#endif + else + { + return invocation.Arguments.Skip(1).Any(arg => IsCultureSensitiveOperation(arg.Value.UnwrapImplicitConversionOperations(), options)); + } + } else if (methodName is "Format" && invocation.TargetMethod.IsStatic && invocation.TargetMethod.ContainingType.IsString() && invocation.Arguments.Length > 0) { if (invocation.TargetMethod.Parameters[0].Type.IsEqualTo(FormatProviderSymbol)) diff --git a/tests/Meziantou.Analyzer.Test/Rules/UseIFormatProviderAnalyzerTests.cs b/tests/Meziantou.Analyzer.Test/Rules/UseIFormatProviderAnalyzerTests.cs index 71b199693..37544206b 100755 --- a/tests/Meziantou.Analyzer.Test/Rules/UseIFormatProviderAnalyzerTests.cs +++ b/tests/Meziantou.Analyzer.Test/Rules/UseIFormatProviderAnalyzerTests.cs @@ -58,7 +58,9 @@ await CreateProjectBuilder() [InlineData(""" [|System.DateTime.TryParse("", out _)|] """)] [InlineData(""" [|System.DateTimeOffset.TryParse("", out _)|] """)] [InlineData(""" [|"".ToLower()|] """)] - [InlineData(""" [|new System.Text.StringBuilder().AppendFormat("{0}", 10)|] """)] + [InlineData(""" [|new System.Text.StringBuilder().AppendFormat("{0}", -1)|] """)] + [InlineData(""" new System.Text.StringBuilder().AppendFormat("{0}", 10) """)] + [InlineData(""" new System.Text.StringBuilder().AppendFormat("{0} / {1}", "X", "Y") """)] [InlineData(""" System.DayOfWeek.Monday.ToString() """)] [InlineData(""" default(System.DateTime).ToString("o") """)] [InlineData(""" default(System.DateTime).ToString("O") """)]