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

VbToCs: integer divide, narrowing/widening #43

Merged
merged 2 commits into from
Mar 14, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
33 changes: 25 additions & 8 deletions ICSharpCode.CodeConverter/CSharp/NodesVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -565,14 +565,31 @@ public override CSharpSyntaxNode VisitOperatorBlock(VBSyntax.OperatorBlockSyntax
var block = node.OperatorStatement;
var attributes = block.AttributeLists.SelectMany(ConvertAttribute);
var modifiers = ConvertModifiers(block.Modifiers, TokenContext.Member);
return SyntaxFactory.OperatorDeclaration(
SyntaxFactory.List(attributes),
modifiers,
(TypeSyntax)block.AsClause?.Type.Accept(TriviaConvertingVisitor) ?? SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)), ConvertToken(block.OperatorToken),
(ParameterListSyntax)block.ParameterList.Accept(TriviaConvertingVisitor),
SyntaxFactory.Block(node.Statements.SelectMany(s => s.Accept(CreateMethodBodyVisitor()))),
null
);
SyntaxToken? conversionOp = null;
conversionOp = modifiers.FirstOrNullable(t=>VisualBasicConverter.IsConversionOperator(t));
if (conversionOp.HasValue) {
modifiers=modifiers.Remove(conversionOp.Value);
return SyntaxFactory.ConversionOperatorDeclaration(
SyntaxFactory.List(attributes),//attributes
modifiers,//modifiers
conversionOp.Value,//implicitOrExplicit
(TypeSyntax)block.AsClause?.Type.Accept(TriviaConvertingVisitor) ?? SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)),//type
(ParameterListSyntax)block.ParameterList.Accept(TriviaConvertingVisitor),//parameterList
SyntaxFactory.Block(node.Statements.SelectMany(s => s.Accept(CreateMethodBodyVisitor()))),//body
null//expressionBody
);

} else {
return SyntaxFactory.OperatorDeclaration(
SyntaxFactory.List(attributes),//attributes
modifiers,//modifiers
(TypeSyntax)block.AsClause?.Type.Accept(TriviaConvertingVisitor) ?? SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)),//returnType
ConvertToken(block.OperatorToken),//operatorToken
(ParameterListSyntax)block.ParameterList.Accept(TriviaConvertingVisitor),//parameterList
SyntaxFactory.Block(node.Statements.SelectMany(s => s.Accept(CreateMethodBodyVisitor()))),//body
null//expressionBody
);
Copy link
Member

Choose a reason for hiding this comment

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

Looks like you're on the right track here

}
}

private VBasic.VisualBasicSyntaxVisitor<SyntaxList<StatementSyntax>> CreateMethodBodyVisitor(bool isIterator = false)
Expand Down
14 changes: 14 additions & 0 deletions ICSharpCode.CodeConverter/CSharp/VisualBasicConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ static bool IgnoreInContext(SyntaxToken m, TokenContext context)
}
}


static bool IsConversionOperator(SyntaxToken token)
{
bool isConvOp= token.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.ExplicitKeyword, Microsoft.CodeAnalysis.CSharp.SyntaxKind.ImplicitKeyword)
||token.IsKind(VBasic.SyntaxKind.NarrowingKeyword, VBasic.SyntaxKind.WideningKeyword);
return isConvOp;
}

