Browse Source

Improved VB -> C# converter.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2202 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
7dfd63273a
  1. 10
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/VBToCSharpConverter.cs
  2. 10
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/CSharpToVBConverter.cs
  3. 1
      src/Libraries/NRefactory/Project/NRefactory.csproj
  4. 11
      src/Libraries/NRefactory/Project/Src/Ast/General/Expression.cs
  5. 1488
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  6. 20
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  7. 16
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs
  8. 15
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
  9. 6
      src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs
  10. 28
      src/Libraries/NRefactory/Project/Src/Visitors/VBNetToCSharpConvertVisitor.cs
  11. 6
      src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs
  12. 2
      src/Libraries/NRefactory/Test/Parser/Statements/ReDimStatementTests.cs
  13. 7
      src/Main/Base/Project/Src/Commands/VBConverter/CSharpConvertBuffer.cs
  14. 2
      src/Main/Base/Project/Src/Commands/VBConverter/ConvertBuffer.cs
  15. 26
      src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs
  16. 2
      src/Main/Base/Project/Src/TextEditor/SearchAndReplace/Gui/AsynchronousWaitDialog.cs
  17. 61
      src/Main/Base/Test/CodeConverterTests.cs
  18. 44
      src/Main/Base/Test/NRefactoryResolverTests.cs
  19. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
  20. 10
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs
  21. 16
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  22. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs
  23. 208
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs

10
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/VBToCSharpConverter.cs

@ -7,13 +7,12 @@ @@ -7,13 +7,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.SharpDevelop.Internal.Templates;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Converter;
@ -42,7 +41,8 @@ namespace CSharpBinding @@ -42,7 +41,8 @@ namespace CSharpBinding
protected override void ConvertAst(CompilationUnit compilationUnit, List<ISpecial> specials, FileProjectItem sourceItem)
{
PreprocessingDirective.VBToCSharp(specials);
compilationUnit.AcceptVisitor(new VBNetToCSharpConvertVisitor(), null);
IProjectContent pc = ParserService.GetProjectContent(sourceItem.Project) ?? ParserService.CurrentProjectContent;
compilationUnit.AcceptVisitor(new VBNetToCSharpConvertVisitor(pc, sourceItem.FileName), null);
}
}
}

10
src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/CSharpToVBConverter.cs

