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 @@ |
|||||||
// <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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
// <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