Skip to content

Commit 6a406b2

Browse files
committed
C#: Do not insert a synthetic ToString call in interpolation expressions, if the type implements IFormattable.
1 parent ab70a94 commit 6a406b2

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,12 @@ attribute.AttributeClass is INamedTypeSymbol nt &&
532532
return isInline;
533533
}
534534

535+
/// <summary>
536+
/// Returns true if this type implements `System.IFormattable`.
537+
/// </summary>
538+
public static bool ImplementsIFormattable(this ITypeSymbol type) =>
539+
type.AllInterfaces.Any(i => i.Name == "IFormattable" && i.ContainingNamespace.ToString() == "System");
540+
535541
/// <summary>
536542
/// Holds if this type is of the form <code>System.ReadOnlySpan&lt;byte&gt;</code>.
537543
/// </summary>

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/InterpolatedString.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.IO;
2+
using Microsoft.CodeAnalysis;
23
using Microsoft.CodeAnalysis.CSharp;
34
using Microsoft.CodeAnalysis.CSharp.Syntax;
45
using Semmle.Extraction.Kinds;
@@ -20,7 +21,15 @@ protected override void PopulateExpression(TextWriter trapFile)
2021
{
2122
case SyntaxKind.Interpolation:
2223
var interpolation = (InterpolationSyntax)c;
23-
ImplicitToString.Create(Context, interpolation.Expression, this, child++);
24+
var exp = interpolation.Expression;
25+
if (Context.GetTypeInfo(exp).Type is ITypeSymbol type && !type.ImplementsIFormattable())
26+
{
27+
ImplicitToString.Create(Context, exp, this, child++);
28+
}
29+
else
30+
{
31+
Create(Context, exp, this, child++);
32+
}
2433
break;
2534
case SyntaxKind.InterpolatedStringText:
2635
// Create a string literal

0 commit comments

Comments
 (0)