@ -7,18 +7,14 @@ @@ -7,18 +7,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.SharpDevelop.Internal.Templates;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Converter;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Converter;
namespace VBNetBinding
{

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

@ -104,7 +104,6 @@ @@ -104,7 +104,6 @@
<Compile Include="Src\Visitors\ToVBNetConvertVisitor.cs" />
<Compile Include="Src\Visitors\ToVBNetRenameConflictingVariables.cs" />
<Compile Include="Src\Visitors\VBNetConstructsConvertVisitor.cs" />
<Compile Include="Src\Visitors\VBNetToCSharpConvertVisitor.cs" />
<Compile Include="Src\EnvironmentInformationProvider.cs" />
<Compile Include="Src\IAstVisitor.cs" />
<Compile Include="Src\ParserFactory.cs" />

11
src/Libraries/NRefactory/Project/Src/Ast/General/Expression.cs

@ -30,8 +30,8 @@ namespace ICSharpCode.NRefactory.Ast @@ -30,8 +30,8 @@ namespace ICSharpCode.NRefactory.Ast
/// <summary>
/// Returns the existing expression plus the specified integer value.
/// WARNING: This method modifies <paramref name="expr"/> and possibly returns <paramref name="expr"/>
/// again, but it might also create a new expression around <paramref name="expr"/>.
/// The old <paramref name="expr"/> object is not modified, but might be a subobject on the new expression
/// (and thus its parent property is modified).
/// </summary>
public static Expression AddInteger(Expression expr, int value)
{
@ -42,6 +42,9 @@ namespace ICSharpCode.NRefactory.Ast @@ -42,6 +42,9 @@ namespace ICSharpCode.NRefactory.Ast
}
BinaryOperatorExpression boe = expr as BinaryOperatorExpression;
if (boe != null && boe.Op == BinaryOperatorType.Add) {
// clone boe:
boe = new BinaryOperatorExpression(boe.Left, boe.Op, boe.Right);
boe.Right = AddInteger(boe.Right, value);
if (boe.Right is PrimitiveExpression && ((PrimitiveExpression)boe.Right).Value is int) {
int newVal = (int)((PrimitiveExpression)boe.Right).Value;
@ -60,6 +63,10 @@ namespace ICSharpCode.NRefactory.Ast @@ -60,6 +63,10 @@ namespace ICSharpCode.NRefactory.Ast
int newVal = (int)pe.Value - value;
if (newVal == 0)
return boe.Left;
// clone boe:
boe = new BinaryOperatorExpression(boe.Left, boe.Op, boe.Right);
if (newVal < 0) {
newVal = -newVal;
boe.Op = BinaryOperatorType.Add;

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

File diff suppressed because it is too large Load Diff

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

@ -703,7 +703,7 @@ EnumMemberDecl<out FieldDeclaration f> @@ -703,7 +703,7 @@ EnumMemberDecl<out FieldDeclaration f>
f = new FieldDeclaration(attributes);
varDecl = new VariableDeclaration(t.val);
f.Fields.Add(varDecl);
f.StartLocation = t.Location;
f.StartLocation = varDecl.StartLocation = t.Location;
.)
[ "=" Expr<out expr> (. varDecl.Initializer = expr; .) ]
EOL
@ -1320,13 +1320,15 @@ ConstantDeclarator<List<VariableDeclaration> constantDeclaration> @@ -1320,13 +1320,15 @@ ConstantDeclarator<List<VariableDeclaration> constantDeclaration>
Expression expr = null;
TypeReference type = null;
string name = String.Empty;
Location location;
.) =
Identifier (. name = t.val; .)
Identifier (. name = t.val; location = t.Location; .)
["As" TypeName<out type> ]
"=" Expr<out expr>
(.
VariableDeclaration f = new VariableDeclaration(name, expr);
f.TypeReference = type;
f.StartLocation = location;
constantDeclaration.Add(f);
.)
.
@ -1344,6 +1346,7 @@ VariableDeclaratorPartAfterIdentifier<List<VariableDeclaration> fieldDeclaration @@ -1344,6 +1346,7 @@ VariableDeclaratorPartAfterIdentifier<List<VariableDeclaration> fieldDeclaration
TypeReference type = null;
ArrayList rank = null;
List<Expression> dimension = null;
Location startLocation = t.Location;
.) =
[ IF(IsSize() && !IsDims()) ArrayInitializationModifier<out dimension> ]
[ IF(IsDims()) ArrayNameModifier<out rank> ]
@ -1398,7 +1401,12 @@ VariableDeclaratorPartAfterIdentifier<List<VariableDeclaration> fieldDeclaration @@ -1398,7 +1401,12 @@ VariableDeclaratorPartAfterIdentifier<List<VariableDeclaration> fieldDeclaration
.)
[ "=" VariableInitializer<out expr> ]
)
(. fieldDeclaration.Add(new VariableDeclaration(name, expr, type)); .)
(.
VariableDeclaration varDecl = new VariableDeclaration(name, expr, type);
varDecl.StartLocation = startLocation;
varDecl.EndLocation = t.Location;
fieldDeclaration.Add(varDecl);
.)
.
/* 6.8 */
@ -2396,12 +2404,10 @@ EmbeddedStatement<out Statement statement> @@ -2396,12 +2404,10 @@ EmbeddedStatement<out Statement statement>
(.
ReDimStatement reDimStatement = new ReDimStatement(isPreserve);
statement = reDimStatement;
InvocationExpression redimClause = expr as InvocationExpression;
if (redimClause != null) { reDimStatement.ReDimClauses.Add(redimClause); }
SafeAdd(reDimStatement, reDimStatement.ReDimClauses, expr as InvocationExpression);
.)
{ "," ReDimClause<out expr>
(. redimClause = expr as InvocationExpression; .)
(. if (redimClause != null) { reDimStatement.ReDimClauses.Add(redimClause); } .)
(. SafeAdd(reDimStatement, reDimStatement.ReDimClauses, expr as InvocationExpression); .)
}
| /* 10.12.2 */
"Erase"

16
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using ICSharpCode.NRefactory.Ast;
@ -244,5 +245,20 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -244,5 +245,20 @@ namespace ICSharpCode.NRefactory.Parser.VB
if (!(expr is PrimitiveExpression) || (expr as PrimitiveExpression).StringValue != "0")
Error("lower bound of array must be zero");
}
/// <summary>
/// Adds a child item to a collection stored in the parent node.
/// Also set's the item's parent to <paramref name="parent"/>.
/// Does nothing if item is null.
/// </summary>
static void SafeAdd<T>(INode parent, List<T> list, T item) where T : class, INode
{
Debug.Assert(parent != null);
Debug.Assert((parent is INullable) ? !(parent as INullable).IsNull : true);
if (item != null) {
list.Add(item);
item.Parent = parent;
}
}
}
}

15
src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

@ -1034,9 +1034,23 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1034,9 +1034,23 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
public override object TrackedVisitReDimStatement(ReDimStatement reDimStatement, object data)
{
if (!reDimStatement.IsPreserve) {
NotSupported(reDimStatement);
return null;
}
foreach (InvocationExpression ie in reDimStatement.ReDimClauses) {
outputFormatter.PrintText("Array.Resize(ref ");
ie.TargetObject.AcceptVisitor(this, data);
outputFormatter.PrintText(", ");
for (int i = 0; i < ie.Arguments.Count; i++) {
if (i > 0) outputFormatter.PrintText(", ");
Expression.AddInteger(ie.Arguments[i], 1).AcceptVisitor(this, data);
}
outputFormatter.PrintText(")");
outputFormatter.PrintToken(Tokens.Semicolon);
}
return null;
}
public override object TrackedVisitExpressionStatement(ExpressionStatement expressionStatement, object data)
{
@ -2081,6 +2095,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -2081,6 +2095,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.PrintToken(Tokens.Assign);
break;
case AssignmentOperatorType.Add:
case AssignmentOperatorType.ConcatString:
outputFormatter.PrintToken(Tokens.PlusAssign);
break;
case AssignmentOperatorType.Subtract:

6
src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs

@ -14,6 +14,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -14,6 +14,7 @@ namespace ICSharpCode.NRefactory.Visitors
{
public sealed class LocalLookupVariable
{
public readonly string Name;
public readonly TypeReference TypeRef;
public readonly Location StartPos;
public readonly Location EndPos;
@ -21,8 +22,9 @@ namespace ICSharpCode.NRefactory.Visitors @@ -21,8 +22,9 @@ namespace ICSharpCode.NRefactory.Visitors
public readonly bool IsLoopVariable;
public readonly Expression Initializer;
public LocalLookupVariable(TypeReference typeRef, Location startPos, Location endPos, bool isConst, bool isLoopVariable, Expression initializer)
public LocalLookupVariable(string name, TypeReference typeRef, Location startPos, Location endPos, bool isConst, bool isLoopVariable, Expression initializer)
{
this.Name = name;
this.TypeRef = typeRef;
this.StartPos = startPos;
this.EndPos = endPos;
@ -69,7 +71,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -69,7 +71,7 @@ namespace ICSharpCode.NRefactory.Visitors
} else {
list = (List<LocalLookupVariable>)variables[name];
}
list.Add(new LocalLookupVariable(typeRef, startPos, endPos, isConst, isLoopVariable, initializer));
list.Add(new LocalLookupVariable(name, typeRef, startPos, endPos, isConst, isLoopVariable, initializer));
}
public override object VisitWithStatement(WithStatement withStatement, object data)

28
src/Libraries/NRefactory/Project/Src/Visitors/VBNetToCSharpConvertVisitor.cs

@ -1,28 +0,0 @@ @@ -1,28 +0,0 @@
// <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>
using System;
using ICSharpCode.NRefactory.Ast;
namespace ICSharpCode.NRefactory.Visitors
{
/// <summary>
/// This class converts VB.NET constructs to their C# equivalents.
/// Applying the VBNetToCSharpConvertVisitor on a CompilationUnit has the same effect
/// as applying the VBNetConstructsConvertVisitor and ToCSharpConvertVisitor.
/// </summary>
public class VBNetToCSharpConvertVisitor : VBNetConstructsConvertVisitor
{
public override object VisitCompilationUnit(CompilationUnit compilationUnit, object data)
{
base.VisitCompilationUnit(compilationUnit, data);
ToCSharpConvertVisitor v = new ToCSharpConvertVisitor();
compilationUnit.AcceptVisitor(v, data);
return null;
}
}
}

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

@ -24,7 +24,8 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter @@ -24,7 +24,8 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
IParser parser = ParserFactory.CreateParser(SupportedLanguage.VBNet, new StringReader(input));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
parser.CompilationUnit.AcceptVisitor(new VBNetToCSharpConvertVisitor(), null);
parser.CompilationUnit.AcceptVisitor(new VBNetConstructsConvertVisitor(), null);
parser.CompilationUnit.AcceptVisitor(new ToCSharpConvertVisitor(), null);
CSharpOutputVisitor outputVisitor = new CSharpOutputVisitor();
outputVisitor.VisitCompilationUnit(parser.CompilationUnit, null);
Assert.AreEqual("", outputVisitor.Errors.ErrorOutput);
@ -303,6 +304,9 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter @@ -303,6 +304,9 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
{
TestStatement("x = \"Hello \" & \"World\"",
"x = \"Hello \" + \"World\";");
TestStatement("x &= \"Hello\"",
"x += \"Hello\";");
}
[Test]

2
src/Libraries/NRefactory/Test/Parser/Statements/ReDimStatementTests.cs

@ -20,6 +20,8 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -20,6 +20,8 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBNetReDimStatementTest()
{
ReDimStatement reDimStatement = ParseUtilVBNet.ParseStatement<ReDimStatement>("ReDim Preserve MyArray(15)");
Assert.AreEqual(1, reDimStatement.ReDimClauses.Count);
Assert.AreSame(reDimStatement, reDimStatement.ReDimClauses[0].Parent);
}
[Test]

7
src/Main/Base/Project/Src/Commands/VBConverter/CSharpConvertBuffer.cs

@ -14,6 +14,7 @@ using ICSharpCode.NRefactory; @@ -14,6 +14,7 @@ using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
namespace ICSharpCode.SharpDevelop.Commands
{
@ -34,12 +35,14 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -34,12 +35,14 @@ namespace ICSharpCode.SharpDevelop.Commands
ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor output = new ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor();
List<ISpecial> specials = p.Lexer.SpecialTracker.CurrentSpecials;
PreprocessingDirective.VBToCSharp(specials);
new VBNetToCSharpConvertVisitor().VisitCompilationUnit(p.CompilationUnit, null);
IAstVisitor v = new VBNetToCSharpConvertVisitor(ParserService.CurrentProjectContent,
window.ViewContent.FileName);
v.VisitCompilationUnit(p.CompilationUnit, null);
using (SpecialNodesInserter.Install(specials, output)) {
output.VisitCompilationUnit(p.CompilationUnit, null);
}
FileService.NewFile("Generated.CS", "C#", output.Text);
FileService.NewFile("Generated.cs", "C#", output.Text);
}
}
}

