📄 csharp2vbconverter.cs
字号:
/*----------------------------------------------------------------------
Author: Kamal Patel
Date: Feb 26 2002 AD
Desc: Receives C# source code as a parameter and converts
it to VB .NET
Version: 1.2
Copyright: (c) Kamal Patel
Please read the copyright notice in Copyright.doc
Email: kppatel@yahoo.com
URL: http://www.KamalPatel.net
-----------------------------------------------------------------------*/
using System;
using System.Text.RegularExpressions;
using System.Text;
using System.Collections;
namespace ConvertCSharp2VB
{
/// <summary>
/// Converts a C# source code block to VB.Net code block
/// </summary>
public class CSharpToVBConverter
{
private string[] Modifiers;
private string[] DataTypes;
private string[] MethodModifiers = {"new","public", "protected", "internal", "private", "static", "virtual", "abstract", "override", "sealed", "extern", "void"};
private ArrayList Stack = new ArrayList();
private static int nStackCounter = -1;
private string TokenStarter = "<" + "__" ;
private string TokenEnder = "__" + ">" ;
private string BlankLineToken = "<__0__>";
private string EndOfAssignedArray = " _ 'CSharp2VBArray";
public CSharpToVBConverter()
{
//Create the Modifiers collection
Modifiers = new string[7];
Modifiers[0] = "internal";
Modifiers[1] = "new";
Modifiers[2] = "private";
Modifiers[3] = "protected";
Modifiers[4] = "public";
Modifiers[5] = "readonly";
Modifiers[6] = "static";
//Create the DataTypes collection
DataTypes = new string[15];
DataTypes[0] = "sbyte";
DataTypes[1] = "short";
DataTypes[2] = "int";
DataTypes[3] = "long";
DataTypes[4] = "byte";
DataTypes[5] = "ushort";
DataTypes[6] = "unit";
DataTypes[7] = "ulong";
DataTypes[8] = "float";
DataTypes[9] = "double";
DataTypes[10] = "decimal";
DataTypes[11] = "bool";
DataTypes[12] = "char";
DataTypes[13] = "object";
DataTypes[14] = "string";
}
/// <summary>
/// Receives a C# code block in string format as a parameter and converts it into VB.Net code
/// </summary>
/// <param name="tcText"></param>
/// <returns></returns>
public string Execute(string tcText)
{
string lcText = "";
//Reset the stack count
CSharpToVBConverter.nStackCounter = -1;
//Startup work, Initialization and break the lines for visibility
tcText = this.FixLines(this.HandleBlankLines(tcText)); //blank lines
tcText = this.FixLines(this.PushQuotesToStack(tcText, "\"")); //double quotes
tcText = this.FixLines(this.PushQuotesToStack(tcText, "\'")); //single quotes
tcText = this.FixLines(this.PushCommentsToStack(tcText)); //comments
tcText = this.FixLines(this.HandleLineBreakDown(tcText));
//Multi-Line comments
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleMultiLineComments(tcText));
}
catch
{
tcText = "'Error: Converting Multi-Line comments \r\n" + lcText;
}
//Attributes (Also handles casting conversions)
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleAttributes(tcText));
}
catch
{
tcText = "'Error: Converting Attributes \r\n" + lcText;
}
//return tcText;
////////////////////////////////////////////////////////////////////////
///Loops
////////////////////////////////////////////////////////////////////////
//ForEach Loop
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "foreach", 0));
}
catch
{
tcText = "'Error: Converting For Each-Loops \r\n" + lcText;
}
//Do Loop
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "do", 0));
}
catch
{
tcText = "'Error: Converting Do-While Loops \r\n" + lcText;
}
//while-until
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "while", 0));
}
catch
{
tcText = "'Error: Converting While-Loops \r\n" + lcText;
}
//For Loop
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleForBlocks(tcText));
}
catch
{
tcText = "'Error: Converting For-Loops \r\n" + lcText;
}
////////////////////////////////////////////////////////////////////////
///Conditional Blocks
////////////////////////////////////////////////////////////////////////
//Try-Catch-Finally
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleTryCatchFinally(tcText));
}
catch
{
tcText = "'Error: Converting Try-Catch-Finally Blocks \r\n" + lcText;
}
//Catch
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "catch", 1));
}
catch
{
tcText = "'Error: Converting Catch bolcks in Try-Catch-Finally \r\n" + lcText;
}
//If-Else-End If Blocks
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleIfBlock(tcText));
}
catch
{
tcText = "'Error: Converting If-Else-End If Blocks \r\n" + lcText;
}
//Switch Blocks
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "switch", 0));
}
catch
{
tcText = "'Error: Converting Switch Blocks \r\n" + lcText;
}
////////////////////////////////////////////////////////////////////////
///classes, structs, enums, namespaces, properties
////////////////////////////////////////////////////////////////////////
//structs
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "struct ", 1));
}
catch
{
tcText = "'Error: Converting Structures \r\n" + lcText;
}
//Classes
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "class ", 1));
}
catch
{
tcText = "'Error: Converting Classes \r\n" + lcText;
}
//Interfaces
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "interface ", 1));
}
catch
{
tcText = "'Error: Converting Interfaces \r\n" + lcText;
}
//Enumerators
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "enum", 1));
}
catch
{
tcText = "'Error: Converting Enumerators \r\n" + lcText;
}
//Namespaces
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "namespace", 0));
}
catch
{
tcText = "'Error: Converting Namespaces \r\n" + lcText;
}
////////////////////////////////////////////////////////////////////////
///Math operations, declarations and methods
////////////////////////////////////////////////////////////////////////
// Object++ to Object = Object + 1
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleMathOperations(tcText)); //Has to be before declarations
}
catch
{
tcText = "'Error: Converting Math operations Object++ to Object = Object + 1 \r\n" + lcText;
}
// Declarations and Fields
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleDeclaration(tcText));
}
catch
{
tcText = "'Error: Converting Declarations and Fields \r\n" + lcText;
}
// Conditional Operator ?:
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleConditionalOperator(tcText));
}
catch
{
tcText = "'Error: Converting Conditional operator ?: \r\n" + lcText;
}
// Methods, Functions and Constructors
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleMethod(tcText));
}
catch
{
tcText = "'Error: Converting Methods, Functions and Constructors \r\n" + lcText;
}
//Properties
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleProperties(tcText)); //Has to be after methods, classes and structs
}
catch
{
tcText = "'Error: Converting Properties \r\n" + lcText;
}
//Case Blocks (Moved after methods and properties)
try
{
lcText = tcText;
tcText = this.FixLines(this.CommonHandler(tcText, "case", 0));
}
catch
{
tcText = "'Error: Converting Case Blocks \r\n" + lcText;
}
//Handle casting
try
{
lcText = tcText;
tcText = this.FixLines(this.HandleCasting(tcText));
}
catch
{
tcText = "'Error: Converting Casting from C# to VB.Net \r\n" + lcText;
}
//Ground work and cleanup
tcText = this.HandleReplacements(tcText);
tcText = this.FixLines(this.PopQuotesFromStack(tcText));
tcText = this.HandlePostReplacements(tcText);
tcText = tcText.TrimEnd() + "\r\n\r\n" + this.GetFooter();
return tcText;
}
protected string FixLines(string tcText)
{
tcText = tcText.Replace("\r", "");
return tcText.Replace("\n", "\r\n");
}
/// <summary>
/// Called by HandleLineBreakDown() method so moving the brackets on next line is common
/// </summary>
/// <param name="tsb"></param>
/// <param name="tcString"></param>
/// <param name="tcBlankToken"></param>
protected void HandleBrakets(ref StringBuilder tsb, string tcString, string tcBlankToken)
{
tsb.Append(tcBlankToken);
string lcString = tcString.Trim();
for(int j=0; j<lcString.Length; j++)
{
if(lcString[j] == '{' || lcString[j] == '}')
{
tsb.Append("\n" + tcBlankToken + lcString[j].ToString() + "\n");
if(lcString[j] == '{')
tsb.Append(tcBlankToken + " ");
}
else
{
tsb.Append(lcString[j]);
}
}
}
/// <summary>
/// Returns a new token number
/// </summary>
/// <returns></returns>
protected string GetNewToken()
{
// Get the new token
CSharpToVBConverter.nStackCounter = CSharpToVBConverter.nStackCounter + 1;
return this.TokenStarter + nStackCounter.ToString() + this.TokenEnder;
}
/// <summary>
/// Handles the blank lines by adding a token.
/// Later on when the real tokens are poped it will be taken care of
/// </summary>
/// <param name="tcString"></param>
/// <returns></returns>
private string HandleBlankLines(string tcText)
{
//get the first token the 0th one
string cToken = this.GetNewToken();
//this.BlankLineToken = cToken;
string cOriginal = " ";
MappingToken o = new MappingToken();
o.cOriginal = cOriginal;
o.cToken = cToken;
this.Stack.Add(o);
StringBuilder sb = new StringBuilder();
string[] aText = tcText.Split('\n');
string lcStr;
for(int i =0; i < aText.Length; i++)
{
lcStr = aText[i].Trim();
if(lcStr.Length == 0)
{
aText[i] = cToken;
}
sb.Append(aText[i] + "\n");
}
return sb.ToString();
}
/// <summary>
/// Pops all the quotes tokens from the stack
/// </summary>
/// <param name="tcText"></param>
/// <returns></returns>
/// <todo>
/// Escape charactes should be handled appropriately at a later time
/// </todo>
private string PopQuotesFromStack(string tcText)
{
StringBuilder sb = new StringBuilder();
string[] aText = tcText.Split('\n');
string lcStr;
for(int i =0; i < aText.Length; i++)
{
lcStr = aText[i].Trim();
if(this.IsHandled(lcStr))
{
sb.Append(aText[i]+ "\n");
continue;
}
//Handle the double quotes first
int nStart = aText[i].IndexOf("<__");
if(nStart < 0)
{
//no quotes
sb.Append(aText[i]+ "\n");
continue;
}
int nEnd = aText[i].IndexOf("__>", nStart+1);
if(nEnd < 0)
{
//no quotes
sb.Append(aText[i]+ "\n");
continue;
}
string cTokenNo = aText[i].Substring(nStart + 3, nEnd-(nStart+3));
string cOriginal = ((MappingToken)this.Stack[int.Parse(cTokenNo)]).cOriginal;
aText[i] = aText[i].Substring(0, nStart) + cOriginal + aText[i].Substring(nEnd+3);
i--;
continue;
}
return sb.ToString();
}
/// <summary>
/// Locate the quoted strings and push them on the stack
/// </summary>
/// <param name="tcText"></param>
/// <param name="tcCheckString"></param>
/// <returns></returns>
/// <todo>
/// Escape charactes should be handled appropriately at a later time
/// </todo>
private string PushQuotesToStack(string tcText, string tcCheckString)
{
StringBuilder sb = new StringBuilder();
string[] aText = tcText.Split('\n');
string lcStr;
for(int i =0; i < aText.Length; i++)
{
lcStr = aText[i].Trim();
if(this.IsHandled(lcStr))
{
sb.Append(aText[i]+ "\n");
continue;
}
//Handle the double quotes first
int nStart = aText[i].IndexOf(tcCheckString);
if(nStart < 0)
{
//no quotes
sb.Append(aText[i]+ "\n");
continue;
}
int nEnd = aText[i].IndexOf(tcCheckString, nStart+1);
if(nEnd < 0)
{
//no quotes
sb.Append(aText[i]+ "\n");
continue;
}
string cOriginal = aText[i].Substring(nStart, nEnd-nStart+1);
string cToken = this.GetNewToken();
aText[i] = aText[i].Substring(0, nStart) + cToken + aText[i].Substring(nEnd+1);
//Fix the original string to be double quotes as VB does not support
//single quotes
if(tcCheckString == "\'")
{
cOriginal = cOriginal.Replace("\'", "\"") + "c";
}
MappingToken o = new MappingToken();
o.cOriginal = cOriginal;
o.cToken = cToken;
this.Stack.Add(o);
i--;
continue;
}
return sb.ToString();
}
private string PushCommentsToStack(string tcText)
{
StringBuilder sb = new StringBuilder();
string[] aText = tcText.Split('\n');
string lcStr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -