Skip to content

Commit

Permalink
Merge pull request #18508 from michaelnebel/csharp/implicitinheritedt…
Browse files Browse the repository at this point in the history
…ostring

C#: Also syntheize calls to inherited `ToString`.
  • Loading branch information
michaelnebel authored Jan 20, 2025
2 parents 75a80f2 + bae29ae commit ef034bc
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@ internal sealed class ImplicitToString : Expression
/// </summary>
private static IMethodSymbol? GetToStringMethod(ITypeSymbol? type)
{
return type?
if (type is null)
{
return null;
}

var toString = type
.GetMembers()
.OfType<IMethodSymbol>()
.Where(method =>
method.GetName() == "ToString" &&
method.Parameters.Length == 0
)
.FirstOrDefault();

return toString ?? GetToStringMethod(type.BaseType);
}

private ImplicitToString(ExpressionNodeInfo info, IMethodSymbol toString) : base(new ExpressionInfo(info.Context, AnnotatedTypeSymbol.CreateNotAnnotated(toString.ReturnType), info.Location, ExprKind.METHOD_INVOCATION, info.Parent, info.Child, isCompilerGenerated: true, info.ExprValue))
Expand Down
10 changes: 10 additions & 0 deletions csharp/ql/test/library-tests/implicittostring/implicitToString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ public override string ToString()
}
}

public class Container2 : Container { }

public class Container3 { }

public class FormattableContainer : IFormattable
{
public string ToString(string format, IFormatProvider formatProvider)
Expand Down Expand Up @@ -40,5 +44,11 @@ public void M()
y = "Hello" + formattableContainer; // Implicit call to ToString().
y = $"Hello {formattableContainer}"; // Implicit call to ToString(string, IFormatProvider). We don't handle this.
y = $"Hello {formattableContainer:D}"; // Implicit call to ToString(string, IFormatProvider). We don't handle this.

var container2 = new Container2();
y = "Hello" + container2; // Implicit Container.ToString call.

var container3 = new Container3();
y = "Hello" + container3; // Implicit Object.ToString call.
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
| implicitToString.cs:31:27:31:35 | call to method ToString |
| implicitToString.cs:33:22:33:30 | call to method ToString |
| implicitToString.cs:35:22:35:30 | call to method ToString |
| implicitToString.cs:40:23:40:42 | call to method ToString |
| implicitToString.cs:35:27:35:35 | call to method ToString | Container |
| implicitToString.cs:37:22:37:30 | call to method ToString | Container |
| implicitToString.cs:39:22:39:30 | call to method ToString | Container |
| implicitToString.cs:44:23:44:42 | call to method ToString | FormattableContainer |
| implicitToString.cs:49:23:49:32 | call to method ToString | Container |
| implicitToString.cs:52:23:52:32 | call to method ToString | Object |
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import csharp

from MethodCall c
where c.isImplicit()
select c
select c, c.getTarget().getDeclaringType().toString()
4 changes: 2 additions & 2 deletions csharp/ql/test/query-tests/Nullness/Implications.expected
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,8 @@
| D.cs:253:13:253:14 | access to local variable o2 | null | D.cs:249:18:249:38 | ... ? ... : ... | null |
| D.cs:266:13:266:27 | ... is ... | true | D.cs:266:13:266:17 | access to local variable other | non-null |
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:21:310:22 | "" | non-null |
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:26:310:26 | access to parameter a | non-null |
| D.cs:310:21:310:26 | ... + ... | null | D.cs:310:26:310:26 | access to parameter a | null |
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:26:310:26 | call to method ToString | non-null |
| D.cs:310:21:310:26 | ... + ... | null | D.cs:310:26:310:26 | call to method ToString | null |
| D.cs:312:17:312:23 | !... | false | D.cs:312:18:312:23 | access to local variable s_null | true |
| D.cs:312:17:312:23 | !... | true | D.cs:312:18:312:23 | access to local variable s_null | false |
| D.cs:318:16:318:62 | ... && ... | true | D.cs:318:16:318:36 | ... == ... | true |
Expand Down

0 comments on commit ef034bc

Please sign in to comment.