From 57d92d186df8ffefe7ec364f0335b6bca13f956a Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 6 Jul 2011 14:29:40 +0200 Subject: [PATCH] add support for OperatorDeclaration and some more statements --- ICSharpCode.NRefactory.VB/Ast/Enums.cs | 60 +----- .../Ast/Statements/DoLoopStatement.cs | 21 ++ .../Ast/Statements/ExitStatement.cs | 55 +++++ .../Ast/Statements/ForEachStatement.cs | 38 ++++ .../Ast/Statements/ForStatement.cs | 21 ++ .../Ast/Statements/SelectStatement.cs | 41 ++++ .../Ast/TypeMembers/OperatorDeclaration.cs | 83 ++++++++ .../Ast/VBModifierToken.cs | 7 + ICSharpCode.NRefactory.VB/IAstVisitor.cs | 5 + .../ICSharpCode.NRefactory.VB.csproj | 6 + .../OutputVisitor/OutputVisitor.cs | 201 +++++++++++++++++- .../Visitors/CSharpToVBConverterVisitor.cs | 161 +++++++++++++- .../Ast/TypeMembers/OperatorDeclaration.cs | 2 +- 13 files changed, 633 insertions(+), 68 deletions(-) create mode 100644 ICSharpCode.NRefactory.VB/Ast/Statements/DoLoopStatement.cs create mode 100644 ICSharpCode.NRefactory.VB/Ast/Statements/ExitStatement.cs create mode 100644 ICSharpCode.NRefactory.VB/Ast/Statements/ForEachStatement.cs create mode 100644 ICSharpCode.NRefactory.VB/Ast/Statements/ForStatement.cs create mode 100644 ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs create mode 100644 ICSharpCode.NRefactory.VB/Ast/TypeMembers/OperatorDeclaration.cs diff --git a/ICSharpCode.NRefactory.VB/Ast/Enums.cs b/ICSharpCode.NRefactory.VB/Ast/Enums.cs index b54c49b65a..b69ae9aa38 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Enums.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Enums.cs @@ -45,6 +45,9 @@ namespace ICSharpCode.NRefactory.VB.Ast ParamArray = 0x800000, Optional = 0x1000000, + Narrowing = 0x2000000, + Widening = 0x4000000, + /// /// Special value used to match any modifiers during pattern matching. /// @@ -108,19 +111,6 @@ namespace ICSharpCode.NRefactory.VB.Ast End } - public enum ExitType - { - None, - Sub, - Function, - Property, - Do, - For, - While, - Select, - Try - } - public enum ConstructorInitializerType { None, @@ -135,50 +125,6 @@ namespace ICSharpCode.NRefactory.VB.Ast Explicit } - public enum OverloadableOperatorType - { - None, - - Add, - Subtract, - Multiply, - Divide, - Modulus, - Concat, - - UnaryPlus, - UnaryMinus, - - Not, - BitNot, - - BitwiseAnd, - BitwiseOr, - ExclusiveOr, - - ShiftLeft, - ShiftRight, - - GreaterThan, - GreaterThanOrEqual, - Equality, - InEquality, - LessThan, - LessThanOrEqual, - - Increment, - Decrement, - - IsTrue, - IsFalse, - - // VB specific - Like, - Power, - CType, - DivideInteger - } - /// /// Charset types, used in external methods /// declarations (VB only). diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/DoLoopStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/DoLoopStatement.cs new file mode 100644 index 0000000000..0b2101c176 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/DoLoopStatement.cs @@ -0,0 +1,21 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.IO; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class DoLoopStatement : Statement + { + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ExitStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ExitStatement.cs new file mode 100644 index 0000000000..5868523259 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ExitStatement.cs @@ -0,0 +1,55 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.IO; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Exit ( Do | For | While | Select | Sub | Function | Property | Try ) + /// + public class ExitStatement : Statement + { + public static readonly Role ExitKindTokenRole = new Role("ExitKindTokenRole"); + + public ExitKind ExitKind { get; set; } + + public VBTokenNode ExitToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public VBTokenNode ExitKindToken { + get { return GetChildByRole (ExitKindTokenRole); } + } + + public ExitStatement(ExitKind kind) + { + this.ExitKind = kind; + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitExitStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ExitStatement o = other as ExitStatement; + return o != null && this.ExitKind == o.ExitKind; + } + } + + public enum ExitKind + { + None, + Sub, + Function, + Property, + Do, + For, + While, + Select, + Try + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ForEachStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ForEachStatement.cs new file mode 100644 index 0000000000..5f9532d146 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ForEachStatement.cs @@ -0,0 +1,38 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.IO; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class ForEachStatement : Statement + { + public static readonly Role InitializerRole = new Role("InitializerRole", Statement.Null); + + public Statement Initializer { + get { return GetChildByRole(InitializerRole); } + set { SetChildByRole(InitializerRole, value); } + } + + public Expression InExpression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public BlockStatement Body { + get { return GetChildByRole(Roles.Body); } + set { SetChildByRole(Roles.Body, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitForEachStatement(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ForStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ForStatement.cs new file mode 100644 index 0000000000..f4abbebff9 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ForStatement.cs @@ -0,0 +1,21 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.IO; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class ForStatement : Statement + { + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitForStatement(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs new file mode 100644 index 0000000000..95b576fd7e --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs @@ -0,0 +1,41 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.IO; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class SelectStatement : Statement + { + public Expression Expression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitSelectStatement(this, data); + } + } + + public class CaseStatement : Statement + { + + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/OperatorDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/OperatorDeclaration.cs new file mode 100644 index 0000000000..8e3574e530 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/OperatorDeclaration.cs @@ -0,0 +1,83 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class OperatorDeclaration : MemberDeclaration + { + public OperatorDeclaration() + { + } + + public OverloadableOperatorType Operator { get; set; } + + public AstNodeCollection Parameters { + get { return GetChildrenByRole(Roles.Parameter); } + } + + public AstNodeCollection ReturnTypeAttributes { + get { return GetChildrenByRole(AttributeBlock.ReturnTypeAttributeBlockRole); } + } + + public AstType ReturnType { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + public BlockStatement Body { + get { return GetChildByRole(Roles.Body); } + set { SetChildByRole(Roles.Body, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitOperatorDeclaration(this, data); + } + } + + public enum OverloadableOperatorType + { + None, + + Add, + Subtract, + Multiply, + Divide, + Modulus, + Concat, + + UnaryPlus, + UnaryMinus, + + Not, + + BitwiseAnd, + BitwiseOr, + ExclusiveOr, + + ShiftLeft, + ShiftRight, + + GreaterThan, + GreaterThanOrEqual, + Equality, + InEquality, + LessThan, + LessThanOrEqual, + + IsTrue, + IsFalse, + + Like, + Power, + CType, + DivideInteger + }// +} diff --git a/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs b/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs index 2050582617..45b8997860 100644 --- a/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs +++ b/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs @@ -63,6 +63,9 @@ namespace ICSharpCode.NRefactory.VB.Ast new KeyValuePair(Modifiers.ByVal, "ByVal".Length), new KeyValuePair(Modifiers.ByRef, "ByRef".Length), new KeyValuePair(Modifiers.ParamArray, "ParamArray".Length), + // operator modifiers + new KeyValuePair(Modifiers.Narrowing, "Narrowing".Length), + new KeyValuePair(Modifiers.Widening, "Widening".Length), // even though it's used for patterns only, it needs to be in this table to be usable in the AST new KeyValuePair(Modifiers.Any, "Any".Length) }; @@ -129,6 +132,10 @@ namespace ICSharpCode.NRefactory.VB.Ast return "ByRef"; case Modifiers.ParamArray: return "ParamArray"; + case Modifiers.Widening: + return "Widening"; + case Modifiers.Narrowing: + return "Narrowing"; default: throw new NotSupportedException("Invalid value for Modifiers: " + modifier); } diff --git a/ICSharpCode.NRefactory.VB/IAstVisitor.cs b/ICSharpCode.NRefactory.VB/IAstVisitor.cs index 3f8fb034c5..c9bad327ce 100644 --- a/ICSharpCode.NRefactory.VB/IAstVisitor.cs +++ b/ICSharpCode.NRefactory.VB/IAstVisitor.cs @@ -41,6 +41,7 @@ namespace ICSharpCode.NRefactory.VB { S VisitAccessor(Accessor accessor, T data); S VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, T data); S VisitEventDeclaration(EventDeclaration eventDeclaration, T data); + S VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, T data); // Expression scope S VisitIdentifier(Identifier identifier, T data); @@ -81,6 +82,10 @@ namespace ICSharpCode.NRefactory.VB { S VisitCatchBlock(CatchBlock catchBlock, T data); S VisitReturnStatement(ReturnStatement returnStatement, T data); S VisitWhileStatement(WhileStatement whileStatement, T data); + S VisitForStatement(ForStatement forStatement, T data); + S VisitForEachStatement(ForEachStatement forEachStatement, T data); + S VisitExitStatement(ExitStatement exitStatement, T data); + S VisitSelectStatement(SelectStatement selectStatement, T data); // TypeName S VisitPrimitiveType(PrimitiveType primitiveType, T data); diff --git a/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj b/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj index 7f289bca8a..8955b43d14 100644 --- a/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj +++ b/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj @@ -86,11 +86,16 @@ + + + + + @@ -102,6 +107,7 @@ + diff --git a/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs b/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs index d04c03ba0f..71d60b3c7a 100644 --- a/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs +++ b/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs @@ -1372,7 +1372,8 @@ namespace ICSharpCode.NRefactory.VB { StartNode(localDeclarationStatement); - WriteModifiers(new [] { localDeclarationStatement.ModifierToken }); + if (localDeclarationStatement.ModifierToken != null && !localDeclarationStatement.ModifierToken.IsNull) + WriteModifiers(new [] { localDeclarationStatement.ModifierToken }); WriteCommaSeparatedList(localDeclarationStatement.Variables); return EndNode(localDeclarationStatement); @@ -1380,12 +1381,30 @@ namespace ICSharpCode.NRefactory.VB public object VisitWithStatement(WithStatement withStatement, object data) { - throw new NotImplementedException(); + StartNode(withStatement); + WriteKeyword("With"); + withStatement.Expression.AcceptVisitor(this, data); + NewLine(); + Indent(); + withStatement.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("End"); + WriteKeyword("With"); + return EndNode(withStatement); } public object VisitSyncLockStatement(SyncLockStatement syncLockStatement, object data) { - throw new NotImplementedException(); + StartNode(syncLockStatement); + WriteKeyword("SyncLock"); + syncLockStatement.Expression.AcceptVisitor(this, data); + NewLine(); + Indent(); + syncLockStatement.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("End"); + WriteKeyword("SyncLock"); + return EndNode(syncLockStatement); } public object VisitTryStatement(TryStatement tryStatement, object data) @@ -1601,7 +1620,6 @@ namespace ICSharpCode.NRefactory.VB case AssignmentOperatorType.DivideInteger: WriteToken("\\=", AssignmentExpression.OperatorRole); break; - break; case AssignmentOperatorType.ConcatString: WriteToken("&=", AssignmentExpression.OperatorRole); break; @@ -1882,5 +1900,180 @@ namespace ICSharpCode.NRefactory.VB return EndNode(whileStatement); } + + public object VisitExitStatement(ExitStatement exitStatement, object data) + { + StartNode(exitStatement); + + WriteKeyword("Exit"); + + switch (exitStatement.ExitKind) { + case ExitKind.Sub: + WriteKeyword("Sub"); + break; + case ExitKind.Function: + WriteKeyword("Function"); + break; + case ExitKind.Property: + WriteKeyword("Property"); + break; + case ExitKind.Do: + WriteKeyword("Do"); + break; + case ExitKind.For: + WriteKeyword("For"); + break; + case ExitKind.While: + WriteKeyword("While"); + break; + case ExitKind.Select: + WriteKeyword("Select"); + break; + case ExitKind.Try: + WriteKeyword("Try"); + break; + default: + throw new Exception("Invalid value for ExitKind"); + } + + return EndNode(exitStatement); + } + + public object VisitForStatement(ForStatement forStatement, object data) + { + StartNode(forStatement); + + throw new NotImplementedException(); + + return EndNode(forStatement); + } + + public object VisitForEachStatement(ForEachStatement forEachStatement, object data) + { + StartNode(forEachStatement); + + WriteKeyword("For"); + WriteKeyword("Each"); + forEachStatement.Initializer.AcceptVisitor(this, data); + WriteKeyword("In"); + forEachStatement.InExpression.AcceptVisitor(this, data); + NewLine(); + Indent(); + forEachStatement.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("Next"); + + return EndNode(forEachStatement); + } + + public object VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, object data) + { + StartNode(operatorDeclaration); + + WriteAttributes(operatorDeclaration.Attributes); + WriteModifiers(operatorDeclaration.ModifierTokens); + WriteKeyword("Operator"); + switch (operatorDeclaration.Operator) { + case OverloadableOperatorType.Add: + case OverloadableOperatorType.UnaryPlus: + WriteToken("+", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.Subtract: + case OverloadableOperatorType.UnaryMinus: + WriteToken("-", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.Multiply: + WriteToken("*", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.Divide: + WriteToken("/", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.Modulus: + WriteKeyword("Mod"); + break; + case OverloadableOperatorType.Concat: + WriteToken("&", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.Not: + WriteKeyword("Not"); + break; + case OverloadableOperatorType.BitwiseAnd: + WriteKeyword("And"); + break; + case OverloadableOperatorType.BitwiseOr: + WriteKeyword("Or"); + break; + case OverloadableOperatorType.ExclusiveOr: + WriteKeyword("Xor"); + break; + case OverloadableOperatorType.ShiftLeft: + WriteToken("<<", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.ShiftRight: + WriteToken(">>", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.GreaterThan: + WriteToken(">", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.GreaterThanOrEqual: + WriteToken(">=", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.Equality: + WriteToken("=", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.InEquality: + WriteToken("<>", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.LessThan: + WriteToken("<", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.LessThanOrEqual: + WriteToken("<=", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.IsTrue: + WriteKeyword("IsTrue"); + break; + case OverloadableOperatorType.IsFalse: + WriteKeyword("IsFalse"); + break; + case OverloadableOperatorType.Like: + WriteKeyword("Like"); + break; + case OverloadableOperatorType.Power: + WriteToken("^", OperatorDeclaration.Roles.Keyword); + break; + case OverloadableOperatorType.CType: + WriteKeyword("CType"); + break; + case OverloadableOperatorType.DivideInteger: + WriteToken("\\", OperatorDeclaration.Roles.Keyword); + break; + default: + throw new Exception("Invalid value for OverloadableOperatorType"); + } + WriteCommaSeparatedListInParenthesis(operatorDeclaration.Parameters, false); + if (!operatorDeclaration.ReturnType.IsNull) { + Space(); + WriteKeyword("As"); + WriteAttributes(operatorDeclaration.ReturnTypeAttributes); + operatorDeclaration.ReturnType.AcceptVisitor(this, data); + } + if (!operatorDeclaration.Body.IsNull) { + NewLine(); + Indent(); + WriteBlock(operatorDeclaration.Body); + Unindent(); + WriteKeyword("End"); + WriteKeyword("Operator"); + } + NewLine(); + + return EndNode(operatorDeclaration); + } + + public object VisitSelectStatement(SelectStatement selectStatement, object data) + { + throw new NotImplementedException(); + } } } diff --git a/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs b/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs index 97abcb4b59..b5d81087ae 100644 --- a/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs +++ b/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Security.Cryptography.X509Certificates; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.VB.Ast; @@ -24,10 +25,12 @@ namespace ICSharpCode.NRefactory.VB.Visitors public class CSharpToVBConverterVisitor : CSharp.IAstVisitor { IEnvironmentProvider provider; + Stack blocks; public CSharpToVBConverterVisitor(IEnvironmentProvider provider) { this.provider = provider; + this.blocks = new Stack(); } public AstNode VisitAnonymousMethodExpression(CSharp.AnonymousMethodExpression anonymousMethodExpression, object data) @@ -691,14 +694,48 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitBlockStatement(CSharp.BlockStatement blockStatement, object data) { var block = new BlockStatement(); + blocks.Push(block); ConvertNodes(blockStatement, block.Statements); - + blocks.Pop(); return EndNode(blockStatement, block); } public AstNode VisitBreakStatement(CSharp.BreakStatement breakStatement, object data) { - throw new NotImplementedException(); + var exit = new ExitStatement(ExitKind.None); + + foreach (var stmt in breakStatement.Ancestors) { + if (stmt is CSharp.MethodDeclaration) { + exit.ExitKind = IsSub(((CSharp.MethodDeclaration)stmt).ReturnType) ? ExitKind.Sub : ExitKind.Function; + break; + } + if (stmt is CSharp.PropertyDeclaration) { + exit.ExitKind = ExitKind.Property; + break; + } + if (stmt is CSharp.DoWhileStatement) { + exit.ExitKind = ExitKind.Do; + break; + } + if (stmt is CSharp.ForStatement || stmt is CSharp.ForeachStatement) { + exit.ExitKind = ExitKind.For; + break; + } + if (stmt is CSharp.WhileStatement) { + exit.ExitKind = ExitKind.While; + break; + } + if (stmt is CSharp.SwitchStatement) { + exit.ExitKind = ExitKind.Select; + break; + } + if (stmt is CSharp.TryCatchStatement) { + exit.ExitKind = ExitKind.Try; + break; + } + } + + return EndNode(breakStatement, exit); } public AstNode VisitCheckedStatement(CSharp.CheckedStatement checkedStatement, object data) @@ -729,17 +766,41 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitFixedStatement(CSharp.FixedStatement fixedStatement, object data) { + // see http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle%28v=VS.100%29.aspx throw new NotImplementedException(); } public AstNode VisitForeachStatement(CSharp.ForeachStatement foreachStatement, object data) { - throw new NotImplementedException(); + var var = new LocalDeclarationStatement(); + + var.Variables.Add(new VariableDeclarator() { Type = (AstType)foreachStatement.VariableType.AcceptVisitor(this, data) }); + var.Variables.Last().Identifiers.Add(new VariableIdentifier() { Name = foreachStatement.VariableName }); + + var stmt = new ForEachStatement() { + Body = (BlockStatement)foreachStatement.EmbeddedStatement.AcceptVisitor(this, data), + InExpression = (Expression)foreachStatement.InExpression.AcceptVisitor(this, data), + Initializer = var + }; + + return EndNode(foreachStatement, stmt); } public AstNode VisitForStatement(CSharp.ForStatement forStatement, object data) { - throw new NotImplementedException(); + // for (;;) ; + if (!forStatement.Initializers.Any() && forStatement.Condition.IsNull && !forStatement.Iterators.Any()) + return EndNode(forStatement, new WhileStatement() { Condition = new PrimitiveExpression(true), Body = (BlockStatement)forStatement.EmbeddedStatement.AcceptVisitor(this, data) }); + + var stmt = new WhileStatement() { + Condition = (Expression)forStatement.Condition.AcceptVisitor(this, data), + Body = (BlockStatement)forStatement.EmbeddedStatement.AcceptVisitor(this, data) + }; + ConvertNodes(forStatement.Iterators, stmt.Body.Statements); + foreach (var initializer in forStatement.Initializers) + blocks.Peek().Statements.Add((Statement)initializer.AcceptVisitor(this, data)); + + return EndNode(forStatement, stmt); } public AstNode VisitGotoCaseStatement(CSharp.GotoCaseStatement gotoCaseStatement, object data) @@ -775,7 +836,12 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitLockStatement(CSharp.LockStatement lockStatement, object data) { - throw new NotImplementedException(); + var stmt = new SyncLockStatement(); + + stmt.Expression = (Expression)lockStatement.Expression.AcceptVisitor(this, data); + stmt.Body = (BlockStatement)lockStatement.EmbeddedStatement.AcceptVisitor(this, data); + + return EndNode(lockStatement, stmt); } public AstNode VisitReturnStatement(CSharp.ReturnStatement returnStatement, object data) @@ -1023,7 +1089,90 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitOperatorDeclaration(CSharp.OperatorDeclaration operatorDeclaration, object data) { - throw new NotImplementedException(); + var result = new OperatorDeclaration(); + ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes); + ConvertNodes(operatorDeclaration.ModifierTokens, result.ModifierTokens); + switch (operatorDeclaration.OperatorType) { + case ICSharpCode.NRefactory.CSharp.OperatorType.LogicalNot: + case ICSharpCode.NRefactory.CSharp.OperatorType.OnesComplement: + result.Operator = OverloadableOperatorType.Not; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Increment: + case ICSharpCode.NRefactory.CSharp.OperatorType.Decrement: + case ICSharpCode.NRefactory.CSharp.OperatorType.True: + case ICSharpCode.NRefactory.CSharp.OperatorType.False: + throw new NotSupportedException(); + case ICSharpCode.NRefactory.CSharp.OperatorType.Implicit: + result.Modifiers |= Modifiers.Widening; + result.Operator = OverloadableOperatorType.CType; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Explicit: + result.Modifiers |= Modifiers.Narrowing; + result.Operator = OverloadableOperatorType.CType; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Addition: + result.Operator = OverloadableOperatorType.Add; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Subtraction: + result.Operator = OverloadableOperatorType.Subtract; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.UnaryPlus: + result.Operator = OverloadableOperatorType.UnaryPlus; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.UnaryNegation: + result.Operator = OverloadableOperatorType.UnaryMinus; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Multiply: + result.Operator = OverloadableOperatorType.Multiply; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Division: + result.Operator = OverloadableOperatorType.Divide; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Modulus: + result.Operator = OverloadableOperatorType.Modulus; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.BitwiseAnd: + result.Operator = OverloadableOperatorType.BitwiseAnd; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.BitwiseOr: + result.Operator = OverloadableOperatorType.BitwiseOr; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.ExclusiveOr: + result.Operator = OverloadableOperatorType.ExclusiveOr; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.LeftShift: + result.Operator = OverloadableOperatorType.ShiftLeft; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.RightShift: + result.Operator = OverloadableOperatorType.ShiftRight; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Equality: + result.Operator = OverloadableOperatorType.Equality; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Inequality: + result.Operator = OverloadableOperatorType.InEquality; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.GreaterThan: + result.Operator = OverloadableOperatorType.GreaterThan; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.LessThan: + result.Operator = OverloadableOperatorType.LessThan; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.GreaterThanOrEqual: + result.Operator = OverloadableOperatorType.GreaterThanOrEqual; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.LessThanOrEqual: + result.Operator = OverloadableOperatorType.LessThanOrEqual; + break; + default: + throw new Exception("Invalid value for OperatorType"); + } + ConvertNodes(operatorDeclaration.Parameters, result.Parameters); + ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes); + result.ReturnType = (AstType)operatorDeclaration.ReturnType.AcceptVisitor(this, data); + result.Body = (BlockStatement)operatorDeclaration.Body.AcceptVisitor(this, data); + + return EndNode(operatorDeclaration, result); } public AstNode VisitParameterDeclaration(CSharp.ParameterDeclaration parameterDeclaration, object data) diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs index c7e68ab029..80cff91ddc 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs @@ -29,7 +29,7 @@ using System.Linq; namespace ICSharpCode.NRefactory.CSharp { - public enum OperatorType + public enum OperatorType { // Values must correspond to Mono.CSharp.Operator.OpType // due to the casts used in OperatorDeclaration.