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

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

@ -70,7 +70,7 @@ namespace NRefactoryToBooConverter @@ -70,7 +70,7 @@ namespace NRefactoryToBooConverter
{
if (statement == null || statement.IsNull)
return null;
ArrayList statements = new ArrayList(1);
List<Statement> statements = new List<Statement>(1);
statements.Add(statement);
return ConvertBlock(statements);
}
@ -83,7 +83,7 @@ namespace NRefactoryToBooConverter @@ -83,7 +83,7 @@ namespace NRefactoryToBooConverter
return b;
}
B.Block ConvertBlock(ArrayList statements)
B.Block ConvertBlock(List<Statement> statements)
{
if (statements.Count == 1) {
if (statements[0] is BlockStatement)
@ -156,7 +156,7 @@ namespace NRefactoryToBooConverter @@ -156,7 +156,7 @@ namespace NRefactoryToBooConverter
/// break $conditionType $condition
/// $body
/// </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.
@ -183,9 +183,9 @@ namespace NRefactoryToBooConverter @@ -183,9 +183,9 @@ namespace NRefactoryToBooConverter
ArrayList MakeManualLoop(ForNextStatement forNextStatement)
{
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)));
ArrayList iterators = new ArrayList(1);
List<Statement> iterators = new List<Statement>(1);
Expression step = forNextStatement.Step;
if (step == null || step.IsNull)
step = new PrimitiveExpression(1, "1");

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using ICSharpCode.NRefactory.Parser;
using NR = ICSharpCode.NRefactory.Parser.AST;
using Boo.Lang.Compiler;
using Boo.Lang.Compiler.Ast;
@ -23,7 +24,10 @@ namespace NRefactoryToBooConverter @@ -23,7 +24,10 @@ namespace NRefactoryToBooConverter
throw new ArgumentNullException("cu");
if (settings == null)
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);
}

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

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

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

@ -1,30 +0,0 @@ @@ -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 @@ @@ -200,6 +200,10 @@
<Compile Include="Src\Output\CodeDOM\CodeDOMVerboseOutputGenerator.cs" />
<Compile Include="Src\Parser\AST\CSharp\Expressions\DefaultValueExpression.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>
<Content Include="Src\Lexer\CSharp\KeywordList.txt" />

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

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

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

