Skip to content

Commit a90e7fd

Browse files
DateConsts
1 parent ce67d2d commit a90e7fd

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

CodeConverter/CSharp/ExpressionNodeVisitor.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -924,25 +924,30 @@ public override async Task<CSharpSyntaxNode> VisitParameter(VBSyntax.ParameterSy
924924

925925
EqualsValueClauseSyntax @default = null;
926926
if (node.Default != null) {
927-
if (node.Default.Value is VBSyntax.LiteralExpressionSyntax les && les.Token.Value is DateTime dt) {
928-
var dateTimeAsLongCsLiteral = LiteralConversions.GetLiteralExpression(dt.Ticks, dt.Ticks + "L");
929-
var dateTimeArg = CommonConversions.CreateAttributeArgumentList(SyntaxFactory.AttributeArgument(dateTimeAsLongCsLiteral));
930-
_extraUsingDirectives.Add("System.Runtime.InteropServices");
931-
_extraUsingDirectives.Add("System.Runtime.CompilerServices");
932-
var optionalDateTimeAttributes = new[] {
933-
SyntaxFactory.Attribute(SyntaxFactory.ParseName("Optional")),
934-
SyntaxFactory.Attribute(SyntaxFactory.ParseName("DateTimeConstant"), dateTimeArg)
927+
var defaultValue = node.Default.Value.SkipParens();
928+
if (_semanticModel.GetTypeInfo(defaultValue).Type?.SpecialType == SpecialType.System_DateTime) {
929+
var constant = _semanticModel.GetConstantValue(defaultValue);
930+
if (constant.HasValue && constant.Value is DateTime dt) {
931+
var dateTimeAsLongCsLiteral = CommonConversions.Literal(dt.Ticks)
932+
.WithTrailingTrivia(SyntaxFactory.ParseTrailingTrivia($"/* {defaultValue} */"));
933+
var dateTimeArg = CommonConversions.CreateAttributeArgumentList(SyntaxFactory.AttributeArgument(dateTimeAsLongCsLiteral));
934+
_extraUsingDirectives.Add("System.Runtime.InteropServices");
935+
_extraUsingDirectives.Add("System.Runtime.CompilerServices");
936+
var optionalDateTimeAttributes = new[] {
937+
SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Optional")),
938+
SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("DateTimeConstant"), dateTimeArg)
935939
};
936-
attributes.Insert(0,
937-
SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(optionalDateTimeAttributes)));
940+
attributes.Insert(0,
941+
SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(optionalDateTimeAttributes)));
942+
}
938943
} else if (node.Modifiers.Any(m => m.IsKind(VBasic.SyntaxKind.ByRefKeyword))) {
939944
var defaultExpression = (ExpressionSyntax)await node.Default.Value.AcceptAsync(TriviaConvertingExpressionVisitor);
940945
var arg = CommonConversions.CreateAttributeArgumentList(SyntaxFactory.AttributeArgument(defaultExpression));
941946
_extraUsingDirectives.Add("System.Runtime.InteropServices");
942947
_extraUsingDirectives.Add("System.Runtime.CompilerServices");
943948
var optionalAttributes = new[] {
944-
SyntaxFactory.Attribute(SyntaxFactory.ParseName("Optional")),
945-
SyntaxFactory.Attribute(SyntaxFactory.ParseName("DefaultParameterValue"), arg)
949+
SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Optional")),
950+
SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("DefaultParameterValue"), arg)
946951
};
947952
attributes.Insert(0,
948953
SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(optionalAttributes)));

Tests/CSharp/ExpressionTests/ExpressionTests.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ End Sub
4343
4444
internal partial class TestClass
4545
{
46-
private void TestMethod([Optional, DateTimeConstant(599266080000000000L)] DateTime date)
46+
private void TestMethod([Optional, DateTimeConstant(599266080000000000/* #1/1/1900# */)] DateTime date)
4747
{
4848
var rslt = DateTime.Parse(""1900-01-01"");
4949
var rslt2 = DateTime.Parse(""2002-08-13 12:14:00"");
@@ -54,6 +54,31 @@ private void TestMethod([Optional, DateTimeConstant(599266080000000000L)] DateTi
5454
BC32024: Default values cannot be supplied for parameters that are not declared 'Optional'.");
5555
}
5656

57+
[Fact]
58+
public async Task DateConsts()
59+
{
60+
await TestConversionVisualBasicToCSharp(@"Public Class Issue213
61+
Const x As Date = #1990-1-1#
62+
63+
Private Sub Y(Optional ByVal opt As Date = x)
64+
End Sub
65+
End Class", @"using System;
66+
using System.Runtime.CompilerServices;
67+
using System.Runtime.InteropServices;
68+
69+
public partial class Issue213
70+
{
71+
private const DateTime x = DateTime.Parse(""1990-01-01"");
72+
73+
private void Y([Optional, DateTimeConstant(627667488000000000/* Global.Issue213.x */)] DateTime opt)
74+
{
75+
}
76+
}
77+
2 target compilation errors:
78+
CS0283: The type 'DateTime' cannot be declared const
79+
CS0133: The expression being assigned to 'Issue213.x' must be constant");
80+
}
81+
5782
[Fact]
5883
public async Task NullInlineRefArgument()
5984
{

0 commit comments

Comments
 (0)