Browse Source

Improved VB -> C# converter.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1187 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
94d339bf97
  1. 89
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs
  2. 42
      src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs
  3. 8
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserControl.cs
  4. 12
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs
  5. 6
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPanel.cs
  6. 3
      src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs

89
src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs

@ -10,6 +10,7 @@ using System.Text;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
using ICSharpCode.NRefactory.Parser; using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB; using ICSharpCode.NRefactory.Parser.VB;
@ -27,6 +28,8 @@ namespace ICSharpCode.NRefactory.Parser
// MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this() // MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this()
// Add Public Modifier to methods and properties // Add Public Modifier to methods and properties
// Override Finalize => Destructor // Override Finalize => Destructor
// IIF(cond, true, false) => ConditionalExpression
// Built-in methods => Prefix with class name
// The following conversions should be implemented in the future: // The following conversions should be implemented in the future:
// Function A() \n A = SomeValue \n End Function -> convert to return statement // Function A() \n A = SomeValue \n End Function -> convert to return statement
@ -198,5 +201,91 @@ namespace ICSharpCode.NRefactory.Parser
return base.Visit(propertyDeclaration, data); return base.Visit(propertyDeclaration, data);
} }
static volatile Dictionary<string, Expression> constantTable;
static volatile Dictionary<string, Expression> methodTable;
public static readonly string VBAssemblyName = "Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
static Dictionary<string, Expression> CreateDictionary(params string[] classNames)
{
Dictionary<string, Expression> d = new Dictionary<string, Expression>(StringComparer.InvariantCultureIgnoreCase);
Assembly asm = Assembly.Load(VBAssemblyName);
foreach (string className in classNames) {
Type type = asm.GetType("Microsoft.VisualBasic." + className);
Expression expr = new IdentifierExpression(className);
foreach (MemberInfo member in type.GetMembers()) {
if (member.DeclaringType == type) { // only direct members
d[member.Name] = expr;
}
}
}
return d;
}
public override object Visit(IdentifierExpression identifierExpression, object data)
{
if (constantTable == null) {
constantTable = CreateDictionary("Constants");
}
Expression expr;
if (constantTable.TryGetValue(identifierExpression.Identifier, out expr)) {
FieldReferenceExpression fre = new FieldReferenceExpression(expr, identifierExpression.Identifier);
ReplaceCurrentNode(fre);
return base.Visit(fre, data);
}
return base.Visit(identifierExpression, data);
}
public override object Visit(InvocationExpression invocationExpression, object data)
{
IdentifierExpression ident = invocationExpression.TargetObject as IdentifierExpression;
if (ident != null) {
if ("IIF".Equals(ident.Identifier, StringComparison.InvariantCultureIgnoreCase)
&& invocationExpression.Arguments.Count == 3)
{
ConditionalExpression ce = new ConditionalExpression(invocationExpression.Arguments[0],
invocationExpression.Arguments[1],
invocationExpression.Arguments[2]);
ReplaceCurrentNode(new ParenthesizedExpression(ce));
return base.Visit(ce, data);
}
if ("IsNothing".Equals(ident.Identifier, StringComparison.InvariantCultureIgnoreCase)
&& invocationExpression.Arguments.Count == 1)
{
BinaryOperatorExpression boe = new BinaryOperatorExpression(invocationExpression.Arguments[0],
BinaryOperatorType.ReferenceEquality,
new PrimitiveExpression(null, "null"));
ReplaceCurrentNode(new ParenthesizedExpression(boe));
return base.Visit(boe, data);
}
if (methodTable == null) {
methodTable = CreateDictionary("Conversion", "FileSystem", "Financial", "Information",
"Interaction", "Strings", "VBMath");
}
Expression expr;
if (methodTable.TryGetValue(ident.Identifier, out expr)) {
FieldReferenceExpression fre = new FieldReferenceExpression(expr, ident.Identifier);
invocationExpression.TargetObject = fre;
}
}
return base.Visit(invocationExpression, data);
}
public override object Visit(UnaryOperatorExpression unaryOperatorExpression, object data)
{
base.Visit(unaryOperatorExpression, data);
if (unaryOperatorExpression.Op == UnaryOperatorType.Not) {
ParenthesizedExpression pe = unaryOperatorExpression.Expression as ParenthesizedExpression;
if (pe != null) {
BinaryOperatorExpression boe = pe.Expression as BinaryOperatorExpression;
if (boe != null && boe.Op == BinaryOperatorType.ReferenceEquality) {
boe.Op = BinaryOperatorType.ReferenceInequality;
ReplaceCurrentNode(pe);
}
}
}
return null;
}
} }
} }

