Browse Source

Improved C# <-> VB conversion.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@959 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
02d57c4611
  1. 3
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 10
      src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorStatements.cs
  3. 6
      src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Converter.cs
  4. 1
      src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/NRefactoryToBooConverter.csproj
  5. 30
      src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RefactoryVisitor.cs
  6. 4
      src/Libraries/NRefactory/Project/NRefactory.csproj
  7. 83
      src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs
  8. 5
      src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs
  9. 25
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/GlobalScope/CompilationUnit.cs
  10. 16
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/ForStatement.cs
  11. 28
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/IfElseStatement.cs
  12. 11
      src/Libraries/NRefactory/Project/Src/Parser/AST/VBNet/Statements/ForNextStatement.cs
  13. 10
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  14. 10
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  15. 4
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  16. 4
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  17. 243
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/CSharpConstructsVisitor.cs
  18. 216
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/CSharpToVBNetConvertVisitor.cs
  19. 24
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/PrefixFieldsVisitor.cs
  20. 30
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToCSharpConvertVisitor.cs
  21. 167
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToVBNetConvertVisitor.cs
  22. 59
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs
  23. 41
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetToCSharpConvertVisitor.cs
  24. 57
      src/Libraries/NRefactory/Test/Output/VBNet/ConverterTest.cs

3
AddIns/ICSharpCode.SharpDevelop.addin

@ -2,7 +2,8 @@
author = "Mike Krueger" author = "Mike Krueger"
copyright = "prj:///doc/copyright.txt" copyright = "prj:///doc/copyright.txt"
url = "http://www.icsharpcode.net" url = "http://www.icsharpcode.net"
description = "SharpDevelop main module"> description = "SharpDevelop main module"
addInManagerHidden = "true">
<Manifest> <Manifest>
<Identity name = "SharpDevelop" version = "@EntryAssemblyVersion"/> <Identity name = "SharpDevelop" version = "@EntryAssemblyVersion"/>

10
src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorStatements.cs

