mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
70 lines
2.8 KiB
C#
70 lines
2.8 KiB
C#
using Microsoft.CodeAnalysis;
|
|
using System.Linq;
|
|
using System.IO;
|
|
using Semmle.Extraction.Kinds;
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|
{
|
|
internal class DateTimeObjectCreation : Expression
|
|
{
|
|
private readonly IMethodSymbol constructorSymbol;
|
|
|
|
private DateTimeObjectCreation(IMethodSymbol constructorSymbol, ExpressionInfo info) : base(info)
|
|
{
|
|
this.constructorSymbol = constructorSymbol;
|
|
}
|
|
|
|
// Gets the value of a System.DateTime object as a string containing the ticks.
|
|
private static long ValueAsLong(object? value) =>
|
|
value is System.DateTime d ? d.Ticks : 0;
|
|
|
|
// Gets the System.DateTime(long) constructor from the `type` symbol.
|
|
private static IMethodSymbol? GetDateTimeConstructor(ITypeSymbol? type)
|
|
{
|
|
return type?.GetMembers()
|
|
.Where(m =>
|
|
m is IMethodSymbol c &&
|
|
c.GetName() == "ctor" &&
|
|
c.Parameters.Length == 1 &&
|
|
c.Parameters[0].Type.SpecialType == SpecialType.System_Int64)
|
|
.Cast<IMethodSymbol>()
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
|
|
protected void PopulateExpression(TextWriter trapFile)
|
|
{
|
|
var constructor = Constructor.Create(Context, constructorSymbol);
|
|
trapFile.expr_call(this, constructor);
|
|
}
|
|
|
|
protected new Expression TryPopulate()
|
|
{
|
|
Context.Try(null, null, () => PopulateExpression(Context.TrapWriter.Writer));
|
|
return this;
|
|
}
|
|
|
|
// Gets an expression that represents a System.DateTime object creation.
|
|
// The `type` symbol must be a System.DateTime type and the value must be a System.DateTime object.
|
|
// The expression that is being created is a call to the System.DateTime(long) constructor, where
|
|
// the number of ticks from the `value` object is used as the argument to the constructor call.
|
|
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, object? value, Extraction.Entities.Location location)
|
|
{
|
|
var constructorSymbol = GetDateTimeConstructor(type) ?? throw new InternalError("Could not find symbol for System.DateTime(long)");
|
|
var expr = new DateTimeObjectCreation(constructorSymbol, new ExpressionInfo(
|
|
cx,
|
|
AnnotatedTypeSymbol.CreateNotAnnotated(type),
|
|
location,
|
|
ExprKind.OBJECT_CREATION,
|
|
parent,
|
|
childIndex,
|
|
true,
|
|
null));
|
|
|
|
var longTypeSymbol = constructorSymbol.Parameters[0].Type;
|
|
Literal.CreateGenerated(cx, expr, 0, longTypeSymbol, ValueAsLong(value), location);
|
|
|
|
return expr.TryPopulate();
|
|
}
|
|
}
|
|
} |