Browse Source

More improvements for the C#->VB converter.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2656 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
1ea9ac7b61
  1. 1
      src/Libraries/NRefactory/Project/NRefactory.csproj
  2. 7
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/KeywordList.txt
  3. 18
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Keywords.cs
  4. 51
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Tokens.cs
  5. 65
      src/Libraries/NRefactory/Project/Src/OperatorPrecedence.cs
  6. 2587
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  7. 1
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  8. 7
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs
  9. 40
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs
  10. 45
      src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs
  11. 9
      src/Main/Base/Test/CodeConverterTests.cs

1
src/Libraries/NRefactory/Project/NRefactory.csproj

@ -74,6 +74,7 @@ @@ -74,6 +74,7 @@
<Compile Include="..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Src\OperatorPrecedence.cs" />
<Compile Include="Src\Parser\CSharp\CSharpParser.cs" />
<Compile Include="Src\Parser\CSharp\Parser.cs" />
<Compile Include="Src\Parser\VBNet\Parser.cs" />

7
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/KeywordList.txt

@ -207,6 +207,9 @@ ConcatStringAssign = "&=" @@ -207,6 +207,9 @@ ConcatStringAssign = "&="
"WithEvents"
"WriteOnly"
"Xor"
# Rem never gets passed to the parser because it is handled by the lexer, but it still
# has to be in the keyword list for the output formatter
"Rem"
# VB.NET 2.0 Keywords:
"Continue"
@ -234,5 +237,5 @@ ConcatStringAssign = "&=" @@ -234,5 +237,5 @@ ConcatStringAssign = "&="
Null("Nothing")
BlockSucc("Case", "Catch", "Else", "ElseIf", "End", "Finally", "Loop", "Next")
# List of unreserved keywords, must be the same as the "Identifier" production in VBNET.ATG
Unreserved("Text", "Binary", "Compare", "Assembly", "Ansi", "Auto", "Preserve", "Unicode", "Until", "Explicit", "Off")
# List of keywords that are valid identifiers, must be the same as the "Identifier" production in VBNET.ATG
IdentifierTokens("Text", "Binary", "Compare", "Assembly", "Ansi", "Auto", "Preserve", "Unicode", "Until", "Explicit", "Off")

18
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Keywords.cs