@ -70,7 +70,7 @@ namespace NRefactoryToBooConverter
{ {
if (statement == null || statement.IsNull) if (statement == null || statement.IsNull)
return null; return null;
ArrayList statements = new ArrayList(1); List<Statement> statements = new List<Statement>(1);
statements.Add(statement); statements.Add(statement);
return ConvertBlock(statements); return ConvertBlock(statements);
} }
@ -83,7 +83,7 @@ namespace NRefactoryToBooConverter
return b; return b;
} }
B.Block ConvertBlock(ArrayList statements) B.Block ConvertBlock(List<Statement> statements)
{ {
if (statements.Count == 1) { if (statements.Count == 1) {
if (statements[0] is BlockStatement) if (statements[0] is BlockStatement)
@ -156,7 +156,7 @@ namespace NRefactoryToBooConverter
/// break $conditionType $condition /// break $conditionType $condition
/// $body /// $body
/// </summary> /// </summary>
ArrayList MakeManualLoop(INode node, ArrayList initializers, B.StatementModifierType conditionType, Expression condition, ArrayList iterators, Statement body) ArrayList MakeManualLoop(INode node, List<Statement> initializers, B.StatementModifierType conditionType, Expression condition, List<Statement> iterators, Statement body)
{ {
// we use this "while true" form because "continue" must not skip the iterator. // we use this "while true" form because "continue" must not skip the iterator.
@ -183,9 +183,9 @@ namespace NRefactoryToBooConverter
ArrayList MakeManualLoop(ForNextStatement forNextStatement) ArrayList MakeManualLoop(ForNextStatement forNextStatement)
{ {
Expression var = new IdentifierExpression(forNextStatement.VariableName); Expression var = new IdentifierExpression(forNextStatement.VariableName);
ArrayList initializers = new ArrayList(1); List<Statement> initializers = new List<Statement>(1);
initializers.Add(new StatementExpression(new AssignmentExpression(var, AssignmentOperatorType.Assign, forNextStatement.Start))); initializers.Add(new StatementExpression(new AssignmentExpression(var, AssignmentOperatorType.Assign, forNextStatement.Start)));
ArrayList iterators = new ArrayList(1); List<Statement> iterators = new List<Statement>(1);
Expression step = forNextStatement.Step; Expression step = forNextStatement.Step;
if (step == null || step.IsNull) if (step == null || step.IsNull)
step = new PrimitiveExpression(1, "1"); step = new PrimitiveExpression(1, "1");

6
src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Converter.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using ICSharpCode.NRefactory.Parser;
using NR = ICSharpCode.NRefactory.Parser.AST; using NR = ICSharpCode.NRefactory.Parser.AST;
using Boo.Lang.Compiler; using Boo.Lang.Compiler;
using Boo.Lang.Compiler.Ast; using Boo.Lang.Compiler.Ast;
@ -23,7 +24,10 @@ namespace NRefactoryToBooConverter
throw new ArgumentNullException("cu"); throw new ArgumentNullException("cu");
if (settings == null) if (settings == null)
throw new ArgumentNullException("settings"); throw new ArgumentNullException("settings");
cu.AcceptVisitor(new RefactoryVisitor(), null); if (settings.IsVisualBasic)
cu.AcceptVisitor(new VBNetConstructsConvertVisitor(), null);
else
cu.AcceptVisitor(new CSharpConstructsVisitor(), null);
return (Module)cu.AcceptVisitor(new ConvertVisitor(settings), null); return (Module)cu.AcceptVisitor(new ConvertVisitor(settings), null);
} }

1
src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/NRefactoryToBooConverter.csproj

@ -35,7 +35,6 @@
<ItemGroup> <ItemGroup>
<Compile Include="AssemblyInfo.cs" /> <Compile Include="AssemblyInfo.cs" />
<Compile Include="Converter.cs" /> <Compile Include="Converter.cs" />
<Compile Include="RefactoryVisitor.cs" />
<Compile Include="ConvertVisitor.cs" /> <Compile Include="ConvertVisitor.cs" />
<Compile Include="Parser.cs" /> <Compile Include="Parser.cs" />
<Compile Include="ConvertVisitorGlobal.cs" /> <Compile Include="ConvertVisitorGlobal.cs" />

30
src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RefactoryVisitor.cs

@ -1,30 +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.Parser;
using ICSharpCode.NRefactory.Parser.AST;
namespace NRefactoryToBooConverter
{
/// <summary>
/// Visitor that prepares the conversion by converting source-language specific constructs
/// into "better suited" constructs.
/// </summary>
/// <example>
/// ForStatements of the form "for(int i = Start; i &lt; End; i += Step)" are
/// converted to "For i As Integer = Start To End Step Step" (VB-Style) which has the better-matching
/// Boo representation of "for i as int in range(Start, End, Step):"
/// </example>
public class RefactoryVisitor : CSharpToVBNetConvertVisitor
{
public RefactoryVisitor()
{
base.RenameConflictingFieldNames = false; // do not rename fields to VB-style
}
}
}

4
src/Libraries/NRefactory/Project/NRefactory.csproj

@ -200,6 +200,10 @@
<Compile Include="Src\Output\CodeDOM\CodeDOMVerboseOutputGenerator.cs" /> <Compile Include="Src\Output\CodeDOM\CodeDOMVerboseOutputGenerator.cs" />
<Compile Include="Src\Parser\AST\CSharp\Expressions\DefaultValueExpression.cs" /> <Compile Include="Src\Parser\AST\CSharp\Expressions\DefaultValueExpression.cs" />
<Compile Include="Src\Parser\AST\General\TypeLevel\InterfaceImplementation.cs" /> <Compile Include="Src\Parser\AST\General\TypeLevel\InterfaceImplementation.cs" />
<Compile Include="Src\Parser\Visitors\VBNetConstructsConvertVisitor.cs" />
<Compile Include="Src\Parser\Visitors\CSharpConstructsVisitor.cs" />
<Compile Include="Src\Parser\Visitors\ToCSharpConvertVisitor.cs" />
<Compile Include="Src\Parser\Visitors\ToVBNetConvertVisitor.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Src\Lexer\CSharp\KeywordList.txt" /> <Content Include="Src\Lexer\CSharp\KeywordList.txt" />

83
src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs

@ -963,14 +963,15 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
{ {
for (int i = 0; i < localVariableDeclaration.Variables.Count; ++i) { for (int i = 0; i < localVariableDeclaration.Variables.Count; ++i) {
VariableDeclaration v = (VariableDeclaration)localVariableDeclaration.Variables[i]; VariableDeclaration v = (VariableDeclaration)localVariableDeclaration.Variables[i];
if (i > 0) {
outputFormatter.NewLine(); outputFormatter.NewLine();
outputFormatter.Indent(); outputFormatter.Indent();
}
OutputModifier(localVariableDeclaration.Modifier); OutputModifier(localVariableDeclaration.Modifier);
nodeTracker.TrackedVisit(localVariableDeclaration.GetTypeForVariable(i), data); nodeTracker.TrackedVisit(localVariableDeclaration.GetTypeForVariable(i), data);
outputFormatter.Space(); outputFormatter.Space();
nodeTracker.TrackedVisit(v, data); nodeTracker.TrackedVisit(v, data);
outputFormatter.PrintToken(Tokens.Semicolon); outputFormatter.PrintToken(Tokens.Semicolon);
outputFormatter.NewLine();
} }
return null; return null;
} }
@ -1011,12 +1012,15 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.PrintToken(Tokens.OpenParenthesis); outputFormatter.PrintToken(Tokens.OpenParenthesis);
nodeTracker.TrackedVisit(ifElseStatement.Condition, data); nodeTracker.TrackedVisit(ifElseStatement.Condition, data);
outputFormatter.PrintToken(Tokens.CloseParenthesis); outputFormatter.PrintToken(Tokens.CloseParenthesis);
outputFormatter.NewLine(); if (ifElseStatement.TrueStatement.Count > 1) {
++outputFormatter.IndentationLevel; outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
}
foreach (Statement stmt in ifElseStatement.TrueStatement) { foreach (Statement stmt in ifElseStatement.TrueStatement) {
nodeTracker.TrackedVisit(stmt, data); nodeTracker.TrackedVisit(stmt, data);
} }
--outputFormatter.IndentationLevel; if (ifElseStatement.TrueStatement.Count > 1) {
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
}
foreach (ElseIfSection elseIfSection in ifElseStatement.ElseIfSections) { foreach (ElseIfSection elseIfSection in ifElseStatement.ElseIfSections) {
nodeTracker.TrackedVisit(elseIfSection, data); nodeTracker.TrackedVisit(elseIfSection, data);
@ -1025,12 +1029,15 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
if (ifElseStatement.HasElseStatements) { if (ifElseStatement.HasElseStatements) {
outputFormatter.Indent(); outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.Else); outputFormatter.PrintToken(Tokens.Else);
outputFormatter.NewLine(); if (ifElseStatement.FalseStatement.Count > 1) {
++outputFormatter.IndentationLevel; outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
}
foreach (Statement stmt in ifElseStatement.FalseStatement) { foreach (Statement stmt in ifElseStatement.FalseStatement) {
nodeTracker.TrackedVisit(stmt, data); nodeTracker.TrackedVisit(stmt, data);
} }
--outputFormatter.IndentationLevel; if (ifElseStatement.FalseStatement.Count > 1) {
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
}
} }
return null; return null;
@ -1362,13 +1369,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
public object Visit(TryCatchStatement tryCatchStatement, object data) public object Visit(TryCatchStatement tryCatchStatement, object data)
{ {
outputFormatter.PrintToken(Tokens.Try); outputFormatter.PrintToken(Tokens.Try);
outputFormatter.Space(); WriteEmbeddedStatement(tryCatchStatement.StatementBlock);
outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
nodeTracker.TrackedVisit(tryCatchStatement.StatementBlock, data);
--outputFormatter.IndentationLevel;
foreach (CatchClause catchClause in tryCatchStatement.CatchClauses) { foreach (CatchClause catchClause in tryCatchStatement.CatchClauses) {
nodeTracker.TrackedVisit(catchClause, data); nodeTracker.TrackedVisit(catchClause, data);
@ -1376,26 +1377,15 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
if (!tryCatchStatement.FinallyBlock.IsNull) { if (!tryCatchStatement.FinallyBlock.IsNull) {
outputFormatter.Indent(); outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Finally); outputFormatter.PrintToken(Tokens.Finally);
outputFormatter.Space(); WriteEmbeddedStatement(tryCatchStatement.FinallyBlock);
outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
nodeTracker.TrackedVisit(tryCatchStatement.FinallyBlock, data);
--outputFormatter.IndentationLevel;
} }
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
return null; return null;
} }
public object Visit(CatchClause catchClause, object data) public object Visit(CatchClause catchClause, object data)
{ {
outputFormatter.Indent(); outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Catch); outputFormatter.PrintToken(Tokens.Catch);
if (!catchClause.TypeReference.IsNull) { if (!catchClause.TypeReference.IsNull) {
@ -1410,12 +1400,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
} }
outputFormatter.PrintToken(Tokens.CloseParenthesis); outputFormatter.PrintToken(Tokens.CloseParenthesis);
} }
outputFormatter.Space(); WriteEmbeddedStatement(catchClause.StatementBlock);
outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
nodeTracker.TrackedVisit(catchClause.StatementBlock, data);
--outputFormatter.IndentationLevel;
return null; return null;
} }
@ -1441,53 +1426,29 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.Space(); outputFormatter.Space();
AppendCommaSeparatedList(fixedStatement.PointerDeclarators); AppendCommaSeparatedList(fixedStatement.PointerDeclarators);
outputFormatter.PrintToken(Tokens.CloseParenthesis); outputFormatter.PrintToken(Tokens.CloseParenthesis);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.OpenCurlyBrace); WriteEmbeddedStatement(fixedStatement.EmbeddedStatement);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
if (fixedStatement.EmbeddedStatement is BlockStatement) {
nodeTracker.TrackedVisit(fixedStatement.EmbeddedStatement, false);
} else {
nodeTracker.TrackedVisit(fixedStatement.EmbeddedStatement, data);
}
--outputFormatter.IndentationLevel;
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
return null; return null;
} }
public object Visit(UnsafeStatement unsafeStatement, object data) public object Visit(UnsafeStatement unsafeStatement, object data)
{ {
outputFormatter.PrintToken(Tokens.Unsafe); outputFormatter.PrintToken(Tokens.Unsafe);
nodeTracker.TrackedVisit(unsafeStatement.Block, data); WriteEmbeddedStatement(unsafeStatement.Block);
return null; return null;
} }
public object Visit(CheckedStatement checkedStatement, object data) public object Visit(CheckedStatement checkedStatement, object data)
{ {
outputFormatter.PrintToken(Tokens.Checked); outputFormatter.PrintToken(Tokens.Checked);
outputFormatter.Space(); WriteEmbeddedStatement(checkedStatement.Block);
outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
nodeTracker.TrackedVisit(checkedStatement.Block, false);
--outputFormatter.IndentationLevel;
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
return null; return null;
} }
public object Visit(UncheckedStatement uncheckedStatement, object data) public object Visit(UncheckedStatement uncheckedStatement, object data)
{ {
outputFormatter.PrintToken(Tokens.Unchecked); outputFormatter.PrintToken(Tokens.Unchecked);
outputFormatter.Space(); WriteEmbeddedStatement(uncheckedStatement.Block);
outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
nodeTracker.TrackedVisit(uncheckedStatement.Block, false);
--outputFormatter.IndentationLevel;
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
return null; return null;
} }

5
src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs

@ -1172,14 +1172,14 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.IndentationLevel -= 1; outputFormatter.IndentationLevel -= 1;
} }
void PrintIndentedBlock(ArrayList statements) void PrintIndentedBlock(IEnumerable statements)
{ {
outputFormatter.IndentationLevel += 1; outputFormatter.IndentationLevel += 1;
VisitStatementList(statements); VisitStatementList(statements);
outputFormatter.IndentationLevel -= 1; outputFormatter.IndentationLevel -= 1;
} }
void VisitStatementList(ArrayList statements) void VisitStatementList(IEnumerable statements)
{ {
foreach (Statement stmt in statements) { foreach (Statement stmt in statements) {
if (stmt is BlockStatement) { if (stmt is BlockStatement) {
@ -1321,6 +1321,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.Space(); outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Then); outputFormatter.PrintToken(Tokens.Then);
outputFormatter.NewLine(); outputFormatter.NewLine();
PrintIndentedBlock(ifElseStatement.TrueStatement); PrintIndentedBlock(ifElseStatement.TrueStatement);
foreach (ElseIfSection elseIfSection in ifElseStatement.ElseIfSections) { foreach (ElseIfSection elseIfSection in ifElseStatement.ElseIfSections) {

25
src/Libraries/NRefactory/Project/Src/Parser/AST/General/GlobalScope/CompilationUnit.cs

@ -14,14 +14,10 @@ namespace ICSharpCode.NRefactory.Parser.AST
{ {
public class CompilationUnit : AbstractNode public class CompilationUnit : AbstractNode
{ {
// TODO: check if the LookUpTable here and the specials are still needed // Children in C#: UsingAliasDeclaration, UsingDeclaration, AttributeSection, NamespaceDeclaration
// TODO: Are the childs still needed? Or should we put them in there own fields? // Children in VB: OptionStatements, ImportsStatement, AttributeSection, NamespaceDeclaration
// Childs in C#: UsingAliasDeclaration, UsingDeclaration, AttributeSection, NamespaceDeclaration
// Childs in VB: OptionStatements, ImportsStatement, AttributeSection, NamespaceDeclaration
Stack blockStack = new Stack(); Stack blockStack = new Stack();
INode lastChild = null;
ArrayList lookUpTable = new ArrayList(); // [VariableDeclaration]
public CompilationUnit() public CompilationUnit()
{ {
@ -35,12 +31,7 @@ namespace ICSharpCode.NRefactory.Parser.AST
public void BlockEnd() public void BlockEnd()
{ {
lastChild = (INode)blockStack.Pop(); blockStack.Pop();
}
public INode TakeBlock()
{
return (INode)blockStack.Pop();
} }
public override void AddChild(INode childNode) public override void AddChild(INode childNode)
@ -49,19 +40,9 @@ namespace ICSharpCode.NRefactory.Parser.AST
INode parent = (INode)blockStack.Peek(); INode parent = (INode)blockStack.Peek();
parent.Children.Add(childNode); parent.Children.Add(childNode);
childNode.Parent = parent; childNode.Parent = parent;
lastChild = childNode;
if (childNode is LocalVariableDeclaration) {
AddToLookUpTable((LocalVariableDeclaration)childNode);
}
} }
} }
public void AddToLookUpTable(LocalVariableDeclaration v)
{
v.Block = (BlockStatement)blockStack.Peek();
lookUpTable.Add(v);
}
public override object AcceptVisitor(IASTVisitor visitor, object data) public override object AcceptVisitor(IASTVisitor visitor, object data)
{ {
return visitor.Visit(this, data); return visitor.Visit(this, data);

16
src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/ForStatement.cs

@ -7,23 +7,23 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Collections; using System.Collections.Generic;
namespace ICSharpCode.NRefactory.Parser.AST namespace ICSharpCode.NRefactory.Parser.AST
{ {
public class ForStatement : StatementWithEmbeddedStatement public class ForStatement : StatementWithEmbeddedStatement
{ {
ArrayList initializers; // EmbeddedStatement OR list of StatmentExpressions List<Statement> initializers; // EmbeddedStatement OR list of StatmentExpressions
Expression condition; Expression condition;
ArrayList iterator; // [Statement] List<Statement> iterator; // [Statement]
public ArrayList Initializers { public List<Statement> Initializers {
get { get {
return initializers; return initializers;
} }
} }
public ArrayList Iterator { public List<Statement> Iterator {
get { get {
return iterator; return iterator;
} }
@ -38,10 +38,10 @@ namespace ICSharpCode.NRefactory.Parser.AST
} }
} }
public ForStatement(ArrayList initializers, Expression condition, ArrayList iterator, Statement embeddedStatement) public ForStatement(List<Statement> initializers, Expression condition, List<Statement> iterator, Statement embeddedStatement)
{ {
this.initializers = initializers == null ? new ArrayList(1) : initializers; this.initializers = initializers ?? new List<Statement>(1);
this.iterator = iterator == null ? new ArrayList(1) : iterator; this.iterator = iterator ?? new List<Statement>(1);
this.Condition = condition; this.Condition = condition;
this.EmbeddedStatement = embeddedStatement; this.EmbeddedStatement = embeddedStatement;

28
src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/IfElseStatement.cs

@ -7,17 +7,17 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Collections; using System.Collections.Generic;
namespace ICSharpCode.NRefactory.Parser.AST namespace ICSharpCode.NRefactory.Parser.AST
{ {
public class IfElseStatement : Statement public class IfElseStatement : Statement
{ {
Expression condition; Expression condition;
ArrayList trueStatement; // List for stmt : stmt : stmt ... in VB.NET List<Statement> trueStatement; // List for stmt : stmt : stmt ... in VB.NET
ArrayList falseStatement; // [Statement] List<Statement> falseStatement; // [Statement]
ArrayList elseIfSections = new ArrayList(1); // VB.NET only, [ElseIfSection] List<Statement> elseIfSections = new List<Statement>(1); // VB.NET only, [ElseIfSection]
public bool HasElseStatements { public bool HasElseStatements {
get { get {
@ -40,46 +40,46 @@ namespace ICSharpCode.NRefactory.Parser.AST
} }
} }
public ArrayList ElseIfSections { public List<Statement> ElseIfSections {
get { get {
return elseIfSections; return elseIfSections;
} }
set { set {
elseIfSections = value == null ? new ArrayList(1) : value; elseIfSections = value ?? new List<Statement>(1);
} }
} }
public ArrayList TrueStatement { public List<Statement> TrueStatement {
get { get {
return trueStatement; return trueStatement;
} }
set { set {
trueStatement = value == null ? new ArrayList(1) : value; trueStatement = value ?? new List<Statement>(1);
} }
} }
public ArrayList FalseStatement { public List<Statement> FalseStatement {
get { get {
return falseStatement; return falseStatement;
} }
set { set {
falseStatement = value == null ? new ArrayList(1) : value; falseStatement = value ?? new List<Statement>(1);
} }
} }
public IfElseStatement(Expression condition, Statement trueStatement) public IfElseStatement(Expression condition, Statement trueStatement)
{ {
this.Condition = condition; this.Condition = condition;
this.trueStatement = new ArrayList(1); this.trueStatement = new List<Statement>(1);
this.falseStatement = new ArrayList(1); this.falseStatement = new List<Statement>(1);
this.trueStatement.Add(Statement.CheckNull(trueStatement)); this.trueStatement.Add(Statement.CheckNull(trueStatement));
} }
public IfElseStatement(Expression condition, Statement trueStatement, Statement falseStatement) public IfElseStatement(Expression condition, Statement trueStatement, Statement falseStatement)
{ {
this.Condition = condition; this.Condition = condition;
this.trueStatement = new ArrayList(1); this.trueStatement = new List<Statement>(1);
this.falseStatement = new ArrayList(1); this.falseStatement = new List<Statement>(1);
this.trueStatement.Add(Statement.CheckNull(trueStatement)); this.trueStatement.Add(Statement.CheckNull(trueStatement));
this.falseStatement.Add(Statement.CheckNull(falseStatement)); this.falseStatement.Add(Statement.CheckNull(falseStatement));
} }

11
src/Libraries/NRefactory/Project/Src/Parser/AST/VBNet/Statements/ForNextStatement.cs

@ -6,7 +6,7 @@
// </file> // </file>
using System; using System;
using System.Collections; using System.Collections.Generic;
namespace ICSharpCode.NRefactory.Parser.AST namespace ICSharpCode.NRefactory.Parser.AST
{ {
@ -16,8 +16,7 @@ namespace ICSharpCode.NRefactory.Parser.AST
Expression end; Expression end;
Expression step; Expression step;
// List<Expression> nextExpressions; List<Expression> nextExpressions;
ArrayList nextExpressions;
TypeReference typeReference; TypeReference typeReference;
string variableName; string variableName;
@ -39,12 +38,12 @@ namespace ICSharpCode.NRefactory.Parser.AST
} }
} }
public ArrayList NextExpressions { public List<Expression> NextExpressions {
get { get {
return nextExpressions; return nextExpressions;
} }
set { set {
nextExpressions = value == null ? new ArrayList(1) : value; nextExpressions = value ?? new List<Expression>(1);
} }
} }
@ -75,7 +74,7 @@ namespace ICSharpCode.NRefactory.Parser.AST
} }
} }
public ForNextStatement(TypeReference typeReference, string variableName, Expression start, Expression end, Expression step, Statement embeddedStatement, ArrayList nextExpressions) public ForNextStatement(TypeReference typeReference, string variableName, Expression start, Expression end, Expression step, Statement embeddedStatement, List<Expression> nextExpressions)
{ {
this.TypeReference = typeReference; this.TypeReference = typeReference;
this.VariableName = variableName; this.VariableName = variableName;

10
src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs

@ -3960,7 +3960,7 @@ out expr);
lexer.NextToken(); lexer.NextToken();
#line 1886 "cs.ATG" #line 1886 "cs.ATG"
ArrayList initializer = null; ArrayList iterator = null; List<Statement> initializer = null; List<Statement> iterator = null;
Expect(20); Expect(20);
if (StartOf(5)) { if (StartOf(5)) {
ForInitializer( ForInitializer(
@ -4196,11 +4196,11 @@ out label);
void ForInitializer( void ForInitializer(
#line 1932 "cs.ATG" #line 1932 "cs.ATG"
out ArrayList initializer) { out List<Statement> initializer) {
#line 1934 "cs.ATG" #line 1934 "cs.ATG"
Statement stmt; Statement stmt;
initializer = new ArrayList(); initializer = new List<Statement>();
if ( if (
#line 1938 "cs.ATG" #line 1938 "cs.ATG"
@ -4232,11 +4232,11 @@ out stmt);
void ForIterator( void ForIterator(
#line 1942 "cs.ATG" #line 1942 "cs.ATG"
out ArrayList iterator) { out List<Statement> iterator) {
#line 1944 "cs.ATG" #line 1944 "cs.ATG"
Statement stmt; Statement stmt;
iterator = new ArrayList(); iterator = new List<Statement>();
StatementExpr( StatementExpr(
#line 1948 "cs.ATG" #line 1948 "cs.ATG"

10
src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG

@ -1883,7 +1883,7 @@ EmbeddedStatement<out Statement statement>
EmbeddedStatement<out embeddedStatement> (. statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.Start);.) EmbeddedStatement<out embeddedStatement> (. statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.Start);.)
| "do" EmbeddedStatement<out embeddedStatement> "while" | "do" EmbeddedStatement<out embeddedStatement> "while"
"(" Expr<out expr> ")" ";" (. statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.End); .) "(" Expr<out expr> ")" ";" (. statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.End); .)
| "for" (. ArrayList initializer = null; ArrayList iterator = null; .) | "for" (. List<Statement> initializer = null; List<Statement> iterator = null; .)
"(" [ ForInitializer<out initializer> ] ";" "(" [ ForInitializer<out initializer> ] ";"
[ Expr<out expr> ] ";" [ Expr<out expr> ] ";"
[ ForIterator<out iterator> ] ")" [ ForIterator<out iterator> ] ")"
@ -1929,20 +1929,20 @@ EmbeddedStatement<out Statement statement>
")" EmbeddedStatement<out embeddedStatement> (. statement = new FixedStatement(type, pointerDeclarators, embeddedStatement); .) ")" EmbeddedStatement<out embeddedStatement> (. statement = new FixedStatement(type, pointerDeclarators, embeddedStatement); .)
. .
ForInitializer<out ArrayList initializer> ForInitializer<out List<Statement> initializer>
(. (.
Statement stmt; Statement stmt;
initializer = new ArrayList(); initializer = new List<Statement>();
.) .)
= =
IF (IsLocalVarDecl()) LocalVariableDecl<out stmt> (. initializer.Add(stmt);.) IF (IsLocalVarDecl()) LocalVariableDecl<out stmt> (. initializer.Add(stmt);.)
| StatementExpr<out stmt> (.initializer.Add(stmt);.) { "," StatementExpr<out stmt> (. initializer.Add(stmt);.) } | StatementExpr<out stmt> (.initializer.Add(stmt);.) { "," StatementExpr<out stmt> (. initializer.Add(stmt);.) }
. .
ForIterator<out ArrayList iterator> ForIterator<out List<Statement> iterator>
(. (.
Statement stmt; Statement stmt;
iterator = new ArrayList(); iterator = new List<Statement>();
.) .)
= =
StatementExpr<out stmt> (. iterator.Add(stmt);.) { "," StatementExpr<out stmt> (. iterator.Add(stmt); .) } StatementExpr<out stmt> (. iterator.Add(stmt);.) { "," StatementExpr<out stmt> (. iterator.Add(stmt); .) }

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

@ -5220,7 +5220,7 @@ out expr);
Expression start = null; Expression start = null;
Expression end = null; Expression end = null;
Expression step = null; Expression step = null;
Expression nextExpr = null;ArrayList nextExpressions = null; Expression nextExpr = null;List<Expression> nextExpressions = null;
LoopControlVariable( LoopControlVariable(
#line 2500 "VBNET.ATG" #line 2500 "VBNET.ATG"
@ -5250,7 +5250,7 @@ out embeddedStatement);
out nextExpr); out nextExpr);
#line 2505 "VBNET.ATG" #line 2505 "VBNET.ATG"
nextExpressions = new ArrayList(); nextExpressions.Add(nextExpr); nextExpressions = new List<Expression>(); nextExpressions.Add(nextExpr);
while (la.kind == 12) { while (la.kind == 12) {
lexer.NextToken(); lexer.NextToken();
Expr( Expr(

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

@ -2495,14 +2495,14 @@ EmbeddedStatement<out Statement statement>
Expression start = null; Expression start = null;
Expression end = null; Expression end = null;
Expression step = null; Expression step = null;
Expression nextExpr = null;ArrayList nextExpressions = null; Expression nextExpr = null;List<Expression> nextExpressions = null;
.) .)
LoopControlVariable<out typeReference, out typeName> LoopControlVariable<out typeReference, out typeName>
"=" Expr<out start> "To" Expr<out end> [ "Step" Expr<out step> ] "=" Expr<out start> "To" Expr<out end> [ "Step" Expr<out step> ]
EndOfStmt Block<out embeddedStatement> EndOfStmt Block<out embeddedStatement>
"Next" "Next"
[ [
Expr<out nextExpr> (. nextExpressions = new ArrayList(); nextExpressions.Add(nextExpr); .) Expr<out nextExpr> (. nextExpressions = new List<Expression>(); nextExpressions.Add(nextExpr); .)
{ "," Expr<out nextExpr> (. nextExpressions.Add(nextExpr); .) } { "," Expr<out nextExpr> (. nextExpressions.Add(nextExpr); .) }
] ]
(. (.

243
src/Libraries/NRefactory/Project/Src/Parser/Visitors/CSharpConstructsVisitor.cs

@ -0,0 +1,243 @@
// <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 System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.NRefactory.Parser.AST;
namespace ICSharpCode.NRefactory.Parser
{
/// <summary>
/// Converts special C# constructs to use more general AST classes.
/// </summary>
public class CSharpConstructsVisitor : AbstractASTVisitor
{
// The following conversions are implemented:
// a == null -> a Is Nothing
// a != null -> a Is Not Nothing
// i++ / ++i as statement: convert to i += 1
// i-- / --i as statement: convert to i -= 1
// ForStatement -> ForNextStatement when for-loop is simple
// The following conversions should be implemented in the future:
// if (Event != null) Event(this, bla); -> RaiseEvent Event(this, bla)
public override object Visit(BinaryOperatorExpression binaryOperatorExpression, object data)
{
if (binaryOperatorExpression.Op == BinaryOperatorType.Equality || binaryOperatorExpression.Op == BinaryOperatorType.InEquality) {
if (IsNullLiteralExpression(binaryOperatorExpression.Left)) {
Expression tmp = binaryOperatorExpression.Left;
binaryOperatorExpression.Left = binaryOperatorExpression.Right;
binaryOperatorExpression.Right = tmp;
}
if (IsNullLiteralExpression(binaryOperatorExpression.Right)) {
if (binaryOperatorExpression.Op == BinaryOperatorType.Equality) {
binaryOperatorExpression.Op = BinaryOperatorType.ReferenceEquality;
} else {
binaryOperatorExpression.Op = BinaryOperatorType.ReferenceInequality;
}
}
}
return base.Visit(binaryOperatorExpression, data);
}
bool IsNullLiteralExpression(Expression expr)
{
PrimitiveExpression pe = expr as PrimitiveExpression;
if (pe == null) return false;
return pe.Value == null;
}
public override object Visit(StatementExpression statementExpression, object data)
{
UnaryOperatorExpression uoe = statementExpression.Expression as UnaryOperatorExpression;
if (uoe != null) {
switch (uoe.Op) {
case UnaryOperatorType.Increment:
case UnaryOperatorType.PostIncrement:
statementExpression.Expression = new AssignmentExpression(uoe.Expression, AssignmentOperatorType.Add, new PrimitiveExpression(1, "1"));
break;
case UnaryOperatorType.Decrement:
case UnaryOperatorType.PostDecrement:
statementExpression.Expression = new AssignmentExpression(uoe.Expression, AssignmentOperatorType.Subtract, new PrimitiveExpression(1, "1"));
break;
}
}
return base.Visit(statementExpression, data);
}
List<IfElseStatement> ifStatements = new List<IfElseStatement>();
public override object Visit(IfElseStatement ifElseStatement, object data)
{
ifStatements.Add(ifElseStatement);
return base.Visit(ifElseStatement, data);
}
void ConvertIfStatements()
{
foreach (IfElseStatement ifStatement in ifStatements) {
ConvertIfStatement(ifStatement);
}
ifStatements.Clear();
}
void ConvertIfStatement(IfElseStatement ifStatement)
{
BinaryOperatorExpression boe = ifStatement.Condition as BinaryOperatorExpression;
if (ifStatement.ElseIfSections.Count == 0
&& ifStatement.FalseStatement.Count == 0
&& ifStatement.TrueStatement.Count == 1
&& boe != null
&& boe.Op == BinaryOperatorType.ReferenceInequality
&& (IsNullLiteralExpression(boe.Left) || IsNullLiteralExpression(boe.Right))
)
{
IdentifierExpression ident = boe.Left as IdentifierExpression;
if (ident == null)
ident = boe.Right as IdentifierExpression;
StatementExpression se = ifStatement.TrueStatement[0] as StatementExpression;
if (se == null) {
BlockStatement block = ifStatement.TrueStatement[0] as BlockStatement;
if (block.Children.Count == 1) {
se = block.Children[0] as StatementExpression;
}
}
if (ident != null && se != null) {
InvocationExpression ie = se.Expression as InvocationExpression;
if (ie != null && (ie.TargetObject as IdentifierExpression).Identifier == ident.Identifier) {
Statement.Replace(ifStatement, new RaiseEventStatement(ident.Identifier, ie.Arguments));
}
}
}
}
List<ForStatement> forStatements = new List<ForStatement>();
public override object Visit(ForStatement forStatement, object data)
{
forStatements.Add(forStatement);
// post-pone conversion because the parent's collection cannot be modified while it
// is in use.
return base.Visit(forStatement, data);
}
void ConvertForStatements()
{
foreach (ForStatement forStatement in forStatements) {
ConvertForStatement(forStatement);
}
forStatements.Clear();
}
void ConvertForStatement(ForStatement forStatement)
{
// ForStatement -> ForNextStatement when for-loop is simple
// only the following forms of the for-statement are allowed:
// for (TypeReference name = start; name < oneAfterEnd; name += step)
// for (name = start; name < oneAfterEnd; name += step)
// for (TypeReference name = start; name <= end; name += step)
// for (name = start; name <= end; name += step)
// for (TypeReference name = start; name > oneAfterEnd; name -= step)
// for (name = start; name > oneAfterEnd; name -= step)
// for (TypeReference name = start; name >= end; name -= step)
// for (name = start; name >= end; name -= step)
// check if the form is valid and collect TypeReference, name, start, end and step
if (forStatement.Initializers.Count != 1)
return;
if (forStatement.Iterator.Count != 1)
return;
StatementExpression statement = forStatement.Iterator[0] as StatementExpression;
if (statement == null)
return;
AssignmentExpression iterator = statement.Expression as AssignmentExpression;
if (iterator == null || (iterator.Op != AssignmentOperatorType.Add && iterator.Op != AssignmentOperatorType.Subtract))
return;
IdentifierExpression iteratorIdentifier = iterator.Left as IdentifierExpression;
if (iteratorIdentifier == null)
return;
PrimitiveExpression stepExpression = iterator.Right as PrimitiveExpression;
if (stepExpression == null || !(stepExpression.Value is int))
return;
int step = (int)stepExpression.Value;
if (iterator.Op == AssignmentOperatorType.Subtract)
step = -step;
BinaryOperatorExpression condition = forStatement.Condition as BinaryOperatorExpression;
if (condition == null || !(condition.Left is IdentifierExpression))
return;
if ((condition.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier)
return;
Expression end;
if (iterator.Op == AssignmentOperatorType.Subtract) {
if (condition.Op == BinaryOperatorType.GreaterThanOrEqual) {
end = condition.Right;
} else if (condition.Op == BinaryOperatorType.GreaterThan) {
end = Expression.AddInteger(condition.Right, 1);
} else {
return;
}
} else {
if (condition.Op == BinaryOperatorType.LessThanOrEqual) {
end = condition.Right;
} else if (condition.Op == BinaryOperatorType.LessThan) {
end = Expression.AddInteger(condition.Right, -1);
} else {
return;
}
}
Expression start;
TypeReference typeReference = null;
LocalVariableDeclaration varDecl = forStatement.Initializers[0] as LocalVariableDeclaration;
if (varDecl != null) {
if (varDecl.Variables.Count != 1
|| varDecl.Variables[0].Name != iteratorIdentifier.Identifier
|| varDecl.Variables[0].Initializer == null)
return;
typeReference = varDecl.GetTypeForVariable(0);
start = varDecl.Variables[0].Initializer;
} else {
statement = forStatement.Initializers[0] as StatementExpression;
if (statement == null)
return;
AssignmentExpression assign = statement.Expression as AssignmentExpression;
if (assign == null || assign.Op != AssignmentOperatorType.Assign)
return;
if (!(assign.Left is IdentifierExpression))
return;
if ((assign.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier)
return;
start = assign.Right;
}
ForNextStatement forNextStatement = new ForNextStatement(typeReference, iteratorIdentifier.Identifier,
start, end,
(step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)),
forStatement.EmbeddedStatement, null);
Statement.Replace(forStatement, forNextStatement);
}
public override object Visit(TypeDeclaration td, object data)
{
object result = base.Visit(td, data);
ConvertForStatements();
ConvertIfStatements();
return result;
}
}
}

216
src/Libraries/NRefactory/Project/Src/Parser/Visitors/CSharpToVBNetConvertVisitor.cs

@ -11,7 +11,6 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB; using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.NRefactory.Parser.AST; using ICSharpCode.NRefactory.Parser.AST;
@ -20,218 +19,13 @@ namespace ICSharpCode.NRefactory.Parser
/// <summary> /// <summary>
/// This class converts C# constructs to their VB.NET equivalents. /// This class converts C# constructs to their VB.NET equivalents.
/// </summary> /// </summary>
public class CSharpToVBNetConvertVisitor : AbstractASTVisitor public class CSharpToVBNetConvertVisitor : CSharpConstructsVisitor
{ {
// The following conversions are implemented: public override object Visit(CompilationUnit compilationUnit, object data)
// Conflicting field/property names -> m_field
// a == null -> a Is Nothing
// a != null -> a Is Not Nothing
// i++ / ++i as statement: convert to i += 1
// i-- / --i as statement: convert to i -= 1
// ForStatement -> ForNextStatement when for-loop is simple
// The following conversions should be implemented in the future:
// if (Event != null) Event(this, bla); -> RaiseEvent Event(this, bla)
bool renameConflictingFieldNames = true;
/// <summary>
/// Gets/Sets if fields that conflict with a property name should be renamed automatically by
/// prefixing them with "m_". Default is true.
/// </summary>
public bool RenameConflictingFieldNames {
get {
return renameConflictingFieldNames;
}
set {
renameConflictingFieldNames = value;
}
}
public override object Visit(BinaryOperatorExpression binaryOperatorExpression, object data)
{
if (binaryOperatorExpression.Op == BinaryOperatorType.Equality || binaryOperatorExpression.Op == BinaryOperatorType.InEquality) {
if (IsNullLiteralExpression(binaryOperatorExpression.Left)) {
Expression tmp = binaryOperatorExpression.Left;
binaryOperatorExpression.Left = binaryOperatorExpression.Right;
binaryOperatorExpression.Right = tmp;
}
if (IsNullLiteralExpression(binaryOperatorExpression.Right)) {
if (binaryOperatorExpression.Op == BinaryOperatorType.Equality) {
binaryOperatorExpression.Op = BinaryOperatorType.ReferenceEquality;
} else {
binaryOperatorExpression.Op = BinaryOperatorType.ReferenceInequality;
}
}
}
return base.Visit(binaryOperatorExpression, data);
}
bool IsNullLiteralExpression(Expression expr)
{
PrimitiveExpression pe = expr as PrimitiveExpression;
if (pe == null) return false;
return pe.Value == null;
}
public override object Visit(TypeDeclaration td, object data)
{
// Conflicting field/property names -> m_field
List<string> properties = new List<string>();
foreach (object o in td.Children) {
PropertyDeclaration pd = o as PropertyDeclaration;
if (pd != null) {
properties.Add(pd.Name);
}
}
List<VariableDeclaration> conflicts = new List<VariableDeclaration>();
foreach (object o in td.Children) {
FieldDeclaration fd = o as FieldDeclaration;
if (fd != null) {
foreach (VariableDeclaration var in fd.Fields) {
string name = var.Name;
foreach (string propertyName in properties) {
if (name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase)) {
conflicts.Add(var);
}
}
}
}
}
if (renameConflictingFieldNames) {
new PrefixFieldsVisitor(conflicts, "m_").Run(td);
}
object result = base.Visit(td, data);
ConvertForStatements();
return result;
}
public override object Visit(StatementExpression statementExpression, object data)
{
UnaryOperatorExpression uoe = statementExpression.Expression as UnaryOperatorExpression;
if (uoe != null) {
switch (uoe.Op) {
case UnaryOperatorType.Increment:
case UnaryOperatorType.PostIncrement:
statementExpression.Expression = new AssignmentExpression(uoe.Expression, AssignmentOperatorType.Add, new PrimitiveExpression(1, "1"));
break;
case UnaryOperatorType.Decrement:
case UnaryOperatorType.PostDecrement:
statementExpression.Expression = new AssignmentExpression(uoe.Expression, AssignmentOperatorType.Subtract, new PrimitiveExpression(1, "1"));
break;
}
}
return base.Visit(statementExpression, data);
}
ArrayList forStatements = new ArrayList();
public override object Visit(ForStatement forStatement, object data)
{ {
forStatements.Add(forStatement); base.Visit(compilationUnit, data);
// post-pone conversion because the parent's collection cannot be modified while it compilationUnit.AcceptVisitor(new ToVBNetConvertVisitor(), data);
// is in use. return null;
return base.Visit(forStatement, data);
}
void ConvertForStatements()
{
foreach (ForStatement forStatement in forStatements) {
ConvertForStatement(forStatement);
}
forStatements.Clear();
}
void ConvertForStatement(ForStatement forStatement)
{
// ForStatement -> ForNextStatement when for-loop is simple
// only the following forms of the for-statement are allowed:
// for (TypeReference name = start; name < oneAfterEnd; name += step)
// for (name = start; name < oneAfterEnd; name += step)
// for (TypeReference name = start; name <= end; name += step)
// for (name = start; name <= end; name += step)
// for (TypeReference name = start; name > oneAfterEnd; name -= step)
// for (name = start; name > oneAfterEnd; name -= step)
// for (TypeReference name = start; name >= end; name -= step)
// for (name = start; name >= end; name -= step)
// check if the form is valid and collect TypeReference, name, start, end and step
if (forStatement.Initializers.Count != 1)
return;
if (forStatement.Iterator.Count != 1)
return;
StatementExpression statement = forStatement.Iterator[0] as StatementExpression;
if (statement == null)
return;
AssignmentExpression iterator = statement.Expression as AssignmentExpression;
if (iterator == null || (iterator.Op != AssignmentOperatorType.Add && iterator.Op != AssignmentOperatorType.Subtract))
return;
IdentifierExpression iteratorIdentifier = iterator.Left as IdentifierExpression;
if (iteratorIdentifier == null)
return;
PrimitiveExpression stepExpression = iterator.Right as PrimitiveExpression;
if (stepExpression == null || !(stepExpression.Value is int))
return;
int step = (int)stepExpression.Value;
if (iterator.Op == AssignmentOperatorType.Subtract)
step = -step;
BinaryOperatorExpression condition = forStatement.Condition as BinaryOperatorExpression;
if (condition == null || !(condition.Left is IdentifierExpression))
return;
if ((condition.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier)
return;
Expression end;
if (iterator.Op == AssignmentOperatorType.Subtract) {
if (condition.Op == BinaryOperatorType.GreaterThanOrEqual) {
end = condition.Right;
} else if (condition.Op == BinaryOperatorType.GreaterThan) {
end = Expression.AddInteger(condition.Right, 1);
} else {
return;
}
} else {
if (condition.Op == BinaryOperatorType.LessThanOrEqual) {
end = condition.Right;
} else if (condition.Op == BinaryOperatorType.LessThan) {
end = Expression.AddInteger(condition.Right, -1);
} else {
return;
}
}
Expression start;
TypeReference typeReference = null;
LocalVariableDeclaration varDecl = forStatement.Initializers[0] as LocalVariableDeclaration;
if (varDecl != null) {
if (varDecl.Variables.Count != 1
|| varDecl.Variables[0].Name != iteratorIdentifier.Identifier
|| varDecl.Variables[0].Initializer == null)
return;
typeReference = varDecl.GetTypeForVariable(0);
start = varDecl.Variables[0].Initializer;
} else {
statement = forStatement.Initializers[0] as StatementExpression;
if (statement == null)
return;
AssignmentExpression assign = statement.Expression as AssignmentExpression;
if (assign == null || assign.Op != AssignmentOperatorType.Assign)
return;
if (!(assign.Left is IdentifierExpression))
return;
if ((assign.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier)
return;
start = assign.Right;
}
ForNextStatement forNextStatement = new ForNextStatement(typeReference, iteratorIdentifier.Identifier,
start, end,
(step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)),
forStatement.EmbeddedStatement, null);
Statement.Replace(forStatement, forNextStatement);
} }
} }
} }

24
src/Libraries/NRefactory/Project/Src/Parser/Visitors/PrefixFieldsVisitor.cs

@ -142,29 +142,5 @@ namespace ICSharpCode.NRefactory.Parser
} }
return curBlock.Contains(name); return curBlock.Contains(name);
} }
/*
public override object Visit(invocationExpression as InvocationExpression, object data)
{
// this method is a workaround for a bug in SharpRefactory
result = data
if invocationExpression.TargetObject != null:
result = invocationExpression.TargetObject.AcceptVisitor(self, data)
if invocationExpression.Parameters != null:
for n as INode in invocationExpression.Parameters:
n.AcceptVisitor(self, data)
return result
}
public override object Visit(indexerExpression as IndexerExpression, object data)
{
// this method is a workaround for a bug in SharpRefactory
result = indexerExpression.TargetObject.AcceptVisitor(self, data)
for n as INode in indexerExpression.Indices {
n.AcceptVisitor(self, data)
}
return result
}
*/
} }
} }

30
src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToCSharpConvertVisitor.cs

@ -0,0 +1,30 @@
/*
* Created by SharpDevelop.
* User: Daniel Grunwald
* Date: 02.01.2006
* Time: 18:15
*/
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
namespace ICSharpCode.NRefactory.Parser
{
/// <summary>
/// Converts elements not supported by C# to their C# representation.
/// Not all elements are converted here, most simple elements (e.g. StopStatement)
/// are converted in the output visitor.
/// </summary>
public class ToCSharpConvertVisitor : AbstractASTVisitor
{
// The following conversions should be implemented in the future:
// Public Event EventName(param As String) -> automatic delegate declaration
}
}

167
src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToVBNetConvertVisitor.cs

@ -0,0 +1,167 @@
/*
* Created by SharpDevelop.
* User: Daniel Grunwald
* Date: 02.01.2006
* Time: 18:18
*/
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
namespace ICSharpCode.NRefactory.Parser
{
/// <summary>
/// Converts elements not supported by VB to their VB representation.
/// Not all elements are converted here, most simple elements (e.g. ConditionalExpression)
/// are converted in the output visitor.
/// </summary>
public class ToVBNetConvertVisitor : AbstractASTVisitor
{
// The following conversions are implemented:
// Conflicting field/property names -> m_field
// Anonymous methods are put into new methods
// Simple event handler creation is replaced with AddressOfExpression
TypeDeclaration currentType;
readonly List<KeyValuePair<Statement, Statement>> replacements = new List<KeyValuePair<Statement, Statement>>();
readonly List<MethodDeclaration> newMethods = new List<MethodDeclaration>();
public override object Visit(TypeDeclaration td, object data)
{
TypeDeclaration outerType = currentType;
currentType = td;
// Conflicting field/property names -> m_field
List<string> properties = new List<string>();
foreach (object o in td.Children) {
PropertyDeclaration pd = o as PropertyDeclaration;
if (pd != null) {
properties.Add(pd.Name);
}
}
List<VariableDeclaration> conflicts = new List<VariableDeclaration>();
foreach (object o in td.Children) {
FieldDeclaration fd = o as FieldDeclaration;
if (fd != null) {
foreach (VariableDeclaration var in fd.Fields) {
string name = var.Name;
foreach (string propertyName in properties) {
if (name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase)) {
conflicts.Add(var);
}
}
}
}
}
new PrefixFieldsVisitor(conflicts, "m_").Run(td);
base.Visit(td, data);
currentType = outerType;
foreach (MethodDeclaration md in newMethods) {
td.AddChild(md);
}
newMethods.Clear();
foreach (KeyValuePair<Statement, Statement> pair in replacements) {
Statement.Replace(pair.Key, pair.Value);
}
replacements.Clear();
return null;
}
string GetAnonymousMethodName()
{
for (int i = 1;; i++) {
string name = "ConvertedAnonymousMethod" + i;
bool ok = true;
foreach (object c in currentType.Children) {
MethodDeclaration method = c as MethodDeclaration;
if (method != null && method.Name == name) {
ok = false;
break;
}
}
foreach (MethodDeclaration method in newMethods) {
if (method != null && method.Name == name) {
ok = false;
break;
}
}
if (ok)
return name;
}
}
public override object Visit(StatementExpression statementExpression, object data)
{
base.Visit(statementExpression, data);
AssignmentExpression ass = statementExpression.Expression as AssignmentExpression;
if (ass != null && ass.Right is AddressOfExpression) {
if (ass.Op == AssignmentOperatorType.Add) {
Statement st = new AddHandlerStatement(ass.Left, ass.Right);
replacements.Add(new KeyValuePair<Statement, Statement>(statementExpression, st));
} else if (ass.Op == AssignmentOperatorType.Subtract) {
Statement st = new RemoveHandlerStatement(ass.Left, ass.Right);
replacements.Add(new KeyValuePair<Statement, Statement>(statementExpression, st));
}
}
return null;
}
string GetMemberNameOnThisReference(Expression expr)
{
IdentifierExpression ident = expr as IdentifierExpression;
if (ident != null)
return ident.Identifier;
FieldReferenceExpression fre = expr as FieldReferenceExpression;
if (fre != null && fre.TargetObject is ThisReferenceExpression)
return fre.FieldName;
return null;
}
string GetMethodNameOfDelegateCreation(Expression expr)
{
string name = GetMemberNameOnThisReference(expr);
if (name != null)
return name;
ObjectCreateExpression oce = expr as ObjectCreateExpression;
if (oce != null && oce.Parameters.Count == 1) {
return GetMemberNameOnThisReference(oce.Parameters[0]);
}
return null;
}
public override object Visit(AssignmentExpression assignmentExpression, object data)
{
AnonymousMethodExpression ame = assignmentExpression.Right as AnonymousMethodExpression;
if (currentType != null && ame != null) {
MethodDeclaration method = new MethodDeclaration(GetAnonymousMethodName(), Modifier.Private, new TypeReference("System.Void"), ame.Parameters, null);
method.Body = ame.Body;
newMethods.Add(method);
assignmentExpression.Right = new AddressOfExpression(new IdentifierExpression(method.Name));
}
if (assignmentExpression.Op == AssignmentOperatorType.Add
|| assignmentExpression.Op == AssignmentOperatorType.Subtract)
{
string methodName = GetMethodNameOfDelegateCreation(assignmentExpression.Right);
if (methodName != null) {
foreach (object c in currentType.Children) {
MethodDeclaration method = c as MethodDeclaration;
if (method != null && method.Name == methodName) {
// this statement is registering an event
assignmentExpression.Right = new AddressOfExpression(new IdentifierExpression(methodName));
break;
}
}
}
}
return base.Visit(assignmentExpression, data);
}
}
}

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

@ -0,0 +1,59 @@
// <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 System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.NRefactory.Parser.AST;
namespace ICSharpCode.NRefactory.Parser
{
/// <summary>
/// Converts special VB constructs to use more general AST classes.
/// </summary>
public class VBNetConstructsConvertVisitor : AbstractASTVisitor
{
// The following conversions are implemented:
// MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this()
// The following conversions should be implemented in the future:
// Function A() \n A = SomeValue \n End Function -> convert to return statement
public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
{
// MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this()
BlockStatement body = constructorDeclaration.Body;
if (body != null && body.Children.Count > 0) {
StatementExpression se = body.Children[0] as StatementExpression;
if (se != null) {
InvocationExpression ie = se.Expression as InvocationExpression;
if (ie != null) {
FieldReferenceExpression fre = ie.TargetObject as FieldReferenceExpression;
if (fre != null && "New".Equals(fre.FieldName, StringComparison.InvariantCultureIgnoreCase)) {
if (fre.TargetObject is BaseReferenceExpression || fre.TargetObject is ClassReferenceExpression) {
body.Children.RemoveAt(0);
ConstructorInitializer ci = new ConstructorInitializer();
ci.Arguments = ie.Arguments;
if (fre.TargetObject is BaseReferenceExpression)
ci.ConstructorInitializerType = ConstructorInitializerType.Base;
else
ci.ConstructorInitializerType = ConstructorInitializerType.This;
constructorDeclaration.ConstructorInitializer = ci;
}
}
}
}
}
return base.Visit(constructorDeclaration, data);
}
}
}

41
src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetToCSharpConvertVisitor.cs

@ -12,49 +12,22 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using ICSharpCode.NRefactory.Parser; using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.NRefactory.Parser.AST; using ICSharpCode.NRefactory.Parser.AST;
namespace ICSharpCode.NRefactory.Parser namespace ICSharpCode.NRefactory.Parser
{ {
/// <summary> /// <summary>
/// This class converts VB.NET constructs to their C# equivalents. /// 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> /// </summary>
public class VBNetToCSharpConvertVisitor : AbstractASTVisitor public class VBNetToCSharpConvertVisitor : VBNetConstructsConvertVisitor
{ {
// The following conversions are implemented: public override object Visit(CompilationUnit compilationUnit, object data)
// MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this()
// The following conversions should be implemented in the future:
// Public Event EventName(param As String) -> automatic delegate declaration
// Function A() \n A = SomeValue \n End Function -> convert to return statement
public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
{ {
// MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this() base.Visit(compilationUnit, data);
BlockStatement body = constructorDeclaration.Body; compilationUnit.AcceptVisitor(new ToCSharpConvertVisitor(), data);
if (body != null && body.Children.Count > 0) { return null;
StatementExpression se = body.Children[0] as StatementExpression;
if (se != null) {
InvocationExpression ie = se.Expression as InvocationExpression;
if (ie != null) {
FieldReferenceExpression fre = ie.TargetObject as FieldReferenceExpression;
if (fre != null && "New".Equals(fre.FieldName, StringComparison.InvariantCultureIgnoreCase)) {
if (fre.TargetObject is BaseReferenceExpression || fre.TargetObject is ClassReferenceExpression) {
body.Children.RemoveAt(0);
ConstructorInitializer ci = new ConstructorInitializer();
ci.Arguments = ie.Arguments;
if (fre.TargetObject is BaseReferenceExpression)
ci.ConstructorInitializerType = ConstructorInitializerType.Base;
else
ci.ConstructorInitializerType = ConstructorInitializerType.This;
constructorDeclaration.ConstructorInitializer = ci;
}
}
}
}
}
return base.Visit(constructorDeclaration, data);
} }
} }
} }

57
src/Libraries/NRefactory/Test/Output/VBNet/ConverterTest.cs

@ -30,6 +30,21 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
Assert.AreEqual(expectedOutput, outputVisitor.Text); Assert.AreEqual(expectedOutput, outputVisitor.Text);
} }
public void TestMember(string input, string expectedOutput)
{
StringBuilder b = new StringBuilder();
b.AppendLine("Class tmp1");
using (StringReader r = new StringReader(expectedOutput)) {
string line;
while ((line = r.ReadLine()) != null) {
b.Append("\t");
b.AppendLine(line);
}
}
b.AppendLine("End Class");
TestProgram("class tmp1 { \n" + input + "\n}", b.ToString());
}
public void TestStatement(string input, string expectedOutput) public void TestStatement(string input, string expectedOutput)
{ {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
@ -85,11 +100,53 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
"\tb(i) = s(i)\n" + "\tb(i) = s(i)\n" +
"Next"); "Next");
} }
[Test] [Test]
public void AddEventHandler() public void AddEventHandler()
{ {
TestStatement("this.button1.Click += new System.EventHandler(this.OnButton1Click);", TestStatement("this.button1.Click += new System.EventHandler(this.OnButton1Click);",
"AddHandler Me.button1.Click, AddressOf Me.OnButton1Click"); "AddHandler Me.button1.Click, AddressOf Me.OnButton1Click");
} }
[Test]
public void RemoveEventHandler()
{
TestStatement("this.button1.Click -= new System.EventHandler(this.OnButton1Click);",
"RemoveHandler Me.button1.Click, AddressOf Me.OnButton1Click");
}
[Test]
public void RaiseEvent()
{
TestStatement("if (MyEvent != null) MyEvent(this, EventArgs.Empty);",
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
TestStatement("if (null != MyEvent) { MyEvent(this, EventArgs.Empty); }",
"RaiseEvent MyEvent(Me, EventArgs.Empty)");
}
[Test]
public void AnonymousMethod()
{
TestMember("void A() { someEvent += delegate(int argument) { return argument * 2; }; }",
"Sub A()\n" +
"\tAddHandler someEvent, AddressOf ConvertedAnonymousMethod1\n" +
"End Sub\n" +
"Private Sub ConvertedAnonymousMethod1(ByVal argument As Integer)\n" +
"\tReturn argument * 2\n" +
"End Sub");
}
[Test]
public void RegisterEvent()
{
TestStatement("someEvent += tmp2;",
"AddHandler someEvent, AddressOf tmp2");
TestStatement("someEvent += this.tmp2;",
"AddHandler someEvent, AddressOf tmp2");
TestStatement("someEvent += new SomeDelegate(tmp2);",
"AddHandler someEvent, AddressOf tmp2");
TestStatement("someEvent += new SomeDelegate(this.tmp2);",
"AddHandler someEvent, AddressOf tmp2");
}
} }
} }

Loading…
Cancel
Save