1+ using Microsoft . CodeAnalysis ;
2+ using System . Linq ;
3+ using System . IO ;
4+ using Semmle . Extraction . Kinds ;
5+
6+ namespace Semmle . Extraction . CSharp . Entities . Expressions
7+ {
8+ internal class DateTimeObjectCreation : Expression
9+ {
10+ private readonly IMethodSymbol constructorSymbol ;
11+
12+ private DateTimeObjectCreation ( IMethodSymbol constructorSymbol , ExpressionInfo info ) : base ( info )
13+ {
14+ this . constructorSymbol = constructorSymbol ;
15+ }
16+
17+ // Gets the value of a System.DateTime object as a string containing the ticks.
18+ private static long ValueAsLong ( object ? value ) =>
19+ value is System . DateTime d ? d . Ticks : 0 ;
20+
21+ // Gets the System.DateTime(long) constructor from the `type` symbol.
22+ private static IMethodSymbol ? GetDateTimeConstructor ( ITypeSymbol ? type )
23+ {
24+ return type ? . GetMembers ( )
25+ . Where ( m =>
26+ m is IMethodSymbol c &&
27+ c . GetName ( ) == "ctor" &&
28+ c . Parameters . Length == 1 &&
29+ c . Parameters [ 0 ] . Type . SpecialType == SpecialType . System_Int64 )
30+ . Cast < IMethodSymbol > ( )
31+ . FirstOrDefault ( ) ;
32+ }
33+
34+
35+ protected void PopulateExpression ( TextWriter trapFile )
36+ {
37+ var constructor = Constructor . Create ( Context , constructorSymbol ) ;
38+ trapFile . expr_call ( this , constructor ) ;
39+ }
40+
41+ protected new Expression TryPopulate ( )
42+ {
43+ Context . Try ( null , null , ( ) => PopulateExpression ( Context . TrapWriter . Writer ) ) ;
44+ return this ;
45+ }
46+
47+ // Gets an expression that represents a System.DateTime object creation.
48+ // The `type` symbol must be a System.DateTime type and the value must be a System.DateTime object.
49+ // The expression that is being created is a call to the System.DateTime(long) constructor, where
50+ // the number of ticks from the `value` object is used as the argument to the constructor call.
51+ public static Expression CreateGenerated ( Context cx , IExpressionParentEntity parent , int childIndex , ITypeSymbol type , object ? value , Extraction . Entities . Location location )
52+ {
53+ var constructorSymbol = GetDateTimeConstructor ( type ) ?? throw new InternalError ( "Could not find symbol for System.DateTime(long)" ) ;
54+ var expr = new DateTimeObjectCreation ( constructorSymbol , new ExpressionInfo (
55+ cx ,
56+ AnnotatedTypeSymbol . CreateNotAnnotated ( type ) ,
57+ location ,
58+ ExprKind . OBJECT_CREATION ,
59+ parent ,
60+ childIndex ,
61+ true ,
62+ null ) ) ;
63+
64+ var longTypeSymbol = constructorSymbol . Parameters [ 0 ] . Type ;
65+ Literal . CreateGenerated ( cx , expr , 0 , longTypeSymbol , ValueAsLong ( value ) , location ) ;
66+
67+ return expr . TryPopulate ( ) ;
68+ }
69+ }
70+ }
0 commit comments