@ -1,16 +1,9 @@ @@ -1,16 +1,9 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
// this file was autogenerated by a tool.
using System;
namespace ICSharpCode.NRefactory.Parser.VB
{
public class Keywords
public static class Keywords
{
static readonly string[] keywordList = {
"ADDHANDLER",
@ -157,6 +150,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -157,6 +150,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
"WITHEVENTS",
"WRITEONLY",
"XOR",
"REM",
"CONTINUE",
"OPERATOR",
"USING",
@ -191,5 +185,13 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -191,5 +185,13 @@ namespace ICSharpCode.NRefactory.Parser.VB
{
return keywords[keyword];
}
public static bool IsNonIdentifierKeyword(string word)
{
int token = GetToken(word);
if (token < 0)
return false;
return !Tokens.IdentifierTokens[token];
}
}
}

51
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Tokens.cs

@ -1,10 +1,3 @@ @@ -1,10 +1,3 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
// this file was autogenerated by a tool.
using System;
using System.Collections;
@ -204,27 +197,28 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -204,27 +197,28 @@ namespace ICSharpCode.NRefactory.Parser.VB
public const int WithEvents = 183;
public const int WriteOnly = 184;
public const int Xor = 185;
public const int Continue = 186;
public const int Operator = 187;
public const int Using = 188;
public const int IsNot = 189;
public const int SByte = 190;
public const int UInteger = 191;
public const int ULong = 192;
public const int UShort = 193;
public const int CSByte = 194;
public const int CUShort = 195;
public const int CUInt = 196;
public const int CULng = 197;
public const int Global = 198;
public const int TryCast = 199;
public const int Of = 200;
public const int Narrowing = 201;
public const int Widening = 202;
public const int Partial = 203;
public const int Custom = 204;
public const int Rem = 186;
public const int Continue = 187;
public const int Operator = 188;
public const int Using = 189;
public const int IsNot = 190;
public const int SByte = 191;
public const int UInteger = 192;
public const int ULong = 193;
public const int UShort = 194;
public const int CSByte = 195;
public const int CUShort = 196;
public const int CUInt = 197;
public const int CULng = 198;
public const int Global = 199;
public const int TryCast = 200;
public const int Of = 201;
public const int Narrowing = 202;
public const int Widening = 203;
public const int Partial = 204;
public const int Custom = 205;
public const int MaxToken = 205;
public const int MaxToken = 206;
static BitArray NewSet(params int[] values)
{
BitArray bitArray = new BitArray(MaxToken);
@ -235,7 +229,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -235,7 +229,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
public static BitArray Null = NewSet(Nothing);
public static BitArray BlockSucc = NewSet(Case, Catch, Else, ElseIf, End, Finally, Loop, Next);
public static BitArray Unreserved = NewSet(Text, Binary, Compare, Assembly, Ansi, Auto, Preserve, Unicode, Until, Explicit, Off);
public static BitArray IdentifierTokens = NewSet(Text, Binary, Compare, Assembly, Ansi, Auto, Preserve, Unicode, Until, Explicit, Off);
static string[] tokenList = new string[] {
// ----- terminal classes -----
@ -427,6 +421,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -427,6 +421,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
"WithEvents",
"WriteOnly",
"Xor",
"Rem",
"Continue",
"Operator",
"Using",

65
src/Libraries/NRefactory/Project/Src/OperatorPrecedence.cs

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 2644$</version>
// </file>
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Ast;
namespace ICSharpCode.NRefactory
{
/// <summary>
/// Stores the operator precedences for the output visitor.
/// </summary>
static class OperatorPrecedence
{
static readonly Dictionary<BinaryOperatorType, int> vbDict = MakePrecedenceTable(
new BinaryOperatorType[] { BinaryOperatorType.Power },
new BinaryOperatorType[] { BinaryOperatorType.Multiply, BinaryOperatorType.Divide },
new BinaryOperatorType[] { BinaryOperatorType.DivideInteger },
new BinaryOperatorType[] { BinaryOperatorType.Modulus },
new BinaryOperatorType[] { BinaryOperatorType.Add, BinaryOperatorType.Subtract },
new BinaryOperatorType[] { BinaryOperatorType.Concat },
new BinaryOperatorType[] { BinaryOperatorType.ShiftLeft, BinaryOperatorType.ShiftRight },
new BinaryOperatorType[] {
BinaryOperatorType.Equality, BinaryOperatorType.InEquality,
BinaryOperatorType.LessThan, BinaryOperatorType.LessThanOrEqual,
BinaryOperatorType.GreaterThan, BinaryOperatorType.GreaterThanOrEqual,
BinaryOperatorType.ReferenceEquality, BinaryOperatorType.ReferenceInequality,
BinaryOperatorType.Like
},
new BinaryOperatorType[] { BinaryOperatorType.LogicalAnd, BinaryOperatorType.BitwiseAnd },
new BinaryOperatorType[] { BinaryOperatorType.LogicalOr, BinaryOperatorType.BitwiseOr },
new BinaryOperatorType[] { BinaryOperatorType.ExclusiveOr }
);
// create a dictionary operator->precedence (higher value = higher precedence)
static Dictionary<BinaryOperatorType, int> MakePrecedenceTable(params BinaryOperatorType[][] input)
{
Dictionary<BinaryOperatorType, int> dict = new Dictionary<BinaryOperatorType, int>();
for (int i = 0; i < input.Length; i++) {
foreach (BinaryOperatorType op in input[i]) {
dict.Add(op, input.Length - i);
}
}
return dict;
}
public static int ComparePrecedenceVB(BinaryOperatorType op1, BinaryOperatorType op2)
{
int p1 = GetOperatorPrecedence(vbDict, op1);
int p2 = GetOperatorPrecedence(vbDict, op2);
return p1.CompareTo(p2);
}
static int GetOperatorPrecedence(Dictionary<BinaryOperatorType, int> dict, BinaryOperatorType op)
{
int p;
dict.TryGetValue(op, out p);
return p;
}
}
}

2587
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

1
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG

@ -201,6 +201,7 @@ TOKENS @@ -201,6 +201,7 @@ TOKENS
"WithEvents"
"WriteOnly"
"Xor"
"Rem"
"Continue"
"Operator"
"Using"

7
src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs

@ -26,13 +26,12 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -26,13 +26,12 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
public override void PrintIdentifier(string identifier)
{
int token = Keywords.GetToken(identifier);
if (token < 0 || Tokens.Unreserved[token]) {
PrintText(identifier);
} else {
if (Keywords.IsNonIdentifierKeyword(identifier)) {
PrintText("[");
PrintText(identifier);
PrintText("]");
} else {
PrintText(identifier);
}
}

40
src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs

@ -1231,7 +1231,19 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1231,7 +1231,19 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
#region Statements
public override object TrackedVisitBlockStatement(BlockStatement blockStatement, object data)
{
if (blockStatement.Parent is BlockStatement) {
outputFormatter.Indent();
outputFormatter.PrintText("If True Then");
outputFormatter.NewLine();
outputFormatter.IndentationLevel += 1;
}
VisitStatementList(blockStatement.Children);
if (blockStatement.Parent is BlockStatement) {
outputFormatter.IndentationLevel -= 1;
outputFormatter.Indent();
outputFormatter.PrintText("End If");
outputFormatter.NewLine();
}
return null;
}
@ -2106,13 +2118,8 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -2106,13 +2118,8 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
op = Tokens.GreaterEqual;
break;
case BinaryOperatorType.InEquality:
TrackedVisit(binaryOperatorExpression.Left, data);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.LessThan);
outputFormatter.PrintToken(Tokens.GreaterThan);
outputFormatter.Space();
TrackedVisit(binaryOperatorExpression.Right, data);
return null;
op = Tokens.NotEqual;
break;
case BinaryOperatorType.NullCoalescing:
outputFormatter.PrintText("If(");
TrackedVisit(binaryOperatorExpression.Left, data);
@ -2129,11 +2136,26 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -2129,11 +2136,26 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
break;
}
BinaryOperatorExpression childBoe = binaryOperatorExpression.Left as BinaryOperatorExpression;
bool requireParenthesis = childBoe != null && OperatorPrecedence.ComparePrecedenceVB(binaryOperatorExpression.Op, childBoe.Op) > 0;
if (requireParenthesis)
outputFormatter.PrintToken(Tokens.OpenParenthesis);
TrackedVisit(binaryOperatorExpression.Left, data);
if (requireParenthesis)
outputFormatter.PrintToken(Tokens.CloseParenthesis);
outputFormatter.Space();
outputFormatter.PrintToken(op);
outputFormatter.Space();
childBoe = binaryOperatorExpression.Right as BinaryOperatorExpression;
requireParenthesis = childBoe != null && OperatorPrecedence.ComparePrecedenceVB(binaryOperatorExpression.Op, childBoe.Op) >= 0;
if (requireParenthesis)
outputFormatter.PrintToken(Tokens.OpenParenthesis);
TrackedVisit(binaryOperatorExpression.Right, data);
if (requireParenthesis)
outputFormatter.PrintToken(Tokens.CloseParenthesis);
return null;
}
@ -2405,10 +2427,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -2405,10 +2427,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.PrintToken(Tokens.CUShort);
break;
case "System.UInt32":
outputFormatter.PrintToken(Tokens.CInt);
outputFormatter.PrintToken(Tokens.CUInt);
break;
case "System.UInt64":
outputFormatter.PrintToken(Tokens.CLng);
outputFormatter.PrintToken(Tokens.CULng);
break;
case "System.Object":
outputFormatter.PrintToken(Tokens.CObj);

45
src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs

@ -424,12 +424,6 @@ End Class @@ -424,12 +424,6 @@ End Class
TestStatement("((IDisposable)o).Dispose();", "DirectCast(o, IDisposable).Dispose()");
}
[Test]
public void PrimitiveCast()
{
TestStatement("a = (int)number;", "a = CInt(number)");
}
[Test]
public void CaseConflictingMethod()
{
@ -451,6 +445,14 @@ End Class @@ -451,6 +445,14 @@ End Class
"Dim i As String(,) = New String(5, 5) {}");
}
[Test]
public void VariableNamedRem()
{
TestStatement("int rem;", "Dim [rem] As Integer");
TestStatement("int Rem;", "Dim [Rem] As Integer");
TestStatement("int a = rem;", "Dim a As Integer = [rem]");
}
[Test]
public void ArrayCast()
{
@ -462,6 +464,25 @@ End Class @@ -462,6 +464,25 @@ End Class
"Dim i As Integer() = DirectCast(obj, Integer())");
}
[Test]
public void PrimitiveCast()
{
TestStatement("int a = (int)number;", "Dim a As Integer = CInt(number)");
TestStatement("byte i = (byte)obj;", "Dim i As Byte = CByte(obj)");
TestStatement("short i = (short)obj;", "Dim i As Short = CShort(obj)");
TestStatement("long i = (long)obj;", "Dim i As Long = CLng(obj)");
}
[Test]
public void PrimitiveUnsignedCast()
{
TestStatement("uint i = (uint)obj;", "Dim i As UInteger = CUInt(obj)");
TestStatement("sbyte i = (sbyte)obj;", "Dim i As SByte = CSByte(obj)");
TestStatement("ushort i = (ushort)obj;", "Dim i As UShort = CUShort(obj)");
TestStatement("ulong i = (ulong)obj;", "Dim i As ULong = CULng(obj)");
}
[Test]
public void InlineAssignment()
{
@ -480,5 +501,17 @@ End Class @@ -480,5 +501,17 @@ End Class
End Class
");
}
[Test]
public void StandaloneBlockStatement()
{
TestStatement("{ int a; } { string a; }",
"If True Then\n" +
"\tDim a As Integer\n" +
"End If\n" +
"If True Then\n" +
"\tDim a As String\n" +
"End If");
}
}
}

9
src/Main/Base/Test/CodeConverterTests.cs

@ -366,6 +366,15 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -366,6 +366,15 @@ namespace ICSharpCode.SharpDevelop.Tests
"Dim c As Integer = a \\ b\n");
}
[Test]
public void OperatorPrecedenceChange()
{
TestStatementsCS2VB("int a = 5;\n" +
"int c = a / a * a;",
"Dim a As Integer = 5\n" +
"Dim c As Integer = (a \\ a) * a\n");
}
#region Casting
[Test]
public void CastToEnum()

Loading…
Cancel
Save