mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
64 lines
2.3 KiB
C#
64 lines
2.3 KiB
C#
using System.Linq;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Semmle.Extraction.CSharp.Util;
|
|
using Semmle.Extraction.Kinds;
|
|
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|
{
|
|
internal sealed class ImplicitToString : Expression
|
|
{
|
|
/// <summary>
|
|
/// Gets the `ToString` method for the given type.
|
|
/// </summary>
|
|
private static IMethodSymbol? GetToStringMethod(ITypeSymbol? 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))
|
|
{
|
|
Factory.Create(info.SetParent(this, -1));
|
|
|
|
var target = Method.Create(Context, toString);
|
|
Context.TrapWriter.Writer.expr_call(this, target);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new expression, adding a compiler generated `ToString` call if required.
|
|
/// </summary>
|
|
public static Expression Create(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child)
|
|
{
|
|
var info = new ExpressionNodeInfo(cx, node, parent, child);
|
|
return CreateFromNode(info.SetImplicitToString(!info.Type.IsStringType()));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wraps the resulting expression in a `ToString` call, if a suitable `ToString` method is available.
|
|
/// </summary>
|
|
public static Expression Wrap(ExpressionNodeInfo info)
|
|
{
|
|
if (GetToStringMethod(info.Type?.Symbol) is IMethodSymbol toString)
|
|
{
|
|
return new ImplicitToString(info, toString);
|
|
}
|
|
return Factory.Create(info);
|
|
}
|
|
}
|
|
}
|