42
src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs

@ -188,5 +188,47 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
"\tDead();\n" + "\tDead();\n" +
"}"); "}");
} }
[Test]
public void IIFExpression()
{
TestStatement("a = iif(cond, trueEx, falseEx)",
"a = (cond ? trueEx : falseEx);");
}
[Test]
public void IsNothing()
{
TestStatement("a = IsNothing(ex)",
"a = (ex == null);");
}
[Test]
public void IsNotNothing()
{
TestStatement("a = Not IsNothing(ex)",
"a = (ex != null);");
}
[Test]
public void CompatibilityMethods()
{
TestStatement("Beep()",
"Interaction.Beep();");
}
[Test]
public void EqualsCall()
{
TestStatement("Equals(a, b)",
"Equals(a, b);");
}
[Test]
public void VBConstants()
{
TestStatement("a = vbYesNo",
"a = Constants.vbYesNo;");
}
} }
} }

8
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserControl.cs

@ -47,6 +47,12 @@ namespace ICSharpCode.SharpDevelop.Project
} }
} }
public AbstractProjectBrowserTreeNode RootNode {
get {
return treeView.Nodes[0] as AbstractProjectBrowserTreeNode;
}
}
public ExtTreeView TreeView { public ExtTreeView TreeView {
get { get {
return treeView; return treeView;
@ -140,7 +146,7 @@ namespace ICSharpCode.SharpDevelop.Project
return FindFileNode(treeView.Nodes, fileName); return FindFileNode(treeView.Nodes, fileName);
} }
// stores the fileName of the last selected target so // stores the fileName of the last selected target so
// that we can select it again on opening a folder // that we can select it again on opening a folder
string lastSelectionTarget; string lastSelectionTarget;

12
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs

@ -20,6 +20,9 @@ namespace ICSharpCode.SharpDevelop.Project
static ProjectBrowserPad instance; static ProjectBrowserPad instance;
public static ProjectBrowserPad Instance { public static ProjectBrowserPad Instance {
get { get {
if (instance == null) {
WorkbenchSingleton.Workbench.GetPad(typeof(ProjectBrowserPad)).CreatePad();
}
return instance; return instance;
} }
} }
@ -31,6 +34,15 @@ namespace ICSharpCode.SharpDevelop.Project
} }
} }
/// <summary>
/// Gets the root node of the project tree view.
/// </summary>
public AbstractProjectBrowserTreeNode SolutionNode {
get {
return projectBrowserPanel.RootNode;
}
}
public ProjectBrowserControl ProjectBrowserControl { public ProjectBrowserControl ProjectBrowserControl {
get { get {
return projectBrowserPanel.ProjectBrowserControl; return projectBrowserPanel.ProjectBrowserControl;

6
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPanel.cs

@ -29,6 +29,12 @@ namespace ICSharpCode.SharpDevelop.Project
} }
} }
public AbstractProjectBrowserTreeNode RootNode {
get {
return projectBrowserControl.RootNode;
}
}
public ProjectBrowserControl ProjectBrowserControl { public ProjectBrowserControl ProjectBrowserControl {
get { get {
return projectBrowserControl; return projectBrowserControl;

3
src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs

@ -140,6 +140,9 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
targetProject.Save(); targetProject.Save();
targetProject.Dispose(); targetProject.Dispose();
TreeNode node = ProjectBrowserPad.Instance.SelectedNode; TreeNode node = ProjectBrowserPad.Instance.SelectedNode;
if (node == null) {
node = ProjectBrowserPad.Instance.SolutionNode;
}
while (node != null) { while (node != null) {
if (node is ISolutionFolderNode) { if (node is ISolutionFolderNode) {
AddExitingProjectToSolution.AddProject((ISolutionFolderNode)node, targetProject.FileName); AddExitingProjectToSolution.AddProject((ISolutionFolderNode)node, targetProject.FileName);

Loading…
Cancel
Save