2
src/Main/Base/Project/Src/Commands/VBConverter/ConvertBuffer.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -44,7 +44,7 @@ namespace ICSharpCode.SharpDevelop.Commands
vbv.VisitCompilationUnit(p.CompilationUnit, null);
}
FileService.NewFile("Generated.VB", "VBNET", vbv.Text);
FileService.NewFile("Generated.vb", "VBNET", vbv.Text);
}
}
}

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

@ -11,6 +11,7 @@ using System.IO; @@ -11,6 +11,7 @@ using System.IO;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
@ -18,6 +19,7 @@ using ICSharpCode.NRefactory.PrettyPrinter; @@ -18,6 +19,7 @@ using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.SharpDevelop.Project.Commands;
using MSBuild = Microsoft.Build.BuildEngine;
using ICSharpCode.SharpDevelop.Internal.Templates;
using AsynchronousWaitDialog = SearchAndReplace.AsynchronousWaitDialog;
namespace ICSharpCode.SharpDevelop.Project.Converter
{
@ -109,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -109,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
}
}
protected virtual void CopyItems(IProject sourceProject, IProject targetProject)
protected virtual void CopyItems(IProject sourceProject, IProject targetProject, IProgressMonitor monitor)
{
if (sourceProject == null)
throw new ArgumentNullException("sourceProject");
@ -118,7 +120,11 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -118,7 +120,11 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
IProjectItemListProvider targetProjectItems = targetProject as IProjectItemListProvider;
if (targetProjectItems == null)
throw new ArgumentNullException("targetProjectItems");
foreach (ProjectItem item in sourceProject.Items) {
ICollection<ProjectItem> sourceItems = sourceProject.Items;
monitor.BeginTask("Converting", sourceItems.Count, true);
int workDone = 0;
foreach (ProjectItem item in sourceItems) {
FileProjectItem fileItem = item as FileProjectItem;
if (fileItem != null && FileUtility.IsBaseDirectory(sourceProject.Directory, fileItem.FileName)) {
FileProjectItem targetItem = new FileProjectItem(targetProject, fileItem.ItemType);
@ -134,7 +140,12 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -134,7 +140,12 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
} else {
targetProjectItems.AddProjectItem(item.CloneFor(targetProject));
}
if (monitor.IsCancelled) {
return;
}
monitor.WorkDone = ++workDone;
}
monitor.Done();
}
protected StringBuilder conversionLog;
@ -158,16 +169,23 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -158,16 +169,23 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
conversionLog.Append(ResourceService.GetString("ICSharpCode.SharpDevelop.Commands.Convert.TargetDirectory")).Append(": ");
conversionLog.AppendLine(targetProjectDirectory);
IProject targetProject;
using (AsynchronousWaitDialog monitor = AsynchronousWaitDialog.ShowWaitDialog(translatedTitle)) {
Directory.CreateDirectory(targetProjectDirectory);
IProject targetProject = CreateProject(targetProjectDirectory, sourceProject);
targetProject = CreateProject(targetProjectDirectory, sourceProject);
CopyProperties(sourceProject, targetProject);
conversionLog.AppendLine();
CopyItems(sourceProject, targetProject);
CopyItems(sourceProject, targetProject, monitor);
if (monitor.IsCancelled) {
return;
}
conversionLog.AppendLine();
AfterConversion(targetProject);
conversionLog.AppendLine(ResourceService.GetString("ICSharpCode.SharpDevelop.Commands.Convert.ConversionComplete"));
targetProject.Save();
targetProject.Dispose();
}
TreeNode node = ProjectBrowserPad.Instance.SelectedNode;
if (node == null) {
node = ProjectBrowserPad.Instance.SolutionNode;

2
src/Main/Base/Project/Src/TextEditor/SearchAndReplace/Gui/AsynchronousWaitDialog.cs

@ -35,7 +35,7 @@ namespace SearchAndReplace @@ -35,7 +35,7 @@ namespace SearchAndReplace
/// long_running_action();
/// }
/// or:
/// using (IProgressMonitor monitor = AsynchronousWaitDialog.ShowWaitDialog("title")) {
/// using (AsynchronousWaitDialog monitor = AsynchronousWaitDialog.ShowWaitDialog("title")) {
/// long_running_action(monitor);
/// }
/// </summary>

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

@ -34,7 +34,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -34,7 +34,7 @@ namespace ICSharpCode.SharpDevelop.Tests
void TestProgramVB2CS(string sourceCode, string expectedOutput)
{
TestProgram(SupportedLanguage.CSharp, sourceCode, expectedOutput);
TestProgram(SupportedLanguage.VBNet, sourceCode, expectedOutput);
}
void TestProgram(SupportedLanguage sourceLanguage, string sourceCode, string expectedOutput)
@ -72,7 +72,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -72,7 +72,7 @@ namespace ICSharpCode.SharpDevelop.Tests
CSharpToVBNetConvertVisitor convertVisitor = new CSharpToVBNetConvertVisitor(pc, visitor.Cu.FileName);
parser.CompilationUnit.AcceptVisitor(convertVisitor, null);
} else {
VBNetToCSharpConvertVisitor convertVisitor = new VBNetToCSharpConvertVisitor();
VBNetToCSharpConvertVisitor convertVisitor = new VBNetToCSharpConvertVisitor(pc, visitor.Cu.FileName);
parser.CompilationUnit.AcceptVisitor(convertVisitor, null);
}
@ -123,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -123,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Tests
"using System;\n" +
"using Microsoft.VisualBasic;\n" +
"class MyClassName {\n" +
"class MyClassName\n{\n" +
IndentAllLines(expectedCode) +
"}");
}
@ -138,6 +138,16 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -138,6 +138,16 @@ namespace ICSharpCode.SharpDevelop.Tests
IndentAllLines(expectedCode) +
"End Sub");
}
void TestStatementsVB2CS(string sourceCode, string expectedCode)
{
TestMemberVB2CS("Private Sub T()\n" +
IndentAllLines(sourceCode) +
"End Sub",
"private void T()\n{\n" +
IndentAllLines(expectedCode) +
"}");
}
#endregion
[Test]
@ -194,5 +204,50 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -194,5 +204,50 @@ namespace ICSharpCode.SharpDevelop.Tests
"If a = b Then\n" +
"End If");
}
[Test]
public void FixVBCasing()
{
TestStatementsVB2CS("Dim obj as iDisposable\n" +
"Obj.dispose()",
"IDisposable obj;\n" +
"obj.Dispose();");
}
[Test]
public void FixVBCasingAndAddMethodCallParenthesis()
{
TestStatementsVB2CS("Dim i as Integer = appdomain.getcurrentthreadid",
"int i = AppDomain.GetCurrentThreadId();");
}
[Test]
public void IndexerExpression()
{
TestStatementsVB2CS("Dim i(10) as Integer\n" +
"Dim i2 As Integer = i(4)",
"int[] i = new int[11];\n" +
"int i2 = i[4];");
TestStatementsVB2CS("Dim s as string = appdomain.currentdomain.GetAssemblies()(1).location",
"string s = AppDomain.CurrentDomain.GetAssemblies()[1].Location;");
}
[Test]
public void Redim()
{
TestStatementsVB2CS("Dim i(10) as Integer\n" +
"Redim i(20)",
"int[] i = new int[11];\n" +
"i = new int[21];");
}
[Test]
public void RedimPreserve()
{
TestStatementsVB2CS("Dim i(10) as Integer\n" +
"Redim Preserve i(20)",
"int[] i = new int[11];\n" +
"Array.Resize(ref i, 21);");
}
}
}

