Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@959 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
24 changed files with 655 additions and 436 deletions
@ -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 < 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
|
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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
|
||||
|
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue