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

C# -> VB: various fixes #533

Merged
merged 17 commits into from
Mar 5, 2020
Merged

C# -> VB: various fixes #533

merged 17 commits into from
Mar 5, 2020

Conversation

Alexilia
Copy link
Contributor

No description provided.

End Sub

Public Sub DoSomething()
End Sub
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good candidate for a self verifying test

Copy link
Member

@GrahamTheCoder GrahamTheCoder Mar 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add one in now - I'm a bit surprised, I thought to avoid all the visual basic magic, using the Is operator was recommended and would match CSharp more closely.

Copy link
Member

@GrahamTheCoder GrahamTheCoder Mar 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pushed the tests. Without your change on NodesVisitor.cs:1208 they pass, but with that change they fail.
Therefore I'm not convinced this is the right conversion. Could you take a look and either explain what problem you're fixing, or revert the change if it's wrong? Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is operator compares two objects by reference. It does not perform value comparison.
= operator with two strings is compiled to IL using Microsoft.VisualBasic.Strings.Equals. So the comparison could be culture-aware. In VB null strings and empty strings are considered equal, and the way to compare a string with null is to use Is Nothing. In simple cases it can't be noticed because compiler use String.Intern.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep so I think we're agreed the runtime equivalent of CSharp "==" in VB is "Is".
If we're not, could you add a test case to the self verifying tests to show where they differ (to pass, the self verifying test must compile and pass in CSharp and after conversion to visual basic)

In terms of priorities for conversion, runtime equivalence is priority 1, idiomatic code in the target language is priority 3:
https://github.com/icsharpcode/CodeConverter/blob/master/.github/CONTRIBUTING.md#deciding-what-the-output-should-be
I. E. Code that works the same is key

Note: In CSharp you would use the Equals method to do invariant culture or case insensitive comparison.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nop, in CSharp == is compiled to IL to [System.Runtime]System.String::op_Equality. It is more equivalent of VB =. These simple test passes in CS and not in VB with Is:

[Fact]
    public void NonInternStringsEqualsOperator() {
        string a = "10";
        string b = 10.ToString();
        Assert.True(a == b);
    }
Public Sub NonInternStringsEqualsOperator()
        Dim a As String = "10"
        Dim b As String = 10.ToString()
        Assert.[True](a Is b)
End Sub

but passes with =

Public Sub NonInternStringsEqualsOperator()
        Dim a As String = "10"
        Dim b As String = 10.ToString()
        Assert.[True](a = b)
End Sub

Empty string and null string in VB are the same because Nothing in VB is not null in CSharp, it's default value, for example 0 = Nothing for integers, so in any comparison null and empty string should be the same. The runtime functions also treat null like empty, so it should not be a problem.

Copy link
Member

@GrahamTheCoder GrahamTheCoder Mar 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, my apologies for misunderstanding. I understand now - I had assumed "Is" called op_Equality, but in fact it calls reference equals. This means the implementation in master is flawed as your new interning related test (presumably) highlights.

But my previous tests you removed/changed show the implementation on this PR is also flawed. You'll need to restore those tests to find the correct solution to this problem. I think the solution is to call Equals(str1, str2) when both sides are known to be strings.

We could also do a test case for object == string that preserves the unintended reference equality comparison like this:
https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUBgBjwwGYACAbzzJrI3UutuYHsAjAKwFMBjYMgB5kAvGUwEAdABUWAZWBgAllADmACgCUAbibMaqcWQCeIsgCJxZnbj20DATjVDhoo9t1kAvnk9A

@GrahamTheCoder
Copy link
Member

Sorry I took so long to get around to this. Looks really good, just a couple of minor suggestions.

@GrahamTheCoder GrahamTheCoder self-assigned this Mar 2, 2020
@GrahamTheCoder GrahamTheCoder removed their assignment Mar 2, 2020
string a = "10";
string b = 10.ToString(); //strings created in runtime are not interned
Assert.True(a == b);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I like this test, it shows that op_Equality is overridden and distinguishes from reference equality (which neither VB or C# does, but someone might guess from "==")

@GrahamTheCoder GrahamTheCoder self-assigned this Mar 5, 2020
@GrahamTheCoder GrahamTheCoder removed their assignment Mar 5, 2020
@GrahamTheCoder GrahamTheCoder merged commit 6bca5c2 into icsharpcode:master Mar 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants