Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cast to dynamic when the accessed member can't be found but the surro… #1068

Merged
merged 1 commit into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CodeConverter/CSharp/ExpressionNodeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,12 @@ public override async Task<CSharpSyntaxNode> VisitMemberAccessExpression(VBasic.
}
if (left == null) {
left = await node.Expression.AcceptAsync<ExpressionSyntax>(TriviaConvertingExpressionVisitor);
if (left != null && _semanticModel.GetSymbolInfo(node) is {CandidateReason: CandidateReason.LateBound, CandidateSymbols.Length: 0}
&& _semanticModel.GetSymbolInfo(node.Expression).Symbol is {Kind: var expressionSymbolKind}
&& expressionSymbolKind != SymbolKind.ErrorType
&& _semanticModel.GetOperation(node) is IDynamicMemberReferenceOperation) {
left = SyntaxFactory.ParenthesizedExpression(SyntaxFactory.CastExpression(SyntaxFactory.ParseTypeName("dynamic"), left));
}
}
if (left == null) {
if (IsSubPartOfConditionalAccess(node)) {
Expand Down
37 changes: 37 additions & 0 deletions Tests/CSharp/ExpressionTests/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,43 @@ private void TestMethod(string a)
}");
}

[Fact]
public async Task DynamicTestAsync()
{
await TestConversionVisualBasicToCSharpAsync(@"
Public Class C
Public Function IsPointWithinBoundaryBox(ByVal dblLat As Double, dblLon As Double, ByVal boundbox As Object) As Boolean
If boundbox IsNot Nothing Then
Dim boolInLatBounds As Boolean = (dblLat <= boundbox.north) And (dblLat >= boundbox.south) 'Less then highest (northmost) lat, AND more than lowest (southmost) lat
Dim boolInLonBounds As Boolean = (dblLon >= boundbox.west) And (dblLon <= boundbox.east) 'More than lowest (westmost) lat, AND less than highest (eastmost) lon
Return boolInLatBounds And boolInLonBounds
Else
'Throw New Exception(""boundbox is null."")
End If
Return False
End Function
End Class
", @"using Microsoft.VisualBasic.CompilerServices; // Install-Package Microsoft.VisualBasic

public partial class C
{
public bool IsPointWithinBoundaryBox(double dblLat, double dblLon, object boundbox)
{
if (boundbox is not null)
{
bool boolInLatBounds = Conversions.ToBoolean(Operators.AndObject(Operators.ConditionalCompareObjectLessEqual(dblLat, ((dynamic)boundbox).north, false), Operators.ConditionalCompareObjectGreaterEqual(dblLat, ((dynamic)boundbox).south, false))); // Less then highest (northmost) lat, AND more than lowest (southmost) lat
bool boolInLonBounds = Conversions.ToBoolean(Operators.AndObject(Operators.ConditionalCompareObjectGreaterEqual(dblLon, ((dynamic)boundbox).west, false), Operators.ConditionalCompareObjectLessEqual(dblLon, ((dynamic)boundbox).east, false))); // More than lowest (westmost) lat, AND less than highest (eastmost) lon
return boolInLatBounds & boolInLonBounds;
}
else
{
// Throw New Exception(""boundbox is null."")
}
return false;
}
}");
}

[Fact]
public async Task ConversionOfNotUsesParensIfNeededAsync()
{
Expand Down
9 changes: 4 additions & 5 deletions Tests/CSharp/StandaloneStatementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,12 @@ End If
var cmccIds = new List<int>();
foreach (var scr in _sponsorPayment.SponsorClaimRevisions)
{
foreach (var claim in (IEnumerable)scr.Claims)
foreach (var claim in (IEnumerable)((dynamic)scr).Claims)
{
if (claim.ClaimSummary is ClaimSummary)
if (((dynamic)claim).ClaimSummary is ClaimSummary)
{
{
var withBlock = (ClaimSummary)claim.ClaimSummary;
var withBlock = (ClaimSummary)((dynamic)claim).ClaimSummary;
cmccIds.AddRange(withBlock.UnpaidClaimMealCountCalculationsIds);
}
}
Expand All @@ -151,9 +151,8 @@ End If
2 source compilation errors:
BC30451: '_sponsorPayment' is not declared. It may be inaccessible due to its protection level.
BC30002: Type 'ClaimSummary' is not defined.
3 target compilation errors:
2 target compilation errors:
CS0103: The name '_sponsorPayment' does not exist in the current context
CS1061: 'object' does not contain a definition for 'ClaimSummary' and no accessible extension method 'ClaimSummary' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
CS0246: The type or namespace name 'ClaimSummary' could not be found (are you missing a using directive or an assembly reference?)");
}
}
Loading