@ -1172,14 +1172,14 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1172,14 +1172,14 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.IndentationLevel -= 1;
}
void PrintIndentedBlock(ArrayList statements)
void PrintIndentedBlock(IEnumerable statements)
{
outputFormatter.IndentationLevel += 1;
VisitStatementList(statements);
outputFormatter.IndentationLevel -= 1;
}
void VisitStatementList(ArrayList statements)
void VisitStatementList(IEnumerable statements)
{
foreach (Statement stmt in statements) {
if (stmt is BlockStatement) {
@ -1321,6 +1321,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1321,6 +1321,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Then);
outputFormatter.NewLine();
PrintIndentedBlock(ifElseStatement.TrueStatement);
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 @@ -14,14 +14,10 @@ namespace ICSharpCode.NRefactory.Parser.AST
{
public class CompilationUnit : AbstractNode
{
// TODO: check if the LookUpTable here and the specials are still needed
// TODO: Are the childs still needed? Or should we put them in there own fields?
// Childs in C#: UsingAliasDeclaration, UsingDeclaration, AttributeSection, NamespaceDeclaration
// Childs in VB: OptionStatements, ImportsStatement, AttributeSection, NamespaceDeclaration
// Children in C#: UsingAliasDeclaration, UsingDeclaration, AttributeSection, NamespaceDeclaration
// Children in VB: OptionStatements, ImportsStatement, AttributeSection, NamespaceDeclaration
Stack blockStack = new Stack();
INode lastChild = null;
ArrayList lookUpTable = new ArrayList(); // [VariableDeclaration]
public CompilationUnit()
{
@ -35,12 +31,7 @@ namespace ICSharpCode.NRefactory.Parser.AST @@ -35,12 +31,7 @@ namespace ICSharpCode.NRefactory.Parser.AST
public void BlockEnd()
{
lastChild = (INode)blockStack.Pop();
}
public INode TakeBlock()
{
return (INode)blockStack.Pop();
blockStack.Pop();
}
public override void AddChild(INode childNode)
@ -49,19 +40,9 @@ namespace ICSharpCode.NRefactory.Parser.AST @@ -49,19 +40,9 @@ namespace ICSharpCode.NRefactory.Parser.AST
INode parent = (INode)blockStack.Peek();
parent.Children.Add(childNode);
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)
{
return visitor.Visit(this, data);

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

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

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

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

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

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

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

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

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

@ -1883,7 +1883,7 @@ EmbeddedStatement<out Statement statement> @@ -1883,7 +1883,7 @@ EmbeddedStatement<out Statement statement>
EmbeddedStatement<out embeddedStatement> (. statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.Start);.)
| "do" EmbeddedStatement<out embeddedStatement> "while"
"(" 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> ] ";"
[ Expr<out expr> ] ";"
[ ForIterator<out iterator> ] ")"
@ -1929,20 +1929,20 @@ EmbeddedStatement<out Statement statement> @@ -1929,20 +1929,20 @@ EmbeddedStatement<out Statement statement>
")" EmbeddedStatement<out embeddedStatement> (. statement = new FixedStatement(type, pointerDeclarators, embeddedStatement); .)
.
ForInitializer<out ArrayList initializer>
ForInitializer<out List<Statement> initializer>
(.
Statement stmt;
initializer = new ArrayList();
initializer = new List<Statement>();
.)
=
IF (IsLocalVarDecl()) LocalVariableDecl<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;
iterator = new ArrayList();
iterator = new List<Statement>();
.)
=
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); @@ -5220,7 +5220,7 @@ out expr);
Expression start = null;
Expression end = null;
Expression step = null;
Expression nextExpr = null;ArrayList nextExpressions = null;
Expression nextExpr = null;List<Expression> nextExpressions = null;
LoopControlVariable(
#line 2500 "VBNET.ATG"
@ -5250,7 +5250,7 @@ out embeddedStatement); @@ -5250,7 +5250,7 @@ out embeddedStatement);
out nextExpr);
#line 2505 "VBNET.ATG"
nextExpressions = new ArrayList(); nextExpressions.Add(nextExpr);
nextExpressions = new List<Expression>(); nextExpressions.Add(nextExpr);
while (la.kind == 12) {
lexer.NextToken();
Expr(

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

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

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

@ -0,0 +1,243 @@ @@ -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; @@ -11,7 +11,6 @@ using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.NRefactory.Parser.AST;
@ -20,218 +19,13 @@ namespace ICSharpCode.NRefactory.Parser @@ -20,218 +19,13 @@ namespace ICSharpCode.NRefactory.Parser
/// <summary>
/// This class converts C# constructs to their VB.NET equivalents.
/// </summary>
public class CSharpToVBNetConvertVisitor : AbstractASTVisitor
public class CSharpToVBNetConvertVisitor : CSharpConstructsVisitor
{
// The following conversions are implemented:
// 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);
// 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)
public override object Visit(CompilationUnit compilationUnit, object data)
{
// 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);
base.Visit(compilationUnit, data);
compilationUnit.AcceptVisitor(new ToVBNetConvertVisitor(), data);
return null;
}
}
}

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

@ -142,29 +142,5 @@ namespace ICSharpCode.NRefactory.Parser @@ -142,29 +142,5 @@ namespace ICSharpCode.NRefactory.Parser
}
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 @@ @@ -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 @@ @@ -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 @@ @@ -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; @@ -12,49 +12,22 @@ 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>
/// 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 : AbstractASTVisitor
public class VBNetToCSharpConvertVisitor : VBNetConstructsConvertVisitor
{
// 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:
// 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)
public override object Visit(CompilationUnit compilationUnit, 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);
base.Visit(compilationUnit, data);
compilationUnit.AcceptVisitor(new ToCSharpConvertVisitor(), data);
return null;
}
}
}

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

@ -30,6 +30,21 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter @@ -30,6 +30,21 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
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)
{
StringBuilder b = new StringBuilder();
@ -85,11 +100,53 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter @@ -85,11 +100,53 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
"\tb(i) = s(i)\n" +
"Next");
}
[Test]
public void AddEventHandler()
{
TestStatement("this.button1.Click += new System.EventHandler(this.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