static bool IsVisibility(SyntaxToken token, TokenContext context)
{
return token.IsKind(VBasic.SyntaxKind.PublicKeyword, VBasic.SyntaxKind.FriendKeyword, VBasic.SyntaxKind.ProtectedKeyword, VBasic.SyntaxKind.PrivateKeyword)
Expand Down Expand Up @@ -333,6 +341,7 @@ static SyntaxKind ConvertToken(VBasic.SyntaxKind t, TokenContext context = Token
case VBasic.SyntaxKind.MultiplyExpression:
return SyntaxKind.MultiplyExpression;
case VBasic.SyntaxKind.DivideExpression:
case VBasic.SyntaxKind.IntegerDivideExpression:
Copy link
Member

Choose a reason for hiding this comment

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

Don't worry about integer divide - that's already fixed in master

return SyntaxKind.DivideExpression;
case VBasic.SyntaxKind.ModuloExpression:
return SyntaxKind.ModuloExpression;
Expand Down Expand Up @@ -401,6 +410,11 @@ static SyntaxKind ConvertToken(VBasic.SyntaxKind t, TokenContext context = Token
return SyntaxKind.DoubleKeyword;
case VBasic.SyntaxKind.CStrKeyword:
return SyntaxKind.StringKeyword;
// Converts
case VBasic.SyntaxKind.NarrowingKeyword:
return SyntaxKind.ExplicitKeyword;
case VBasic.SyntaxKind.WideningKeyword:
return SyntaxKind.ImplicitKeyword;
//
case VBasic.SyntaxKind.AssemblyKeyword:
return SyntaxKind.AssemblyKeyword;
Expand Down
57 changes: 57 additions & 0 deletions Tests/CSharp/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -633,5 +633,62 @@ public string TestMethod()
}
}");
}





[Fact]
public void IntegerDivideExpression()
{
TestConversionVisualBasicToCSharp(@"Class TestClass
Sub TestMethod(ByRef i As Integer)
Dim k as Integer
k = i \ 1000000
End Sub
End Class"
, @"class TestClass
{
public void TestMethod(ref int i)
{
int k;
k = i / 1000000;
}
}");
}
Copy link
Member

Choose a reason for hiding this comment

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

Yep this is the right sort of test for integer division - now already covered in master by

public void IntegerArithmetic()





[Fact]
public void NarrowingWideningExpression()
{
//TestConversionVisualBasicToCSharp => Failing! because of cr/lf after "operator MyInt" in expected CS below:
TestConversionVisualBasicToCSharpWithoutComments(@"Public Class MyInt
Public Shared Narrowing Operator CType(i As Integer) As MyInt
Return New MyInt()
End Operator
Public Shared Widening Operator CType(myInt As MyInt) As Integer
Return 1
End Operator
End Class"
, @"public class MyInt
{
public static explicit operator MyInt
(int i)
{
return new MyInt();
}
public static implicit operator int
(MyInt myInt)
{
return 1;
}
}");
}
Copy link
Member

@GrahamTheCoder GrahamTheCoder Mar 13, 2018

Choose a reason for hiding this comment

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

Yep you're on the right track here too!

Copy link
Author

@BaronBodissey BaronBodissey Mar 14, 2018

Choose a reason for hiding this comment

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

Here there's an issue I didn't knew how to fix: the parameters list is send to the next line instead of staying on the same line as the operator declaration.
It seems it's roslyn which generate this line feed at
resultNode.ToFullString()
projectconvertion.cs line 61
I tried to find any option to prevent this to happen but didn't find any. Maybe you already know the answer. Indeed I had to use the TestConversionVisualBasicToCSharpWithoutComments instead of the TestConversionVisualBasicToCSharp which is clearly failing because of this evil line feed :-).

Copy link
Member

Choose a reason for hiding this comment

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

Yes I'm happy with that fix for the test failure. Good job figuring it out - I've added this as a separate issue to try to make it clearer for others (#45).

Copy link
Member

Choose a reason for hiding this comment

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

I think this test probably belongs in MemberTests since it's really about a special kind of class member. Would you mind moving it into there?

Copy link
Author

Choose a reason for hiding this comment

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

Will do...if you can wait...I'm on the steep slope of the learning curve ;-)

Copy link
Member

@GrahamTheCoder GrahamTheCoder Mar 14, 2018

Choose a reason for hiding this comment

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

@BaronBodissey No worries then - I'll tidy things up and get it merged now





}
}
15 changes: 15 additions & 0 deletions Tests/CSharp/NamespaceLevelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ public void TestNamespace()
using System.Linq;
using Microsoft.VisualBasic;

namespace Test
{
}");
}

//TODO
//[Fact]
public void TestGlobalNamespace()
{
TestConversionVisualBasicToCSharp(@"Namespace Global.Test
End Namespace", @"using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualBasic;

namespace Test
{
}");
Expand Down