44
src/Main/Base/Test/NRefactoryResolverTests.cs

@ -362,11 +362,29 @@ class A { @@ -362,11 +362,29 @@ class A {
}
}
";
ResolveResult result = Resolve<LocalResolveResult>(program, "eh(this, new ResolveEventArgs())", 5);
Assert.AreEqual("eh", (result as LocalResolveResult).Field.Name);
LocalResolveResult result = Resolve<LocalResolveResult>(program, "eh(this, new ResolveEventArgs())", 5);
Assert.AreEqual("eh", result.Field.Name);
result = Resolve<MemberResolveResult>(program, "eh(this, new ResolveEventArgs()).GetType(\"bla\")", 5);
Assert.AreEqual("System.Reflection.Module.GetType", (result as MemberResolveResult).ResolvedMember.FullyQualifiedName);
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "eh(this, new ResolveEventArgs()).GetType(\"bla\")", 5);
Assert.AreEqual("System.Reflection.Module.GetType", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
public void DelegateReturnedFromMethodCallTest()
{
string program = @"using System;
class A {
void Method() {
}
abstract Predicate<string> GetHandler();
}
";
ResolveResult result = Resolve<MemberResolveResult>(program, "GetHandler()(abc)", 4);
Assert.AreEqual("System.Boolean", result.ResolvedType.FullyQualifiedName);
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "GetHandler()(abc).ToString()", 4);
Assert.AreEqual("System.Boolean.ToString", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
@ -588,6 +606,24 @@ class TestClass { @@ -588,6 +606,24 @@ class TestClass {
rr = Resolve<ResolveResult>(program, "(short.MaxValue)", 4);
Assert.AreEqual("System.Int16", rr.ResolvedType.FullyQualifiedName);
}
[Test]
public void VBNetArrayReturnedFromMethodTest()
{
string program = @"Module Main
Sub Main()
End Sub
Function F() As String()
End Function
End Module
";
MemberResolveResult result = ResolveVB<MemberResolveResult>(program, "F()(0)", 3);
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName);
Assert.IsFalse(result.ResolvedType.IsArrayReturnType);
Assert.IsInstanceOfType(typeof(IProperty), result.ResolvedMember);
Assert.IsTrue((result.ResolvedMember as IProperty).IsIndexer);
}
#endregion
#region Import namespace tests

1
src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj

@ -92,6 +92,7 @@ @@ -92,6 +92,7 @@
<Compile Include="Src\NRefactoryResolver\NRefactoryInformationProvider.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryResolver.cs" />
<Compile Include="Src\NRefactoryResolver\TypeVisitor.cs" />
<Compile Include="Src\NRefactoryResolver\VBNetToCSharpConvertVisitor.cs" />
<Compile Include="Src\ReflectionLayer\DomPersistence.cs" />
<Compile Include="Src\ReflectionLayer\ReflectionClass.cs" />
<Compile Include="Src\ReflectionLayer\ReflectionEvent.cs" />

10
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs

@ -40,13 +40,19 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -40,13 +40,19 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (!methodDeclaration.Body.IsNull) {
if (_resolver.Initialize(_fileName, methodDeclaration.Body.StartLocation.Y, methodDeclaration.Body.StartLocation.X)) {
_resolver.RunLookupTableVisitor(methodDeclaration);
} else {
LoggingService.Warn("Resolver initialization failed");
}
}
return base.VisitMethodDeclaration(methodDeclaration, data);
}
public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
{
if (_resolver.Initialize(_fileName, propertyDeclaration.BodyStart.Y, propertyDeclaration.BodyStart.X)) {
_resolver.RunLookupTableVisitor(propertyDeclaration);
}
return base.VisitPropertyDeclaration(propertyDeclaration, data);
}
public override object VisitExpressionStatement(ExpressionStatement expressionStatement, object data)
{
if (_resolver.CompilationUnit == null)

16
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -619,10 +619,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -619,10 +619,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return new MixedResolveResult(result, result2);
}
IField CreateLocalVariableField(LocalLookupVariable var, string identifier)
IField CreateLocalVariableField(LocalLookupVariable var)
{
IReturnType type = GetVariableType(var);
IField f = new DefaultField.LocalVariableField(type, identifier, new DomRegion(var.StartPos, var.EndPos), callingClass);
IField f = new DefaultField.LocalVariableField(type, var.Name, new DomRegion(var.StartPos, var.EndPos), callingClass);
if (var.IsConst) {
f.Modifiers |= ModifierEnum.Const;
}
@ -634,7 +634,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -634,7 +634,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (callingMember != null) { // LocalResolveResult requires callingMember to be set
LocalLookupVariable var = SearchVariable(identifier, position);
if (var != null) {
return new LocalResolveResult(callingMember, CreateLocalVariableField(var, identifier));
return new LocalResolveResult(callingMember, CreateLocalVariableField(var));
}
IParameter para = SearchMethodParameter(identifier);
if (para != null) {
@ -726,14 +726,14 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -726,14 +726,14 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return null;
foreach (IMethod method in type.GetMethods()) {
if (IsSameName(identifier, method.Name))
return new MethodResolveResult(callingClass, callingMember, type, identifier);
return new MethodResolveResult(callingClass, callingMember, type, method.Name);
}
if (languageProperties.SupportsExtensionMethods && callingClass != null) {
ArrayList list = new ArrayList();
ResolveResult.AddExtensions(languageProperties, list, callingClass, type);
foreach (IMethodOrProperty mp in list) {
if (mp is IMethod && IsSameName(mp.Name, identifier)) {
return new MethodResolveResult(callingClass, callingMember, type, identifier);
return new MethodResolveResult(callingClass, callingMember, type, mp.Name);
}
}
}
@ -829,7 +829,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -829,7 +829,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
public IReturnType SearchType(string name, NR.Location position)
{
Debug.Assert(!position.IsEmpty);
if (position.IsEmpty)
return projectContent.SearchType(new SearchTypeRequest(name, 0, callingClass, cu, caretLine, caretColumn)).Result;
else
return projectContent.SearchType(new SearchTypeRequest(name, 0, callingClass, cu, position.Line, position.Column)).Result;
}
@ -1069,7 +1071,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1069,7 +1071,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
foreach (LocalLookupVariable v in pair.Value) {
if (IsInside(new NR.Location(caretColumn, caretLine), v.StartPos, v.EndPos)) {
// convert to a field for display
result.Add(CreateLocalVariableField(v, pair.Key));
result.Add(CreateLocalVariableField(v));
break;
}
}

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs

@ -150,6 +150,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -150,6 +150,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (methods.Count == 0 && resolver.Language == SupportedLanguage.VBNet)
return GetVisualBasicIndexer(invocationExpression);
return FindOverload(methods, typeParameters, invocationExpression.Arguments, null);
} else {
// this could be a nested indexer access
if (resolver.Language == SupportedLanguage.VBNet)
return GetVisualBasicIndexer(invocationExpression);
}
return null;
}

208
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs

@ -0,0 +1,208 @@ @@ -0,0 +1,208 @@
// <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>
using System;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
/// <summary>
/// This class converts C# constructs to their VB.NET equivalents.
/// </summary>
public class VBNetToCSharpConvertVisitor : VBNetConstructsConvertVisitor
{
// Fixes identifier casing
// Adds using statements for the default usings
NRefactoryResolver _resolver;
string _fileName;
public VBNetToCSharpConvertVisitor(IProjectContent pc, string fileName)
{
_resolver = new NRefactoryResolver(pc, LanguageProperties.VBNet);
_fileName = fileName;
}
public override object VisitCompilationUnit(CompilationUnit compilationUnit, object data)
{
base.VisitCompilationUnit(compilationUnit, data);
ToCSharpConvertVisitor v = new ToCSharpConvertVisitor();
compilationUnit.AcceptVisitor(v, data);
if (_resolver.ProjectContent.DefaultImports != null) {
int index = 0;
foreach (string u in _resolver.ProjectContent.DefaultImports.Usings) {
compilationUnit.Children.Insert(index++, new UsingDeclaration(u));
}
}
return null;
}
public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
{
// Initialize resolver for method:
if (!methodDeclaration.Body.IsNull) {
if (_resolver.Initialize(_fileName, methodDeclaration.Body.StartLocation.Line, methodDeclaration.Body.StartLocation.Column)) {
_resolver.RunLookupTableVisitor(methodDeclaration);
}
}
return base.VisitMethodDeclaration(methodDeclaration, data);
}
public override object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data)
{
if (!constructorDeclaration.Body.IsNull) {
if (_resolver.Initialize(_fileName, constructorDeclaration.Body.StartLocation.Line, constructorDeclaration.Body.StartLocation.Column)) {
_resolver.RunLookupTableVisitor(constructorDeclaration);
}
}
return base.VisitConstructorDeclaration(constructorDeclaration, data);
}
public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
{
if (_resolver.Initialize(_fileName, propertyDeclaration.BodyStart.Line, propertyDeclaration.BodyStart.Column)) {
_resolver.RunLookupTableVisitor(propertyDeclaration);
}
return base.VisitPropertyDeclaration(propertyDeclaration, data);
}
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
{
base.VisitIdentifierExpression(identifierExpression, data);
if (_resolver.CompilationUnit == null)
return null;
ResolveResult rr = _resolver.ResolveInternal(identifierExpression, ExpressionContext.Default);
string ident = GetIdentifierFromResult(rr);
if (ident != null) {
identifierExpression.Identifier = ident;
}
return null;
}
public override object VisitFieldReferenceExpression(FieldReferenceExpression fieldReferenceExpression, object data)
{
base.VisitFieldReferenceExpression(fieldReferenceExpression, data);
if (_resolver.CompilationUnit == null)
return null;
ResolveResult rr = _resolver.ResolveInternal(fieldReferenceExpression, ExpressionContext.Default);
string ident = GetIdentifierFromResult(rr);
if (ident != null) {
fieldReferenceExpression.FieldName = ident;
}
if (rr is MethodResolveResult
&& !(fieldReferenceExpression.Parent is AddressOfExpression)
&& !(fieldReferenceExpression.Parent is InvocationExpression))
{
ReplaceCurrentNode(new InvocationExpression(fieldReferenceExpression));
}
return rr;
}
public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
{
base.VisitInvocationExpression(invocationExpression, data);
if (_resolver.CompilationUnit == null)
return null;
if (invocationExpression.Arguments.Count > 0
&& !(invocationExpression.Parent is ReDimStatement))
{
MemberResolveResult rr = _resolver.ResolveInternal(invocationExpression, ExpressionContext.Default) as MemberResolveResult;
if (rr != null) {
IProperty p = rr.ResolvedMember as IProperty;
if (p != null) {
ReplaceCurrentNode(new IndexerExpression(invocationExpression.TargetObject, invocationExpression.Arguments));
}
}
}
return null;
}
ClassFinder CreateContext()
{
return new ClassFinder(_resolver.CallingClass, _resolver.CallingMember, _resolver.CaretLine, _resolver.CaretColumn);
}
public override object VisitReDimStatement(ReDimStatement reDimStatement, object data)
{
base.VisitReDimStatement(reDimStatement, data);
if (_resolver.CompilationUnit == null)
return null;
if (!reDimStatement.IsPreserve && reDimStatement.ReDimClauses.Count == 1) {
// replace with array create expression
ResolveResult rr = _resolver.ResolveInternal(reDimStatement.ReDimClauses[0].TargetObject, ExpressionContext.Default);
if (rr != null && rr.ResolvedType != null && rr.ResolvedType.IsArrayReturnType) {
ArrayCreateExpression ace = new ArrayCreateExpression(
Refactoring.CodeGenerator.ConvertType(rr.ResolvedType, CreateContext())
);
foreach (Expression arg in reDimStatement.ReDimClauses[0].Arguments) {
ace.Arguments.Add(Expression.AddInteger(arg, 1));
}
ReplaceCurrentNode(new ExpressionStatement(
new AssignmentExpression(reDimStatement.ReDimClauses[0].TargetObject, AssignmentOperatorType.Assign, ace)));
}
}
return null;
}
public override object VisitLocalVariableDeclaration(LocalVariableDeclaration localVariableDeclaration, object data)
{
FixTypeReferenceCasing(localVariableDeclaration.TypeReference, localVariableDeclaration.StartLocation);
return base.VisitLocalVariableDeclaration(localVariableDeclaration, data);
}
public override object VisitVariableDeclaration(VariableDeclaration variableDeclaration, object data)
{
FixTypeReferenceCasing(variableDeclaration.TypeReference, variableDeclaration.StartLocation);
return base.VisitVariableDeclaration(variableDeclaration, data);
}
void FixTypeReferenceCasing(TypeReference tr, Location loc)
{
if (_resolver.CompilationUnit == null) return;
if (tr.IsNull) return;
IReturnType rt = _resolver.SearchType(tr.SystemType, loc);
if (rt != null) {
IClass c = rt.GetUnderlyingClass();
if (c != null) {
if (string.Equals(tr.Type, c.Name, StringComparison.InvariantCultureIgnoreCase)) {
tr.Type = c.Name;
}
}
}
}
string GetIdentifierFromResult(ResolveResult rr)
{
LocalResolveResult lrr = rr as LocalResolveResult;
if (lrr != null)
return lrr.Field.Name;
MemberResolveResult mrr = rr as MemberResolveResult;
if (mrr != null)
return mrr.ResolvedMember.Name;
MethodResolveResult mtrr = rr as MethodResolveResult;
if (mtrr != null)
return mtrr.Name;
TypeResolveResult trr = rr as TypeResolveResult;
if (trr != null && trr.ResolvedClass != null)
return trr.ResolvedClass.Name;
return null;
}
}
}
Loading…
Cancel
Save