diff --git a/ICSharpCode.NRefactory.VB/Ast/AstNode.cs b/ICSharpCode.NRefactory.VB/Ast/AstNode.cs index 7a79baf682..57c6498768 100644 --- a/ICSharpCode.NRefactory.VB/Ast/AstNode.cs +++ b/ICSharpCode.NRefactory.VB/Ast/AstNode.cs @@ -1,28 +1,5 @@ -// -// AstNode.cs -// -// Author: -// Mike Krüger -// -// Copyright (c) 2009 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// 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.Collections; @@ -532,13 +509,13 @@ namespace ICSharpCode.NRefactory.VB public static readonly Role XmlIdentifier = new Role("XmlIdentifier", Ast.XmlIdentifier.Null); public static readonly Role XmlLiteralString = new Role("XmlLiteralString", Ast.XmlLiteralString.Null); -// public static readonly Role Body = new Role("Body", CSharp.BlockStatement.Null); + public static readonly Role Body = new Role("Body", Ast.BlockStatement.Null); public static readonly Role Parameter = new Role("Parameter"); public static readonly Role Argument = new Role("Argument", Ast.Expression.Null); public static readonly Role Type = new Role("Type", AstType.Null); public static readonly Role Expression = new Role("Expression", Ast.Expression.Null); -// public static readonly Role TargetExpression = new Role("Target", CSharp.Expression.Null); -// public readonly static Role Condition = new Role("Condition", CSharp.Expression.Null); + public static readonly Role TargetExpression = new Role("Target", Ast.Expression.Null); + public readonly static Role Condition = new Role("Condition", Ast.Expression.Null); // public static readonly Role TypeParameter = new Role("TypeParameter"); public static readonly Role TypeArgument = new Role("TypeArgument", AstType.Null); @@ -558,6 +535,7 @@ namespace ICSharpCode.NRefactory.VB public static readonly Role LChevron = new Role("LChevron", VBTokenNode.Null); public static readonly Role RChevron = new Role("RChevron", VBTokenNode.Null); public static readonly Role Comma = new Role("Comma", VBTokenNode.Null); + public static readonly Role QuestionMark = new Role("QuestionMark", VBTokenNode.Null); public static readonly Role Dot = new Role("Dot", VBTokenNode.Null); public static readonly Role Semicolon = new Role("Semicolon", VBTokenNode.Null); public static readonly Role Assign = new Role("Assign", VBTokenNode.Null); @@ -579,8 +557,5 @@ namespace ICSharpCode.NRefactory.VB } } - public class Comment - { - - } + } diff --git a/ICSharpCode.NRefactory.VB/Ast/Comment.cs b/ICSharpCode.NRefactory.VB/Ast/Comment.cs new file mode 100644 index 0000000000..ee8f6b3853 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Comment.cs @@ -0,0 +1,67 @@ +// 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.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using ICSharpCode.NRefactory.PatternMatching; +using ICSharpCode.NRefactory.VB.Ast; + +namespace ICSharpCode.NRefactory.VB +{ + public class Comment : AstNode + { + public bool IsDocumentationComment { get; set; } + + public bool StartsLine { + get; + set; + } + + public string Content { + get; + set; + } + + AstLocation startLocation; + public override AstLocation StartLocation { + get { + return startLocation; + } + } + + AstLocation endLocation; + public override AstLocation EndLocation { + get { + return endLocation; + } + } + + public Comment (string content, bool isDocumentation = false) + { + this.IsDocumentationComment = isDocumentation; + this.Content = content; + } + + public Comment (bool isDocumentation, AstLocation startLocation, AstLocation endLocation) + { + this.IsDocumentationComment = isDocumentation; + this.startLocation = startLocation; + this.endLocation = endLocation; + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitComment(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + Comment o = other as Comment; + return o != null && this.IsDocumentationComment == o.IsDocumentationComment && MatchString(this.Content, o.Content); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Enums.cs b/ICSharpCode.NRefactory.VB/Ast/Enums.cs index d0fc139296..e030125433 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Enums.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Enums.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; @@ -25,7 +25,7 @@ namespace ICSharpCode.NRefactory.VB.Ast Const = 0x0200, Shared = 0x0400, Static = 0x0800, - Override = 0x1000, + Overrides = 0x1000, ReadOnly = 0x2000, Shadows = 0x4000, Partial = 0x8000, @@ -45,6 +45,12 @@ namespace ICSharpCode.NRefactory.VB.Ast ParamArray = 0x800000, Optional = 0x1000000, + Narrowing = 0x2000000, + Widening = 0x4000000, + + Iterator = 0x8000000, + Async = 0x10000000, + /// /// Special value used to match any modifiers during pattern matching. /// @@ -67,13 +73,6 @@ namespace ICSharpCode.NRefactory.VB.Ast Ref } - public enum VarianceModifier - { - Invariant, - Covariant, - Contravariant - }; - public enum AssignmentOperatorType { None, @@ -83,7 +82,6 @@ namespace ICSharpCode.NRefactory.VB.Ast Subtract, Multiply, Divide, - Modulus, Power, // (VB only) DivideInteger, // (VB only) @@ -91,117 +89,6 @@ namespace ICSharpCode.NRefactory.VB.Ast ShiftLeft, ShiftRight, - - BitwiseAnd, - BitwiseOr, - ExclusiveOr, - } - - public enum BinaryOperatorType - { - None, - - /// '&' in C#, 'And' in VB. - BitwiseAnd, - /// '|' in C#, 'Or' in VB. - BitwiseOr, - /// '&&' in C#, 'AndAlso' in VB. - LogicalAnd, - /// '||' in C#, 'OrElse' in VB. - LogicalOr, - /// '^' in C#, 'Xor' in VB. - ExclusiveOr, - - /// > - GreaterThan, - /// >= - GreaterThanOrEqual, - /// '==' in C#, '=' in VB. - Equality, - /// '!=' in C#, '<>' in VB. - InEquality, - /// < - LessThan, - /// <= - LessThanOrEqual, - - /// + - Add, - /// - - Subtract, - /// * - Multiply, - /// / - Divide, - /// '%' in C#, 'Mod' in VB. - Modulus, - /// VB-only: \ - DivideInteger, - /// VB-only: ^ - Power, - /// VB-only: & - Concat, - - /// C#: << - ShiftLeft, - /// C#: >> - ShiftRight, - /// VB-only: Is - ReferenceEquality, - /// VB-only: IsNot - ReferenceInequality, - - /// VB-only: Like - Like, - /// - /// C#: ?? - /// VB: IF(x, y) - /// - NullCoalescing, - - /// VB-only: ! - DictionaryAccess - } - - public enum CastType - { - /// - /// direct cast (C#, VB "DirectCast") - /// - Cast, - /// - /// try cast (C# "as", VB "TryCast") - /// - TryCast, - /// - /// converting cast (VB "CType") - /// - Conversion, - /// - /// primitive converting cast (VB "CString" etc.) - /// - PrimitiveConversion - } - - public enum UnaryOperatorType - { - None, - Not, - BitNot, - - Minus, - Plus, - - Increment, - Decrement, - - PostIncrement, - PostDecrement, - - /// Dereferencing pointer - Dereference, - /// Get address of - AddressOf } public enum ContinueType @@ -215,38 +102,12 @@ namespace ICSharpCode.NRefactory.VB.Ast public enum ConditionType { None, - Until, - While, + LoopUntil, + LoopWhile, + DoUntil, DoWhile } - public enum ConditionPosition - { - None, - Start, - End - } - - public enum ExitType - { - None, - Sub, - Function, - Property, - Do, - For, - While, - Select, - Try - } - - public enum ConstructorInitializerType - { - None, - Base, - This - } - public enum ConversionType { None, @@ -254,66 +115,10 @@ 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). - /// - public enum CharsetModifier - { - None, - Auto, - Unicode, - Ansi - } - /// /// Specifies the ordering direction of a QueryExpressionOrdering node. /// - public enum QueryExpressionOrderingDirection + public enum QueryOrderingDirection { None, Ascending, @@ -324,7 +129,7 @@ namespace ICSharpCode.NRefactory.VB.Ast /// Specifies the partition type for a VB.NET /// query expression. /// - public enum QueryExpressionPartitionType + public enum PartitionKind { Take, TakeWhile, diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/AnonymousObjectCreationExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/AnonymousObjectCreationExpression.cs new file mode 100644 index 0000000000..ac3f8d0daa --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/AnonymousObjectCreationExpression.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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class AnonymousObjectCreationExpression : Expression + { + public AstNodeCollection Initializer { + get { return GetChildrenByRole(Roles.Expression); } + } + + public AnonymousObjectCreationExpression () + { + } + + public AnonymousObjectCreationExpression (IEnumerable initializer) + { + foreach (var ini in initializer) { + AddChild (ini, Roles.Expression); + } + } + + public AnonymousObjectCreationExpression (params Expression[] initializer) : this ((IEnumerable)initializer) + { + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitAnonymousObjectCreationExpression(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + var o = other as AnonymousObjectCreationExpression; + return o != null && this.Initializer.DoMatch(o.Initializer, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/ArrayCreateExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/ArrayCreateExpression.cs new file mode 100644 index 0000000000..b3f580894f --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/ArrayCreateExpression.cs @@ -0,0 +1,64 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// New Type[Dimensions] + /// + public class ArrayCreateExpression : Expression + { + public readonly static Role AdditionalArraySpecifierRole = new Role("AdditionalArraySpecifier"); + public readonly static Role InitializerRole = new Role("Initializer", ArrayInitializerExpression.Null); + + public AstType Type { + get { return GetChildByRole (Roles.Type); } + set { SetChildByRole (Roles.Type, value); } + } + + public AstNodeCollection Arguments { + get { return GetChildrenByRole (Roles.Argument); } + } + + /// + /// Gets additional array ranks (those without size info). + /// Empty for "New Integer(5,1)"; will contain a single element for "New Integer(5)()". + /// + public AstNodeCollection AdditionalArraySpecifiers { + get { return GetChildrenByRole(AdditionalArraySpecifierRole); } + } + + public ArrayInitializerExpression Initializer { + get { return GetChildByRole (InitializerRole); } + set { SetChildByRole (InitializerRole, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitArrayCreateExpression (this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ArrayCreateExpression o = other as ArrayCreateExpression; + return o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match) && this.AdditionalArraySpecifiers.DoMatch(o.AdditionalArraySpecifiers, match) && this.Initializer.DoMatch(o.Initializer, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/ArrayInitializerExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/ArrayInitializerExpression.cs new file mode 100644 index 0000000000..785f2c19b1 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/ArrayInitializerExpression.cs @@ -0,0 +1,53 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// { Elements } + /// + public class ArrayInitializerExpression : Expression + { + #region Null + public new static readonly ArrayInitializerExpression Null = new NullArrayInitializerExpression (); + + sealed class NullArrayInitializerExpression : ArrayInitializerExpression + { + public override bool IsNull { + get { + return true; + } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return default (S); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } + } + #endregion + + public readonly static Role InitializerRole = new Role("Initializer", ArrayInitializerExpression.Null); + + public AstNodeCollection Elements { + get { return GetChildrenByRole(Roles.Expression); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitArrayInitializerExpression (this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ArrayInitializerExpression o = other as ArrayInitializerExpression; + return o != null && this.Elements.DoMatch(o.Elements, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/AssignmentExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/AssignmentExpression.cs new file mode 100644 index 0000000000..bab517a579 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/AssignmentExpression.cs @@ -0,0 +1,44 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class AssignmentExpression : Expression + { + public readonly static Role LeftExpressionRole = BinaryOperatorExpression.LeftExpressionRole; + public readonly static Role OperatorRole = BinaryOperatorExpression.OperatorRole; + public readonly static Role RightExpressionRole = BinaryOperatorExpression.RightExpressionRole; + + public AssignmentExpression(Expression left, AssignmentOperatorType type, Expression right) + { + AddChild(left, LeftExpressionRole); + AddChild(right, RightExpressionRole); + Operator = type; + } + + public Expression Left { + get { return GetChildByRole(LeftExpressionRole); } + set { SetChildByRole(LeftExpressionRole, value); } + } + + public AssignmentOperatorType Operator { get; set; } + + public Expression Right { + get { return GetChildByRole(RightExpressionRole); } + set { SetChildByRole(RightExpressionRole, 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.VisitAssignmentExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/BinaryOperatorExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/BinaryOperatorExpression.cs new file mode 100644 index 0000000000..b83a0909fe --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/BinaryOperatorExpression.cs @@ -0,0 +1,110 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class BinaryOperatorExpression : Expression + { + public readonly static Role LeftExpressionRole = new Role("Left"); + public readonly static Role OperatorRole = new Role("Operator"); + public readonly static Role RightExpressionRole = new Role("Right"); + + public BinaryOperatorExpression(Expression left, BinaryOperatorType type, Expression right) + { + AddChild(left, LeftExpressionRole); + AddChild(right, RightExpressionRole); + Operator = type; + } + + public Expression Left { + get { return GetChildByRole(LeftExpressionRole); } + set { SetChildByRole(LeftExpressionRole, value); } + } + + public BinaryOperatorType Operator { get; set; } + + public Expression Right { + get { return GetChildByRole(RightExpressionRole); } + set { SetChildByRole(RightExpressionRole, 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.VisitBinaryOperatorExpression(this, data); + } + } + + public enum BinaryOperatorType + { + None, + + /// '&' in C#, 'And' in VB. + BitwiseAnd, + /// '|' in C#, 'Or' in VB. + BitwiseOr, + /// '&&' in C#, 'AndAlso' in VB. + LogicalAnd, + /// '||' in C#, 'OrElse' in VB. + LogicalOr, + /// '^' in C#, 'Xor' in VB. + ExclusiveOr, + + /// > + GreaterThan, + /// >= + GreaterThanOrEqual, + /// '==' in C#, '=' in VB. + Equality, + /// '!=' in C#, '<>' in VB. + InEquality, + /// < + LessThan, + /// <= + LessThanOrEqual, + + /// + + Add, + /// - + Subtract, + /// * + Multiply, + /// / + Divide, + /// '%' in C#, 'Mod' in VB. + Modulus, + /// VB-only: \ + DivideInteger, + /// VB-only: ^ + Power, + /// VB-only: & + Concat, + + /// C#: << + ShiftLeft, + /// C#: >> + ShiftRight, + /// VB-only: Is + ReferenceEquality, + /// VB-only: IsNot + ReferenceInequality, + + /// VB-only: Like + Like, + /// + /// C#: ?? + /// VB: IF(x, y) + /// + NullCoalescing, + + /// VB-only: ! + DictionaryAccess + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/CastExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/CastExpression.cs new file mode 100644 index 0000000000..5cdbd3fa63 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/CastExpression.cs @@ -0,0 +1,95 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// CastType(Expression, AstType) + /// + public class CastExpression : Expression + { + public CastType CastType { get; set; } + + public VBTokenNode CastTypeToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public AstType Type { + get { return GetChildByRole (Roles.Type); } + set { SetChildByRole (Roles.Type, value); } + } + + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public CastExpression () + { + } + + public CastExpression (CastType castType, AstType castToType, Expression expression) + { + CastType = castType; + AddChild (castToType, Roles.Type); + AddChild (expression, Roles.Expression); + } + + public CastExpression (CastType castType, Expression expression) + { + CastType = castType; + AddChild (expression, Roles.Expression); + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitCastExpression (this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + CastExpression o = other as CastExpression; + return o != null && this.CastType == o.CastType && this.Type.DoMatch(o.Type, match) && this.Expression.DoMatch(o.Expression, match); + } + } + + public enum CastType + { + DirectCast, + TryCast, + CType, + CBool, + CByte, + CChar, + CDate, + CDec, + CDbl, + CInt, + CLng, + CObj, + CSByte, + CShort, + CSng, + CStr, + CUInt, + CULng, + CUShort + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/CollectionRangeVariableDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/CollectionRangeVariableDeclaration.cs new file mode 100644 index 0000000000..711341d0cd --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/CollectionRangeVariableDeclaration.cs @@ -0,0 +1,42 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Identifier As Type In Expression + /// + public class CollectionRangeVariableDeclaration : AstNode + { + public static readonly Role CollectionRangeVariableDeclarationRole = new Role("CollectionRangeVariableDeclaration"); + + public VariableIdentifier Identifier { + get { return GetChildByRole(VariableIdentifier.VariableIdentifierRole); } + set { SetChildByRole(VariableIdentifier.VariableIdentifierRole, value); } + } + + public AstType Type { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitCollectionRangeVariableDeclaration(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + CollectionRangeVariableDeclaration o = other as CollectionRangeVariableDeclaration; + return o != null && this.Identifier.DoMatch(o.Identifier, match) && this.Type.DoMatch(o.Type, match) && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/ConditionalExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/ConditionalExpression.cs new file mode 100644 index 0000000000..4b53d56633 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/ConditionalExpression.cs @@ -0,0 +1,44 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class ConditionalExpression : Expression + { + public readonly static Role ConditionExpressionRole = new Role("ConditionExpressionRole", Expression.Null); + public readonly static Role TrueExpressionRole = new Role("TrueExpressionRole", Expression.Null); + public readonly static Role FalseExpressionRole = new Role("FalseExpressionRole", Expression.Null); + + public VBTokenNode IfToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public Expression ConditionExpression { + get { return GetChildByRole (ConditionExpressionRole); } + set { SetChildByRole (ConditionExpressionRole, value); } + } + + public Expression TrueExpression { + get { return GetChildByRole (TrueExpressionRole); } + set { SetChildByRole (TrueExpressionRole, value); } + } + + public Expression FalseExpression { + get { return GetChildByRole (FalseExpressionRole); } + set { SetChildByRole (FalseExpressionRole, 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.VisitConditionalExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/EmptyExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/EmptyExpression.cs new file mode 100644 index 0000000000..c475a2b515 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/EmptyExpression.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class EmptyExpression : Expression + { + AstLocation location; + + public override AstLocation StartLocation { + get { + return location; + } + } + + public override AstLocation EndLocation { + get { + return location; + } + } + + public EmptyExpression() + { + } + + public EmptyExpression(AstLocation location) + { + this.location = location; + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitEmptyExpression(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + var o = other as EmptyExpression; + return o != null; + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/Expression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/Expression.cs index d15756e3ee..dad5cd9332 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Expressions/Expression.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/Expression.cs @@ -1,7 +1,8 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; +using System.Collections.Generic; namespace ICSharpCode.NRefactory.VB.Ast { @@ -29,5 +30,78 @@ namespace ICSharpCode.NRefactory.VB.Ast } } #endregion + + #region Builder methods + /// + /// Builds an member reference expression using this expression as target. + /// + public MemberAccessExpression Member(string memberName) + { + return new MemberAccessExpression { Target = this, MemberName = memberName }; + } + + /// + /// Builds an invocation expression using this expression as target. + /// + public InvocationExpression Invoke(string methodName, IEnumerable arguments) + { + return Invoke(methodName, null, arguments); + } + + /// + /// Builds an invocation expression using this expression as target. + /// + public InvocationExpression Invoke(string methodName, params Expression[] arguments) + { + return Invoke(methodName, null, arguments); + } + + /// + /// Builds an invocation expression using this expression as target. + /// + public InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberAccessExpression mre = new MemberAccessExpression(); + mre.Target = this; + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + /// + /// Builds an invocation expression using this expression as target. + /// + public InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = this; + ie.Arguments.AddRange(arguments); + return ie; + } + + /// + /// Builds an invocation expression using this expression as target. + /// + public InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = this; + ie.Arguments.AddRange(arguments); + return ie; + } + + public CastExpression CastTo(AstType type) + { + return new CastExpression { CastType = CastType.CType, Type = type, Expression = this }; + } + + public CastExpression CastTo(Type type) + { + return new CastExpression { CastType = CastType.CType, Type = AstType.Create(type), Expression = this }; + } + #endregion } } diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/FieldInitializerExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/FieldInitializerExpression.cs new file mode 100644 index 0000000000..bc77666c8a --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/FieldInitializerExpression.cs @@ -0,0 +1,49 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// [ Key ] .Identifier = Expression + /// + public class FieldInitializerExpression : Expression + { + public bool IsKey { get; set; } + + public VBTokenNode KeyToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public VBTokenNode DotToken { + get { return GetChildByRole (Roles.Dot); } + } + + public Identifier Identifier { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public VBTokenNode AssignToken { + get { return GetChildByRole (Roles.Assign); } + } + + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitFieldInitializerExpression(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + FieldInitializerExpression o = other as FieldInitializerExpression; + return o != null && this.IsKey == o.IsKey && this.Identifier.DoMatch(o.Identifier, match) && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/GetTypeExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/GetTypeExpression.cs new file mode 100644 index 0000000000..573d1cf8b3 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/GetTypeExpression.cs @@ -0,0 +1,31 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class GetTypeExpression : Expression + { + public GetTypeExpression() + { + } + + public AstType Type { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + var expr = other as GetTypeExpression; + return expr != null && + Type.DoMatch(expr.Type, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitGetTypeExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/GetXmlNamespaceExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/GetXmlNamespaceExpression.cs new file mode 100644 index 0000000000..390281d3f6 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/GetXmlNamespaceExpression.cs @@ -0,0 +1,32 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class GetXmlNamespaceExpression : Expression + { + public GetXmlNamespaceExpression(XmlIdentifier namespaceName) + { + SetChildByRole(Roles.XmlIdentifier, namespaceName); + } + + public XmlIdentifier NamespaceName { + get { return GetChildByRole(Roles.XmlIdentifier); } + set { SetChildByRole(Roles.XmlIdentifier, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + var expr = other as GetXmlNamespaceExpression; + return expr != null && + NamespaceName.DoMatch(expr.NamespaceName, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitGetXmlNamespaceExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/IdentifierExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/IdentifierExpression.cs new file mode 100644 index 0000000000..6bd77cb9bd --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/IdentifierExpression.cs @@ -0,0 +1,39 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class IdentifierExpression : Expression + { + public IdentifierExpression() + { + + } + + public IdentifierExpression(Identifier identifier) + { + this.Identifier = identifier; + } + + public Identifier Identifier { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public AstNodeCollection TypeArguments { + get { return GetChildrenByRole(Roles.TypeArgument); } + } + + 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.VisitIdentifierExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/InstanceExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/InstanceExpression.cs new file mode 100644 index 0000000000..d51972cb1d --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/InstanceExpression.cs @@ -0,0 +1,61 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Description of InstanceExpression. + /// + public class InstanceExpression : Expression + { + AstLocation location; + + public InstanceExpression(InstanceExpressionType type, AstLocation location) + { + this.Type = type; + this.location = location; + } + + public override AstLocation StartLocation { + get { return location; } + } + + public override AstLocation EndLocation { + get { + switch (Type) { + case InstanceExpressionType.Me: + return new AstLocation(location.Line, location.Column + "Me".Length); + case InstanceExpressionType.MyBase: + return new AstLocation(location.Line, location.Column + "MyBase".Length); + case InstanceExpressionType.MyClass: + return new AstLocation(location.Line, location.Column + "MyClass".Length); + default: + throw new Exception("Invalid value for InstanceExpressionType"); + } + } + } + + public InstanceExpressionType Type { get; set; } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + var expr = other as InstanceExpression; + return expr != null && + Type == expr.Type; + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitInstanceExpression(this, data); + } + } + + public enum InstanceExpressionType + { + Me, + MyBase, + MyClass + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/InvocationExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/InvocationExpression.cs new file mode 100644 index 0000000000..6a81c0376d --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/InvocationExpression.cs @@ -0,0 +1,52 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Target(Arguments) + /// + public class InvocationExpression : Expression + { + public Expression Target { + get { return GetChildByRole (Roles.TargetExpression); } + set { SetChildByRole(Roles.TargetExpression, value); } + } + + public AstNodeCollection Arguments { + get { return GetChildrenByRole(Roles.Argument); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitInvocationExpression(this, data); + } + + public InvocationExpression () + { + } + + public InvocationExpression (Expression target, IEnumerable arguments) + { + AddChild (target, Roles.TargetExpression); + if (arguments != null) { + foreach (var arg in arguments) { + AddChild (arg, Roles.Argument); + } + } + } + + public InvocationExpression (Expression target, params Expression[] arguments) : this (target, (IEnumerable)arguments) + { + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + InvocationExpression o = other as InvocationExpression; + return o != null && this.Target.DoMatch(o.Target, match) && this.Arguments.DoMatch(o.Arguments, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/LambdaExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/LambdaExpression.cs new file mode 100644 index 0000000000..75863cbfc3 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/LambdaExpression.cs @@ -0,0 +1,124 @@ +// 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.Collections.Generic; +using System.Linq; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public abstract class LambdaExpression : Expression + { + public static readonly Role ModifierRole = AttributedNode.ModifierRole; + + public LambdaExpressionModifiers Modifiers { + get { return GetModifiers(this); } + set { SetModifiers(this, value); } + } + + public AstNodeCollection ModifierTokens { + get { return GetChildrenByRole (ModifierRole); } + } + + internal static LambdaExpressionModifiers GetModifiers(AstNode node) + { + LambdaExpressionModifiers m = 0; + foreach (VBModifierToken t in node.GetChildrenByRole (ModifierRole)) { + m |= (LambdaExpressionModifiers)t.Modifier; + } + return m; + } + + internal static void SetModifiers(AstNode node, LambdaExpressionModifiers newValue) + { + LambdaExpressionModifiers oldValue = GetModifiers(node); + AstNode insertionPos = null; + foreach (Modifiers m in VBModifierToken.AllModifiers) { + if ((m & (Modifiers)newValue) != 0) { + if ((m & (Modifiers)oldValue) == 0) { + // Modifier was added + var newToken = new VBModifierToken(AstLocation.Empty, m); + node.InsertChildAfter(insertionPos, newToken, ModifierRole); + insertionPos = newToken; + } else { + // Modifier already exists + insertionPos = node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m); + } + } else { + if ((m & (Modifiers)oldValue) != 0) { + // Modifier was removed + node.GetChildrenByRole (ModifierRole).First(t => t.Modifier == m).Remove(); + } + } + } + } + + public AstNodeCollection Parameters { + get { return GetChildrenByRole(Roles.Parameter); } + } + } + + public class SingleLineSubLambdaExpression : LambdaExpression + { + public static readonly Role StatementRole = BlockStatement.StatementRole; + + public Statement EmbeddedStatement { + get { return GetChildByRole(StatementRole); } + set { SetChildByRole(StatementRole, 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.VisitSingleLineSubLambdaExpression(this, data); + } + } + + public class SingleLineFunctionLambdaExpression : LambdaExpression + { + public Expression EmbeddedExpression { + 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.VisitSingleLineFunctionLambdaExpression(this, data); + } + } + + public class MultiLineLambdaExpression : LambdaExpression + { + public bool IsSub { get; set; } + + 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.VisitMultiLineLambdaExpression(this, data); + } + } + + public enum LambdaExpressionModifiers + { + Async = Modifiers.Async, + Iterator = Modifiers.Iterator + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/MemberAccessExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/MemberAccessExpression.cs new file mode 100644 index 0000000000..17e8057750 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/MemberAccessExpression.cs @@ -0,0 +1,42 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class MemberAccessExpression : Expression + { + public MemberAccessExpression() + { + } + + public Expression Target { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public Identifier MemberName { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public AstNodeCollection TypeArguments { + get { return GetChildrenByRole(Roles.TypeArgument); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + var expr = other as MemberAccessExpression; + return expr != null && + Target.DoMatch(expr.Target, match) && + MemberName.DoMatch(expr.MemberName, match) && + TypeArguments.DoMatch(expr.TypeArguments, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitMemberAccessExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/NamedArgumentExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/NamedArgumentExpression.cs new file mode 100644 index 0000000000..730eaafafd --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/NamedArgumentExpression.cs @@ -0,0 +1,39 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Represents a named argument passed to a method or attribute. + /// + public class NamedArgumentExpression : Expression + { + public Identifier Identifier { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public VBTokenNode AssignToken { + get { return GetChildByRole (Roles.Assign); } + } + + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitNamedArgumentExpression(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + NamedArgumentExpression o = other as NamedArgumentExpression; + return o != null && this.Identifier.DoMatch(o.Identifier, match) && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/ObjectCreationExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/ObjectCreationExpression.cs new file mode 100644 index 0000000000..6e28b292d8 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/ObjectCreationExpression.cs @@ -0,0 +1,59 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// New Type(Arguments) { Initializer } + /// + public class ObjectCreationExpression : Expression + { + public readonly static Role InitializerRole = ArrayInitializerExpression.InitializerRole; + + public AstType Type { + get { return GetChildByRole (Roles.Type); } + set { SetChildByRole (Roles.Type, value); } + } + + public AstNodeCollection Arguments { + get { return GetChildrenByRole (Roles.Argument); } + } + + public ArrayInitializerExpression Initializer { + get { return GetChildByRole (InitializerRole); } + set { SetChildByRole (InitializerRole, value); } + } + + public ObjectCreationExpression() + { + } + + public ObjectCreationExpression (AstType type, IEnumerable arguments = null) + { + AddChild (type, Roles.Type); + if (arguments != null) { + foreach (var arg in arguments) { + AddChild (arg, Roles.Argument); + } + } + } + + public ObjectCreationExpression (AstType type, params Expression[] arguments) : this (type, (IEnumerable)arguments) + { + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitObjectCreationExpression(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ObjectCreationExpression o = other as ObjectCreationExpression; + return o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match) && this.Initializer.DoMatch(o.Initializer, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/ParenthesizedExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/ParenthesizedExpression.cs new file mode 100644 index 0000000000..31c234044c --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/ParenthesizedExpression.cs @@ -0,0 +1,34 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Description of ParenthesizedExpression. + /// + public class ParenthesizedExpression : Expression + { + public ParenthesizedExpression() + { + } + + 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) + { + var expr = other as ParenthesizedExpression; + return expr != null && + Expression.DoMatch(expr.Expression, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitParenthesizedExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/PrimitiveExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/PrimitiveExpression.cs index c01adaf8ad..39eeabc07b 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Expressions/PrimitiveExpression.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/PrimitiveExpression.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using ICSharpCode.NRefactory.VB.PrettyPrinter; using System; @@ -32,7 +32,7 @@ namespace ICSharpCode.NRefactory.VB.Ast string stringValue; public string StringValue { - get { return stringValue; } // TODO ?? VBNetOutputVisitor.ToVBNetString(this); } + get { return stringValue ?? OutputVisitor.ToVBNetString(this); } } public PrimitiveExpression(object value) diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/QueryExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/QueryExpression.cs new file mode 100644 index 0000000000..2701d4e892 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/QueryExpression.cs @@ -0,0 +1,348 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class QueryExpression : Expression + { + public AstNodeCollection QueryOperators { + get { return GetChildrenByRole(QueryOperator.QueryOperatorRole); } + } + + 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.VisitQueryExpression(this, data); + } + } + + public abstract class QueryOperator : AstNode + { + #region Null + public new static readonly QueryOperator Null = new NullQueryOperator(); + + sealed class NullQueryOperator : QueryOperator + { + public override bool IsNull { + get { + return true; + } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return default (S); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } + } + #endregion + + public static readonly Role QueryOperatorRole = new Role("QueryOperator", QueryOperator.Null); + } + + public class FromQueryOperator : QueryOperator + { + public AstNodeCollection Variables { + get { return GetChildrenByRole (CollectionRangeVariableDeclaration.CollectionRangeVariableDeclarationRole); } + } + + 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.VisitFromQueryOperator(this, data); + } + } + + public class AggregateQueryOperator : QueryOperator + { + public CollectionRangeVariableDeclaration Variable { + get { return GetChildByRole(CollectionRangeVariableDeclaration.CollectionRangeVariableDeclarationRole); } + set { SetChildByRole(CollectionRangeVariableDeclaration.CollectionRangeVariableDeclarationRole, value); } + } + + public AstNodeCollection SubQueryOperators { + get { return GetChildrenByRole(QueryOperatorRole); } + } + + public AstNodeCollection IntoExpressions { + get { return GetChildrenByRole(VariableInitializer.VariableInitializerRole); } + } + + 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.VisitAggregateQueryOperator(this, data); + } + } + + public class SelectQueryOperator : QueryOperator + { + public AstNodeCollection Variables { + get { return GetChildrenByRole(VariableInitializer.VariableInitializerRole); } + } + + 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.VisitSelectQueryOperator(this, data); + } + } + + public class DistinctQueryOperator : QueryOperator + { + 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.VisitDistinctQueryOperator(this, data); + } + } + + public class WhereQueryOperator : QueryOperator + { + public Expression Condition { + 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.VisitWhereQueryOperator(this, data); + } + } + + public class OrderExpression : AstNode + { + public static readonly Role OrderExpressionRole = new Role("OrderExpression"); + + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public QueryOrderingDirection Direction { get; set; } + + 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.VisitOrderExpression(this, data); + } + } + + public class OrderByQueryOperator : QueryOperator + { + public AstNodeCollection Expressions { + get { return GetChildrenByRole(OrderExpression.OrderExpressionRole); } + } + + 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.VisitOrderByQueryOperator(this, data); + } + } + + public class PartitionQueryOperator : QueryOperator + { + public PartitionKind Kind { get; set; } + + 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.VisitPartitionQueryOperator(this, data); + } + } + + public class LetQueryOperator : QueryOperator + { + public AstNodeCollection Variables { + get { return GetChildrenByRole(VariableInitializer.VariableInitializerRole); } + } + + 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.VisitLetQueryOperator(this, data); + } + } + + public class GroupByQueryOperator : QueryOperator + { + public static readonly Role GroupExpressionRole = new Role("GroupExpression"); + public static readonly Role ByExpressionRole = new Role("ByExpression"); + public static readonly Role IntoExpressionRole = new Role("IntoExpression"); + + public AstNodeCollection GroupExpressions { + get { return GetChildrenByRole(GroupExpressionRole); } + } + + public AstNodeCollection ByExpressions { + get { return GetChildrenByRole(ByExpressionRole); } + } + + public AstNodeCollection IntoExpressions { + get { return GetChildrenByRole(IntoExpressionRole); } + } + + 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.VisitGroupByQueryOperator(this, data); + } + } + + public class JoinQueryOperator : QueryOperator + { + #region Null + public new static readonly JoinQueryOperator Null = new NullJoinQueryOperator(); + + sealed class NullJoinQueryOperator : JoinQueryOperator + { + public override bool IsNull { + get { + return true; + } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return default (S); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } + } + #endregion + + public static readonly Role JoinQueryOperatorRole = new Role("JoinQueryOperator", JoinQueryOperator.Null); + + public CollectionRangeVariableDeclaration JoinVariable { + get { return GetChildByRole(CollectionRangeVariableDeclaration.CollectionRangeVariableDeclarationRole); } + set { SetChildByRole(CollectionRangeVariableDeclaration.CollectionRangeVariableDeclarationRole, value); } + } + + public JoinQueryOperator SubJoinQuery { + get { return GetChildByRole(JoinQueryOperatorRole); } + set { SetChildByRole(JoinQueryOperatorRole, value); } + } + + public AstNodeCollection JoinConditions { + get { return GetChildrenByRole(JoinCondition.JoinConditionRole); } + } + + 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.VisitJoinQueryOperator(this, data); + } + } + + public class JoinCondition : AstNode + { + public static readonly Role JoinConditionRole = new Role("JoinCondition"); + + public static readonly Role LeftExpressionRole = BinaryOperatorExpression.LeftExpressionRole; + public static readonly Role RightExpressionRole = BinaryOperatorExpression.RightExpressionRole; + + public Expression Left { + get { return GetChildByRole (LeftExpressionRole); } + set { SetChildByRole (LeftExpressionRole, value); } + } + + public Expression Right { + get { return GetChildByRole (RightExpressionRole); } + set { SetChildByRole (RightExpressionRole, 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.VisitJoinCondition(this, data); + } + } + + public class GroupJoinQueryOperator : JoinQueryOperator + { + public static readonly Role IntoExpressionRole = GroupByQueryOperator.IntoExpressionRole; + + public AstNodeCollection IntoExpressions { + get { return GetChildrenByRole(IntoExpressionRole); } + } + + 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.VisitGroupJoinQueryOperator(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/SimpleNameExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/SimpleNameExpression.cs index 257b8e744a..0face5c9e9 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Expressions/SimpleNameExpression.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/SimpleNameExpression.cs @@ -1,22 +1,27 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; namespace ICSharpCode.NRefactory.VB.Ast { /// - /// Description of IdentifierExpression. + /// Description of SimpleNameExpression. /// public class SimpleNameExpression : Expression { public Identifier Identifier { get; set; } + public AstNodeCollection TypeArguments { + get { return GetChildrenByRole(Roles.TypeArgument); } + } + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) { var node = other as SimpleNameExpression; return node != null - && Identifier.DoMatch(node.Identifier, match); + && Identifier.DoMatch(node.Identifier, match) + && TypeArguments.DoMatch(node.TypeArguments, match); } public override S AcceptVisitor(IAstVisitor visitor, T data) diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/TypeOfIsExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/TypeOfIsExpression.cs new file mode 100644 index 0000000000..54ef20f94f --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/TypeOfIsExpression.cs @@ -0,0 +1,37 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class TypeOfIsExpression : Expression + { + public TypeOfIsExpression() + { + } + + public Expression TypeOfExpression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public AstType Type { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + var expr = other as TypeOfIsExpression; + return expr != null && + TypeOfExpression.DoMatch(expr.TypeOfExpression, match) && + Type.DoMatch(expr.Type, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitTypeOfIsExpression(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/TypeReferenceExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/TypeReferenceExpression.cs new file mode 100644 index 0000000000..d163fcd77b --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/TypeReferenceExpression.cs @@ -0,0 +1,39 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Represents an AstType as an expression. + /// This is used when calling a method on a primitive type: "Integer.Parse()" + /// + public class TypeReferenceExpression : Expression + { + public AstType Type { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitTypeReferenceExpression(this, data); + } + + public TypeReferenceExpression () + { + } + + public TypeReferenceExpression (AstType type) + { + SetChildByRole(Roles.Type, type); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + TypeReferenceExpression o = other as TypeReferenceExpression; + return o != null && this.Type.DoMatch(o.Type, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/UnaryOperatorExpression.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/UnaryOperatorExpression.cs new file mode 100644 index 0000000000..7876984849 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/UnaryOperatorExpression.cs @@ -0,0 +1,80 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Operator Expression + /// + public class UnaryOperatorExpression : Expression + { + public readonly static Role OperatorRole = BinaryOperatorExpression.OperatorRole; + + public UnaryOperatorExpression() + { + } + + public UnaryOperatorExpression(UnaryOperatorType op, Expression expression) + { + this.Operator = op; + this.Expression = expression; + } + + public UnaryOperatorType Operator { + get; + set; + } + + public VBTokenNode OperatorToken { + get { return GetChildByRole (OperatorRole); } + } + + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitUnaryOperatorExpression(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + UnaryOperatorExpression o = other as UnaryOperatorExpression; + return o != null && this.Operator == o.Operator && this.Expression.DoMatch(o.Expression, match); + } + + public static string GetOperatorSymbol(UnaryOperatorType op) + { + switch (op) { + case UnaryOperatorType.Not: + return "Not"; + case UnaryOperatorType.Minus: + return "-"; + case UnaryOperatorType.Plus: + return "+"; + default: + throw new NotSupportedException("Invalid value for UnaryOperatorType"); + } + } + } + + public enum UnaryOperatorType + { + /// Logical/Bitwise not (Not a) + Not, + /// Unary minus (-a) + Minus, + /// Unary plus (+a) + Plus, + /// AddressOf + AddressOf, + /// Await + Await + } + +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/VariableInitializer.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/VariableInitializer.cs new file mode 100644 index 0000000000..7d1cb87e70 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/VariableInitializer.cs @@ -0,0 +1,46 @@ +// 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.Collections.Generic; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Identifier As Type = Expression + /// + public class VariableInitializer : AstNode + { + public static readonly Role VariableInitializerRole = new Role("VariableInitializer"); + + public VariableIdentifier Identifier { + get { return GetChildByRole(VariableIdentifier.VariableIdentifierRole); } + set { SetChildByRole(VariableIdentifier.VariableIdentifierRole, value); } + } + + public AstType Type { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + public VBTokenNode AssignToken { + get { return GetChildByRole (Roles.Assign); } + } + + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitVariableInitializer(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + VariableInitializer o = other as VariableInitializer; + return o != null && this.Identifier.DoMatch(o.Identifier, match) && this.Type.DoMatch(o.Type, match) && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlIdentifier.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlIdentifier.cs index 7d3a6ca0b9..97860526fb 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlIdentifier.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlIdentifier.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlLiteralString.cs b/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlLiteralString.cs index 3195bcd69a..90845e0fb7 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlLiteralString.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlLiteralString.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Ast/General/Attribute.cs b/ICSharpCode.NRefactory.VB/Ast/General/Attribute.cs index 22261575ef..3ad4686092 100644 --- a/ICSharpCode.NRefactory.VB/Ast/General/Attribute.cs +++ b/ICSharpCode.NRefactory.VB/Ast/General/Attribute.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; @@ -42,7 +42,9 @@ namespace ICSharpCode.NRefactory.VB.Ast public static readonly Role AttributeRole = new Role("Attribute"); public static readonly Role TargetRole = new Role("Target", VBTokenNode.Null); - public VBTokenNode Target { + public AttributeTarget Target { get; set; } + + public VBTokenNode TargetKeyword { get { return GetChildByRole(TargetRole); } set { SetChildByRole(TargetRole, value); } } @@ -81,12 +83,13 @@ namespace ICSharpCode.NRefactory.VB.Ast protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) { var node = other as Attribute; - return node != null && node.Target.DoMatch(this.Target, match) && node.Type.DoMatch(this.Type, match) && node.Arguments.DoMatch(this.Arguments, match); + return node != null && node.Target == Target && node.TargetKeyword.DoMatch(this.TargetKeyword, match) && node.Type.DoMatch(this.Type, match) && node.Arguments.DoMatch(this.Arguments, match); } } public enum AttributeTarget { + None, Assembly, Module } diff --git a/ICSharpCode.NRefactory.VB/Ast/General/AttributeBlock.cs b/ICSharpCode.NRefactory.VB/Ast/General/AttributeBlock.cs index 2e06d39172..57d69db33d 100644 --- a/ICSharpCode.NRefactory.VB/Ast/General/AttributeBlock.cs +++ b/ICSharpCode.NRefactory.VB/Ast/General/AttributeBlock.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Ast/General/AttributedNode.cs b/ICSharpCode.NRefactory.VB/Ast/General/AttributedNode.cs index 37e364ee6b..f7330195f9 100644 --- a/ICSharpCode.NRefactory.VB/Ast/General/AttributedNode.cs +++ b/ICSharpCode.NRefactory.VB/Ast/General/AttributedNode.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; @@ -20,7 +20,7 @@ namespace ICSharpCode.NRefactory.VB.Ast set { SetModifiers(this, value); } } - public IEnumerable ModifierTokens { + public AstNodeCollection ModifierTokens { get { return GetChildrenByRole (ModifierRole); } } diff --git a/ICSharpCode.NRefactory.VB/Ast/General/CompilationUnit.cs b/ICSharpCode.NRefactory.VB/Ast/General/CompilationUnit.cs index 6dbe784277..fcc2f2b1bb 100644 --- a/ICSharpCode.NRefactory.VB/Ast/General/CompilationUnit.cs +++ b/ICSharpCode.NRefactory.VB/Ast/General/CompilationUnit.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Ast/General/EventMemberSpecifier.cs b/ICSharpCode.NRefactory.VB/Ast/General/EventMemberSpecifier.cs new file mode 100644 index 0000000000..da1e14cf4f --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/General/EventMemberSpecifier.cs @@ -0,0 +1,39 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class EventMemberSpecifier : AstNode + { + public static readonly Role EventMemberSpecifierRole = new Role("EventMemberSpecifier"); + + public EventMemberSpecifier() + { + } + + public Expression Target { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public Identifier Member { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + var expr = other as EventMemberSpecifier; + return expr != null && + Target.DoMatch(expr.Target, match) && + Member.DoMatch(expr.Member, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitEventMemberSpecifier(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/General/InterfaceMemberSpecifier.cs b/ICSharpCode.NRefactory.VB/Ast/General/InterfaceMemberSpecifier.cs new file mode 100644 index 0000000000..84cc23da6b --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/General/InterfaceMemberSpecifier.cs @@ -0,0 +1,47 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class InterfaceMemberSpecifier : AstNode + { + public static readonly Role InterfaceMemberSpecifierRole = new Role("InterfaceMemberSpecifier"); + + public InterfaceMemberSpecifier(Expression target, Identifier member) + { + Target = target; + Member = member; + } + + public InterfaceMemberSpecifier(AstType target, string member) + { + Target = new TypeReferenceExpression(target); + Member = new Identifier(member, AstLocation.Empty); + } + + public Expression Target { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public Identifier Member { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + var expr = other as InterfaceMemberSpecifier; + return expr != null && + Target.DoMatch(expr.Target, match) && + Member.DoMatch(expr.Member, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitInterfaceMemberSpecifier(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/General/ParameterDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/General/ParameterDeclaration.cs index 87b4162b4f..61b4f2ae37 100644 --- a/ICSharpCode.NRefactory.VB/Ast/General/ParameterDeclaration.cs +++ b/ICSharpCode.NRefactory.VB/Ast/General/ParameterDeclaration.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; @@ -17,7 +17,7 @@ namespace ICSharpCode.NRefactory.VB.Ast set { SetChildByRole(Roles.Expression, value); } } - public AstType ReturnType { + public AstType Type { get { return GetChildByRole(Roles.Type); } set { SetChildByRole(Roles.Type, value); } } @@ -29,7 +29,7 @@ namespace ICSharpCode.NRefactory.VB.Ast MatchAttributesAndModifiers(param, match) && Name.DoMatch(param.Name, match) && OptionalValue.DoMatch(param.OptionalValue, match) && - ReturnType.DoMatch(param.ReturnType, match); + Type.DoMatch(param.Type, match); } public override S AcceptVisitor(IAstVisitor visitor, T data) diff --git a/ICSharpCode.NRefactory.VB/Ast/General/TypeParameterDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/General/TypeParameterDeclaration.cs index 90be4263a7..cfce070566 100644 --- a/ICSharpCode.NRefactory.VB/Ast/General/TypeParameterDeclaration.cs +++ b/ICSharpCode.NRefactory.VB/Ast/General/TypeParameterDeclaration.cs @@ -1,10 +1,12 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; using System.Linq; +using ICSharpCode.NRefactory.TypeSystem; + namespace ICSharpCode.NRefactory.VB.Ast { /// diff --git a/ICSharpCode.NRefactory.VB/Ast/Generated.cs b/ICSharpCode.NRefactory.VB/Ast/Generated.cs index bd973a0d79..dee6e4d96f 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Generated.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Generated.cs @@ -1,5 +1,5 @@ //// 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) +//// This code is distributed under MIT X11 license (for details please see \doc\license.txt) //using System; //using System.Collections.Generic; // diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/DelegateDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/DelegateDeclaration.cs index bc2d06ca03..8a88c91350 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/DelegateDeclaration.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/DelegateDeclaration.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumDeclaration.cs index 49fe3f239c..736d579ffb 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumDeclaration.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumDeclaration.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; @@ -22,7 +22,7 @@ namespace ICSharpCode.NRefactory.VB.Ast set { SetChildByRole(UnderlyingTypeRole, value); } } - public AstNodeCollection Member { + public AstNodeCollection Members { get { return GetChildrenByRole(MemberRole); } } @@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.VB.Ast MatchAttributesAndModifiers(decl, match) && Name.DoMatch(decl.Name, match) && UnderlyingType.DoMatch(decl.UnderlyingType, match) && - Member.DoMatch(decl.Member, match); + Members.DoMatch(decl.Members, match); } public override S AcceptVisitor(IAstVisitor visitor, T data) diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumMemberDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumMemberDeclaration.cs index 476ec56360..72e757c607 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumMemberDeclaration.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumMemberDeclaration.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsClause.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsClause.cs index 15730eab03..a9d7f45bf0 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsClause.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsClause.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; @@ -73,7 +73,7 @@ namespace ICSharpCode.NRefactory.VB.Ast public override S AcceptVisitor(IAstVisitor visitor, T data) { - return visitor.VisitMembersImportsClause(this, data); + return visitor.VisitMemberImportsClause(this, data); } public override string ToString() diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsStatement.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsStatement.cs index 6691b852ba..24ea944d62 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsStatement.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsStatement.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; using ICSharpCode.NRefactory.PatternMatching; diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/NamespaceDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/NamespaceDeclaration.cs index 5c392a73af..5859cc40a9 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/NamespaceDeclaration.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/NamespaceDeclaration.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/OptionStatement.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/OptionStatement.cs index 903439c89a..299cc5b01e 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/OptionStatement.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/OptionStatement.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; using ICSharpCode.NRefactory.PatternMatching; diff --git a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs index eadd4f031f..1780cb59d7 100644 --- a/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs +++ b/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; @@ -20,11 +20,9 @@ namespace ICSharpCode.NRefactory.VB.Ast public ClassType ClassType { get; set; } - public string Name { - get { return GetChildByRole(Roles.Identifier).Name; } - set { - SetChildByRole(Roles.Identifier, new Identifier (value, AstLocation.Empty)); - } + public Identifier Name { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } } public AstNodeCollection TypeParameters { @@ -33,6 +31,7 @@ namespace ICSharpCode.NRefactory.VB.Ast public AstType InheritsType { get { return GetChildByRole(InheritsTypeRole); } + set { SetChildByRole(InheritsTypeRole, value); } } public AstNodeCollection ImplementsTypes { @@ -46,7 +45,7 @@ namespace ICSharpCode.NRefactory.VB.Ast MatchAttributesAndModifiers(t, match) && Members.DoMatch(t.Members, match) && ClassType == t.ClassType && - MatchString(Name, t.Name) && + Name.DoMatch(t.Name, match) && TypeParameters.DoMatch(t.TypeParameters, match) && InheritsType.DoMatch(t.InheritsType, match) && ImplementsTypes.DoMatch(t.ImplementsTypes, match); diff --git a/ICSharpCode.NRefactory.VB/Ast/INullable.cs b/ICSharpCode.NRefactory.VB/Ast/INullable.cs index 14a65a444e..1ce646f6bb 100644 --- a/ICSharpCode.NRefactory.VB/Ast/INullable.cs +++ b/ICSharpCode.NRefactory.VB/Ast/INullable.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) namespace ICSharpCode.NRefactory.VB.Ast { diff --git a/ICSharpCode.NRefactory.VB/Ast/Identifier.cs b/ICSharpCode.NRefactory.VB/Ast/Identifier.cs index ea308b7f9f..0ffa568c96 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Identifier.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Identifier.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; @@ -69,6 +69,11 @@ namespace ICSharpCode.NRefactory.VB.Ast this.startLocation = location; } + public static implicit operator Identifier(string name) + { + return new Identifier(name, AstLocation.Empty); + } + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) { var node = other as Identifier; @@ -84,8 +89,8 @@ namespace ICSharpCode.NRefactory.VB.Ast public override string ToString() { - return string.Format("[Identifier Name={0}, StartLocation={1}, TypeCharacter{4}]", - name, startLocation, TypeCharacter); + return string.Format("{0}", + name); } } } diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/BlockStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/BlockStatement.cs index 73610fe707..1cce01649d 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Statements/BlockStatement.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/BlockStatement.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; @@ -79,7 +79,7 @@ namespace ICSharpCode.NRefactory.VB.Ast protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { BlockStatement o = other as BlockStatement; - return o != null && !o.IsNull && this.Statements.DoMatch(o.Statements, match); + return o != null && !(o is CatchBlock) && !o.IsNull && this.Statements.DoMatch(o.Statements, match); } #region Builder methods @@ -88,28 +88,26 @@ namespace ICSharpCode.NRefactory.VB.Ast AddChild(statement, StatementRole); } - // TODO : uncomment + public void Add(Expression expression) + { + AddChild(new ExpressionStatement { Expression = expression }, StatementRole); + } -// public void Add(Expression expression) -// { -// AddChild(new ExpressionStatement { Expression = expression }, StatementRole); -// } -// public void AddRange(IEnumerable statements) { foreach (Statement st in statements) AddChild(st, StatementRole); } -// public void AddAssignment(Expression left, Expression right) -// { -// Add(new AssignmentExpression { Left = left, Operator = AssignmentOperatorType.Assign, Right = right }); -// } -// -// public void AddReturnStatement(Expression expression) -// { -// Add(new ReturnStatement { Expression = expression }); -// } + public void AddAssignment(Expression left, Expression right) + { + Add(new AssignmentExpression(left, AssignmentOperatorType.Assign, right)); + } + + public void AddReturnStatement(Expression expression) + { + Add(new ReturnStatement { Expression = expression }); + } #endregion IEnumerator IEnumerable.GetEnumerator() diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ContinueStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ContinueStatement.cs new file mode 100644 index 0000000000..4ec41f6284 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ContinueStatement.cs @@ -0,0 +1,50 @@ +// 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 +{ + /// + /// Continue ( Do | For | While ) + /// + public class ContinueStatement : Statement + { + public static readonly Role ContinueKindTokenRole = new Role("ContinueKindToken"); + + public ContinueKind ContinueKind { get; set; } + + public VBTokenNode ContinueToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public VBTokenNode ContinueKindToken { + get { return GetChildByRole (ContinueKindTokenRole); } + } + + public ContinueStatement(ContinueKind kind) + { + this.ContinueKind = kind; + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitContinueStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ContinueStatement o = other as ContinueStatement; + return o != null && this.ContinueKind == o.ContinueKind; + } + } + + public enum ContinueKind + { + None, + Do, + For, + While + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/DoLoopStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/DoLoopStatement.cs new file mode 100644 index 0000000000..9335926f89 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/DoLoopStatement.cs @@ -0,0 +1,33 @@ +// 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 + { + public ConditionType ConditionType { get; set; } + + public Expression Expression { + 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.VisitDoLoopStatement(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ExitStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ExitStatement.cs new file mode 100644 index 0000000000..b5f7c0ff3c --- /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("ExitKindToken"); + + 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/ExpressionStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ExpressionStatement.cs new file mode 100644 index 0000000000..67e8952d65 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ExpressionStatement.cs @@ -0,0 +1,40 @@ +// 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 +{ + /// + /// Expression + /// + // TODO this does not directly reflect the VB grammar! + public class ExpressionStatement : Statement + { + public Expression Expression { + get { return GetChildByRole (Roles.Expression); } + set { SetChildByRole (Roles.Expression, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitExpressionStatement(this, data); + } + + public ExpressionStatement() + { + } + + public ExpressionStatement(Expression expression) + { + this.Expression = expression; + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ExpressionStatement o = other as ExpressionStatement; + return o != null && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ForEachStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ForEachStatement.cs new file mode 100644 index 0000000000..7c0cd90b14 --- /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 VariableRole = new Role("Variable", AstNode.Null); + + public AstNode Variable { + get { return GetChildByRole(VariableRole); } + set { SetChildByRole(VariableRole, 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..c28ea0fd56 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ForStatement.cs @@ -0,0 +1,45 @@ +// 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 + { + public static readonly Role VariableRole = new Role("Variable", AstNode.Null); + public static readonly Role ToExpressionRole = new Role("ToExpression", Expression.Null); + public static readonly Role StepExpressionRole = new Role("StepExpression", Expression.Null); + + public AstNode Variable { + get { return GetChildByRole(VariableRole); } + set { SetChildByRole(VariableRole, value); } + } + + public Expression ToExpression { + get { return GetChildByRole(ToExpressionRole); } + set { SetChildByRole(ToExpressionRole, value); } + } + + public Expression StepExpression { + get { return GetChildByRole(StepExpressionRole); } + set { SetChildByRole(StepExpressionRole, 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.VisitForStatement(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/GoToStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/GoToStatement.cs new file mode 100644 index 0000000000..32dc7d7456 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/GoToStatement.cs @@ -0,0 +1,27 @@ +// 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 GoToStatement : Statement + { + /// either PrimitiveExpression or IdentifierExpression + public Expression Label { + 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.VisitGoToStatement(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/IfElseStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/IfElseStatement.cs new file mode 100644 index 0000000000..08738789aa --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/IfElseStatement.cs @@ -0,0 +1,39 @@ +// 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 IfElseStatement : Statement + { + public static readonly Role FalseStatementRole = new Role("False", Ast.Statement.Null); + public static readonly Role TrueStatementRole = new Role("True", Ast.Statement.Null); + + public Expression Condition { + get { return GetChildByRole(Roles.Condition); } + set { SetChildByRole(Roles.Condition, value); } + } + + public Statement Body { + get { return GetChildByRole(TrueStatementRole); } + set { SetChildByRole(TrueStatementRole, value); } + } + + public Statement ElseBlock { + get { return GetChildByRole(FalseStatementRole); } + set { SetChildByRole(FalseStatementRole, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitIfElseStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/LabelDeclarationStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/LabelDeclarationStatement.cs new file mode 100644 index 0000000000..589fea5a6c --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/LabelDeclarationStatement.cs @@ -0,0 +1,35 @@ +// 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 +{ + /// + /// Label: + /// + public class LabelDeclarationStatement : Statement + { + /// either PrimitiveExpression or IdentifierExpression + public Expression Label { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public VBTokenNode Colon { + get { return GetChildByRole(Roles.Colon); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitLabelDeclarationStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + LabelDeclarationStatement o = other as LabelDeclarationStatement; + return o != null && this.Label.DoMatch(o.Label, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/LocalDeclarationStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/LocalDeclarationStatement.cs new file mode 100644 index 0000000000..40c19b2abb --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/LocalDeclarationStatement.cs @@ -0,0 +1,37 @@ +// 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 +{ + /// + /// ( Dim | Static | Const ) VariableDeclarator { , VariableDeclarator } + /// + public class LocalDeclarationStatement : Statement + { + public AstNodeCollection Variables { + get { return GetChildrenByRole(VariableDeclarator.VariableDeclaratorRole); } + } + + public Modifiers Modifiers { + get { return AttributedNode.GetModifiers(this); } + set { AttributedNode.SetModifiers(this, value); } + } + + public VBModifierToken ModifierToken { + get { return GetChildByRole(AttributedNode.ModifierRole); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitLocalDeclarationStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ReturnStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ReturnStatement.cs new file mode 100644 index 0000000000..26deb1ab29 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ReturnStatement.cs @@ -0,0 +1,43 @@ +// 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 +{ + /// + /// Return Expression + /// + public class ReturnStatement : Statement + { + public VBTokenNode ReturnToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public Expression Expression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public ReturnStatement() + { + } + + public ReturnStatement(Expression expression) + { + AddChild (expression, Roles.Expression); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitReturnStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ReturnStatement o = other as ReturnStatement; + return o != null && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs new file mode 100644 index 0000000000..70f2dd7209 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs @@ -0,0 +1,147 @@ +// 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); } + } + + public AstNodeCollection Cases { + get { return GetChildrenByRole(CaseStatement.CaseStatementRole); } + } + + 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 + { + public static readonly Role CaseStatementRole = new Role("CaseStatement"); + + public AstNodeCollection Clauses { + get { return GetChildrenByRole(CaseClause.CaseClauseRole); } + } + + 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.VisitCaseStatement(this, data); + } + } + + public abstract class CaseClause : AstNode + { + #region Null + public new static readonly CaseClause Null = new NullCaseClause(); + + sealed class NullCaseClause : CaseClause + { + public override bool IsNull { + get { + return true; + } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return default (S); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } + } + #endregion + + public static readonly Role CaseClauseRole = new Role("CaseClause", CaseClause.Null); + + public Expression Expression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + } + + public class SimpleCaseClause : CaseClause + { + 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.VisitSimpleCaseClause(this, data); + } + } + + public class RangeCaseClause : CaseClause + { + public static readonly Role ToExpressionRole = ForStatement.ToExpressionRole; + + public Expression ToExpression { + get { return GetChildByRole(ToExpressionRole); } + set { SetChildByRole(ToExpressionRole, 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.VisitRangeCaseClause(this, data); + } + } + + public class ComparisonCaseClause : CaseClause + { + public static readonly Role OperatorRole = BinaryOperatorExpression.OperatorRole; + + public ComparisonOperator Operator { get; set; } + + 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.VisitComparisonCaseClause(this, data); + } + } + + public enum ComparisonOperator + { + Equality = BinaryOperatorType.Equality, + InEquality = BinaryOperatorType.InEquality, + LessThan = BinaryOperatorType.LessThan, + GreaterThan = BinaryOperatorType.GreaterThan, + LessThanOrEqual = BinaryOperatorType.LessThanOrEqual, + GreaterThanOrEqual = BinaryOperatorType.GreaterThanOrEqual + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs index c20407051c..5b2a55bbb3 100644 --- a/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs @@ -115,18 +115,18 @@ namespace ICSharpCode.NRefactory.VB.Ast } // Make debugging easier by giving Statements a ToString() implementation - public override string ToString() - { -// if (IsNull) -// return "Null"; -// StringWriter w = new StringWriter(); -// AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null); -// string text = w.ToString().TrimEnd().Replace("\t", "").Replace(w.NewLine, " "); -// if (text.Length > 100) -// return text.Substring(0, 97) + "..."; -// else -// return text; - throw new NotImplementedException(); - } +// public override string ToString() +// { +//// if (IsNull) +//// return "Null"; +//// StringWriter w = new StringWriter(); +//// AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null); +//// string text = w.ToString().TrimEnd().Replace("\t", "").Replace(w.NewLine, " "); +//// if (text.Length > 100) +//// return text.Substring(0, 97) + "..."; +//// else +//// return text; +// throw new NotImplementedException(); +// } } } diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/SyncLockStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/SyncLockStatement.cs new file mode 100644 index 0000000000..7fd317eb09 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/SyncLockStatement.cs @@ -0,0 +1,36 @@ +// 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 +{ + /// + /// SyncLock Expression
+ /// Block
+ /// End SyncLock + ///
+ public class SyncLockStatement : Statement + { + public Expression Expression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public BlockStatement Body { + get { return GetChildByRole(Roles.Body); } + set { SetChildByRole(Roles.Body, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitSyncLockStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/ThrowStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/ThrowStatement.cs new file mode 100644 index 0000000000..c4c1634b5c --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/ThrowStatement.cs @@ -0,0 +1,43 @@ +// 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 +{ + /// + /// Throw Expression + /// + public class ThrowStatement : Statement + { + public VBTokenNode ThrowToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public Expression Expression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public ThrowStatement() + { + } + + public ThrowStatement(Expression expression) + { + AddChild (expression, Roles.Expression); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitThrowStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + ThrowStatement o = other as ThrowStatement; + return o != null && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/TryStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/TryStatement.cs new file mode 100644 index 0000000000..7e5eb94da9 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/TryStatement.cs @@ -0,0 +1,67 @@ +// 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 TryStatement : Statement + { + public static readonly Role FinallyBlockRole = new Role("FinallyBlock", Ast.BlockStatement.Null); + + public BlockStatement Body { + get { return GetChildByRole(Roles.Body); } + set { SetChildByRole(Roles.Body, value); } + } + + public AstNodeCollection CatchBlocks { + get { return GetChildrenByRole(CatchBlock.CatchBlockRole); } + } + + public BlockStatement FinallyBlock { + get { return GetChildByRole(FinallyBlockRole); } + set { SetChildByRole(FinallyBlockRole, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitTryStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + throw new NotImplementedException(); + } + } + + public class CatchBlock : BlockStatement + { + public static readonly Role CatchBlockRole = new Role("CatchBlockRole"); + + public Identifier ExceptionVariable { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public AstType ExceptionType { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + public Expression WhenExpression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitCatchBlock(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/UsingStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/UsingStatement.cs new file mode 100644 index 0000000000..c2147e447a --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/UsingStatement.cs @@ -0,0 +1,33 @@ +// 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 UsingStatement : Statement + { + public static readonly Role ResourceRole = new Role("Resource", AstNode.Null); + + /// either multiple VariableInitializers or one Expression + public AstNodeCollection Resources { + get { return GetChildrenByRole(ResourceRole); } + } + + 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.VisitUsingStatement(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/WhileStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/WhileStatement.cs new file mode 100644 index 0000000000..e5c9ec24c5 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/WhileStatement.cs @@ -0,0 +1,31 @@ +// 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 WhileStatement : Statement + { + public Expression Condition { + 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.VisitWhileStatement(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/WithStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/WithStatement.cs new file mode 100644 index 0000000000..b915a90815 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/WithStatement.cs @@ -0,0 +1,36 @@ +// 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 +{ + /// + /// With Expression
+ /// Block
+ /// End With + ///
+ public class WithStatement : Statement + { + public Expression Expression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public BlockStatement Body { + get { return GetChildByRole(Roles.Body); } + set { SetChildByRole(Roles.Body, value); } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return visitor.VisitWithStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/Statements/YieldStatement.cs b/ICSharpCode.NRefactory.VB/Ast/Statements/YieldStatement.cs new file mode 100644 index 0000000000..895382aa1d --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/Statements/YieldStatement.cs @@ -0,0 +1,44 @@ +// 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 +{ + /// + /// Yield Expression + /// + /// VB 11 + public class YieldStatement : Statement + { + public VBTokenNode YieldToken { + get { return GetChildByRole (Roles.Keyword); } + } + + public Expression Expression { + get { return GetChildByRole(Roles.Expression); } + set { SetChildByRole(Roles.Expression, value); } + } + + public YieldStatement() + { + } + + public YieldStatement(Expression expression) + { + AddChild (expression, Roles.Expression); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitYieldStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + YieldStatement o = other as YieldStatement; + return o != null && this.Expression.DoMatch(o.Expression, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/Accessor.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/Accessor.cs new file mode 100644 index 0000000000..7eb287c267 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/Accessor.cs @@ -0,0 +1,49 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Get/Set/AddHandler/RemoveHandler/RaiseEvent + /// + public class Accessor : AttributedNode + { + public static readonly new Accessor Null = new NullAccessor (); + sealed class NullAccessor : Accessor + { + public override bool IsNull { + get { + return true; + } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return default (S); + } + } + + public BlockStatement Body { + get { return GetChildByRole(Roles.Body); } + set { SetChildByRole(Roles.Body, value); } + } + + public AstNodeCollection Parameters { + get { return GetChildrenByRole(Roles.Parameter); } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitAccessor(this, data); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + Accessor o = other as Accessor; + return o != null && !o.IsNull && this.MatchAttributesAndModifiers(o, match) && + this.Body.DoMatch(o.Body, match) && Parameters.DoMatch(o.Parameters, match); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ConstructorDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ConstructorDeclaration.cs new file mode 100644 index 0000000000..9e57fc572d --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ConstructorDeclaration.cs @@ -0,0 +1,45 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public abstract class MemberDeclaration : AttributedNode + { + + } + + /// + /// Description of ConstructorDeclaration. + /// + public class ConstructorDeclaration : MemberDeclaration + { + public ConstructorDeclaration() + { + } + + public AstNodeCollection Parameters { + get { return GetChildrenByRole(Roles.Parameter); } + } + + 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) + { + var ctor = other as ConstructorDeclaration; + return ctor != null && + MatchAttributesAndModifiers(ctor, match) && + Parameters.DoMatch(ctor.Parameters, match) && + Body.DoMatch(ctor.Body, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitConstructorDeclaration(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/EventDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/EventDeclaration.cs new file mode 100644 index 0000000000..ce01819640 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/EventDeclaration.cs @@ -0,0 +1,59 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class EventDeclaration : MemberDeclaration + { + public bool IsCustom { get; set; } + + public static readonly Role AddHandlerRole = new Role("AddHandler", Accessor.Null); + public static readonly Role RemoveHandlerRole = new Role("RemoveHandler", Accessor.Null); + public static readonly Role RaiseEventRole = new Role("RaiseEvent", Accessor.Null); + + public Identifier Name { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public AstType ReturnType { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + public AstNodeCollection Parameters { + get { return GetChildrenByRole(Roles.Parameter); } + } + + public AstNodeCollection ImplementsClause { + get { return GetChildrenByRole(InterfaceMemberSpecifier.InterfaceMemberSpecifierRole); } + } + + public Accessor AddHandlerBlock { + get { return GetChildByRole(AddHandlerRole); } + set { SetChildByRole(AddHandlerRole, value); } + } + + public Accessor RemoveHandlerBlock { + get { return GetChildByRole(RemoveHandlerRole); } + set { SetChildByRole(RemoveHandlerRole, value); } + } + + public Accessor RaiseEventBlock { + get { return GetChildByRole(RaiseEventRole); } + set { SetChildByRole(RaiseEventRole, 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.VisitEventDeclaration(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ExternalMethodDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ExternalMethodDeclaration.cs new file mode 100644 index 0000000000..d5d9754472 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ExternalMethodDeclaration.cs @@ -0,0 +1,71 @@ +// 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.Runtime.InteropServices; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class ExternalMethodDeclaration : MemberDeclaration + { + public ExternalMethodDeclaration() + { + } + + public CharsetModifier CharsetModifier { get; set; } + + public bool IsSub { get; set; } + + public Identifier Name { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public string Library { get; set; } + + public string Alias { 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); } + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + // TODO : finish + var method = other as ExternalMethodDeclaration; + return method != null && + MatchAttributesAndModifiers(method, match) && + IsSub == method.IsSub && + Name.DoMatch(method.Name, match) && + Parameters.DoMatch(method.Parameters, match) && + ReturnTypeAttributes.DoMatch(method.ReturnTypeAttributes, match) && + ReturnType.DoMatch(method.ReturnType, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitExternalMethodDeclaration(this, data); + } + } + + /// + /// Charset types, used in external methods + /// declarations (VB only). + /// + public enum CharsetModifier + { + None, + Auto, + Unicode, + Ansi + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs new file mode 100644 index 0000000000..528d632cb4 --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs @@ -0,0 +1,81 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// Attributes? VariableModifier+ VariableDeclarators StatementTerminator + /// + public class FieldDeclaration : MemberDeclaration + { + public AstNodeCollection Variables { + get { return GetChildrenByRole(VariableDeclarator.VariableDeclaratorRole); } + } + + 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.VisitFieldDeclaration(this, data); + } + } + + + + /// + /// Identifier IdentifierModifiers + /// + public class VariableIdentifier : AstNode + { + #region Null + public new static readonly VariableIdentifier Null = new NullVariableIdentifier(); + + sealed class NullVariableIdentifier : VariableIdentifier + { + public override bool IsNull { + get { + return true; + } + } + + public override S AcceptVisitor (IAstVisitor visitor, T data) + { + return default (S); + } + + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + { + return other == null || other.IsNull; + } + } + #endregion + + public static readonly Role VariableIdentifierRole = new Role("VariableIdentifier", VariableIdentifier.Null); + + public Identifier Name { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public bool HasNullableSpecifier { get; set; } + + public AstNodeCollection ArraySpecifiers { + get { return GetChildrenByRole(ComposedType.ArraySpecifierRole); } + } + + 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.VisitVariableIdentifier(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/MethodDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/MethodDeclaration.cs new file mode 100644 index 0000000000..a6dd87159e --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/MethodDeclaration.cs @@ -0,0 +1,72 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class MethodDeclaration : MemberDeclaration + { + public MethodDeclaration() + { + } + + public bool IsSub { get; set; } + + public Identifier Name { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + public AstNodeCollection TypeParameters { + get { return GetChildrenByRole(Roles.TypeParameter); } + } + + 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 AstNodeCollection HandlesClause { + get { return GetChildrenByRole(EventMemberSpecifier.EventMemberSpecifierRole); } + } + + public AstNodeCollection ImplementsClause { + get { return GetChildrenByRole(InterfaceMemberSpecifier.InterfaceMemberSpecifierRole); } + } + + 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) + { + var method = other as MethodDeclaration; + return method != null && + MatchAttributesAndModifiers(method, match) && + IsSub == method.IsSub && + Name.DoMatch(method.Name, match) && + TypeParameters.DoMatch(method.TypeParameters, match) && + Parameters.DoMatch(method.Parameters, match) && + ReturnTypeAttributes.DoMatch(method.ReturnTypeAttributes, match) && + ReturnType.DoMatch(method.ReturnType, match) && + HandlesClause.DoMatch(method.HandlesClause, match) && + ImplementsClause.DoMatch(method.ImplementsClause, match) && + Body.DoMatch(method.Body, match); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return visitor.VisitMethodDeclaration(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/OperatorDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/OperatorDeclaration.cs new file mode 100644 index 0000000000..f6591e4a4f --- /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 MIT X11 license (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/TypeMembers/PropertyDeclaration.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/PropertyDeclaration.cs new file mode 100644 index 0000000000..6fdab3842a --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/PropertyDeclaration.cs @@ -0,0 +1,57 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + public class PropertyDeclaration : MemberDeclaration + { + // TODO : support automatic properties + + public static readonly Role GetterRole = new Role("Getter", Accessor.Null); + public static readonly Role SetterRole = new Role("Setter", Accessor.Null); + + public Identifier Name { + get { return GetChildByRole(Roles.Identifier); } + set { SetChildByRole(Roles.Identifier, value); } + } + + 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 AstNodeCollection ImplementsClause { + get { return GetChildrenByRole(InterfaceMemberSpecifier.InterfaceMemberSpecifierRole); } + } + + public Accessor Getter { + get { return GetChildByRole(GetterRole); } + set { SetChildByRole(GetterRole, value); } + } + + public Accessor Setter { + get { return GetChildByRole(SetterRole); } + set { SetChildByRole(SetterRole, 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.VisitPropertyDeclaration(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeMembers/VariableDeclarator.cs b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/VariableDeclarator.cs new file mode 100644 index 0000000000..a3ad2892ad --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Ast/TypeMembers/VariableDeclarator.cs @@ -0,0 +1,63 @@ +// 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; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// VariableIdentifiers As ObjectCreationExpression
+ /// VariableIdentifiers ( As TypeName )? ( Equals Expression )? + ///
+ public abstract class VariableDeclarator : AstNode + { + public static readonly Role VariableDeclaratorRole = new Role("VariableDeclarator"); + + public AstNodeCollection Identifiers { + get { return GetChildrenByRole(VariableIdentifier.VariableIdentifierRole); } + } + } + + public class VariableDeclaratorWithTypeAndInitializer : VariableDeclarator + { + public AstType Type { + get { return GetChildByRole(Roles.Type); } + set { SetChildByRole(Roles.Type, value); } + } + + public Expression Initializer { + 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.VisitVariableDeclaratorWithTypeAndInitializer(this, data); + } + } + + public class VariableDeclaratorWithObjectCreation : VariableDeclarator + { + public static readonly Role InitializerRole = new Role("InitializerRole"); + + public ObjectCreationExpression Initializer { + get { return GetChildByRole(InitializerRole); } + set { SetChildByRole(InitializerRole, 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.VisitVariableDeclaratorWithObjectCreation(this, data); + } + } +} diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeName/AstType.cs b/ICSharpCode.NRefactory.VB/Ast/TypeName/AstType.cs index 13ba3ee971..ca39bd369e 100644 --- a/ICSharpCode.NRefactory.VB/Ast/TypeName/AstType.cs +++ b/ICSharpCode.NRefactory.VB/Ast/TypeName/AstType.cs @@ -1,7 +1,8 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; +using System.Linq; namespace ICSharpCode.NRefactory.VB.Ast { @@ -70,38 +71,55 @@ namespace ICSharpCode.NRefactory.VB.Ast return new ComposedType { BaseType = this }.MakeArrayType(rank); } - // TODO : reimplement this -// /// -// /// Builds an expression that can be used to access a static member on this type. -// /// -// public MemberReferenceExpression Member(string memberName) -// { -// return new TypeReferenceExpression { Type = this }.Member(memberName); -// } -// -// /// -// /// Builds an invocation expression using this type as target. -// /// -// public InvocationExpression Invoke(string methodName, IEnumerable arguments) -// { -// return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments); -// } -// -// /// -// /// Builds an invocation expression using this type as target. -// /// -// public InvocationExpression Invoke(string methodName, params Expression[] arguments) -// { -// return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments); -// } -// -// /// -// /// Builds an invocation expression using this type as target. -// /// -// public InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) -// { -// return new TypeReferenceExpression { Type = this }.Invoke(methodName, typeArguments, arguments); -// } + public static AstType FromName(string fullName) + { + if (string.IsNullOrEmpty(fullName)) + throw new ArgumentNullException("fullName"); + fullName = fullName.Trim(); + if (!fullName.Contains(".")) + return new SimpleType(fullName); + string[] parts = fullName.Split('.'); + + AstType type = new SimpleType(parts.First()); + + foreach (var part in parts.Skip(1)) { + type = new QualifiedType(type, part); + } + + return type; + } + + /// + /// Builds an expression that can be used to access a static member on this type. + /// + public MemberAccessExpression Member(string memberName) + { + return new TypeReferenceExpression { Type = this }.Member(memberName); + } + + /// + /// Builds an invocation expression using this type as target. + /// + public InvocationExpression Invoke(string methodName, IEnumerable arguments) + { + return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments); + } + + /// + /// Builds an invocation expression using this type as target. + /// + public InvocationExpression Invoke(string methodName, params Expression[] arguments) + { + return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments); + } + + /// + /// Builds an invocation expression using this type as target. + /// + public InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + return new TypeReferenceExpression { Type = this }.Invoke(methodName, typeArguments, arguments); + } public static AstType Create(Type type) { diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeName/ComposedType.cs b/ICSharpCode.NRefactory.VB/Ast/TypeName/ComposedType.cs index e214a7e4b5..4b688366c9 100644 --- a/ICSharpCode.NRefactory.VB/Ast/TypeName/ComposedType.cs +++ b/ICSharpCode.NRefactory.VB/Ast/TypeName/ComposedType.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; using System.Linq; diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeName/PrimitiveType.cs b/ICSharpCode.NRefactory.VB/Ast/TypeName/PrimitiveType.cs index 8d6badc8f3..d7dc0c2451 100644 --- a/ICSharpCode.NRefactory.VB/Ast/TypeName/PrimitiveType.cs +++ b/ICSharpCode.NRefactory.VB/Ast/TypeName/PrimitiveType.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; using System.Linq; diff --git a/ICSharpCode.NRefactory.VB/Ast/TypeName/QualifiedType.cs b/ICSharpCode.NRefactory.VB/Ast/TypeName/QualifiedType.cs index 116f9918c9..4c3d93cd36 100644 --- a/ICSharpCode.NRefactory.VB/Ast/TypeName/QualifiedType.cs +++ b/ICSharpCode.NRefactory.VB/Ast/TypeName/QualifiedType.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Linq; diff --git a/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs b/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs index 05a22acc44..4b5a57ce3c 100644 --- a/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs +++ b/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; @@ -46,10 +46,11 @@ namespace ICSharpCode.NRefactory.VB.Ast new KeyValuePair(Modifiers.Overridable, "Overridable".Length), new KeyValuePair(Modifiers.NotInheritable, "NotInheritable".Length), new KeyValuePair(Modifiers.NotOverridable, "NotOverridable".Length), + new KeyValuePair(Modifiers.Dim, "Dim".Length), new KeyValuePair(Modifiers.Const, "Const".Length), new KeyValuePair(Modifiers.Shared, "Shared".Length), new KeyValuePair(Modifiers.Static, "Static".Length), - new KeyValuePair(Modifiers.Override, "Override".Length), + new KeyValuePair(Modifiers.Overrides, "Overrides".Length), new KeyValuePair(Modifiers.ReadOnly, "ReadOnly".Length), new KeyValuePair(Modifiers.WriteOnly, "WriteOnly".Length), new KeyValuePair(Modifiers.Shadows, "Shadows".Length), @@ -57,8 +58,17 @@ namespace ICSharpCode.NRefactory.VB.Ast new KeyValuePair(Modifiers.Overloads, "Overloads".Length), new KeyValuePair(Modifiers.WithEvents, "WithEvents".Length), new KeyValuePair(Modifiers.Default, "Default".Length), - new KeyValuePair(Modifiers.Dim, "Dim".Length), - + // parameter modifiers + new KeyValuePair(Modifiers.Optional, "Optional".Length), + 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), + // VB 11 modifiers + new KeyValuePair(Modifiers.Async, "Async".Length), + new KeyValuePair(Modifiers.Iterator, "Iterator".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) }; @@ -99,8 +109,8 @@ namespace ICSharpCode.NRefactory.VB.Ast return "Shared"; case Modifiers.Static: return "Static"; - case Modifiers.Override: - return "Override"; + case Modifiers.Overrides: + return "Overrides"; case Modifiers.ReadOnly: return "ReadOnly"; case Modifiers.Shadows: @@ -117,8 +127,24 @@ namespace ICSharpCode.NRefactory.VB.Ast return "Dim"; case Modifiers.WriteOnly: return "WriteOnly"; + case Modifiers.Optional: + return "Optional"; + case Modifiers.ByVal: + return "ByVal"; + case Modifiers.ByRef: + return "ByRef"; + case Modifiers.ParamArray: + return "ParamArray"; + case Modifiers.Widening: + return "Widening"; + case Modifiers.Narrowing: + return "Narrowing"; + case Modifiers.Async: + return "Async"; + case Modifiers.Iterator: + return "Iterator"; default: - throw new NotSupportedException("Invalid value for Modifiers"); + throw new NotSupportedException("Invalid value for Modifiers: " + modifier); } } } diff --git a/ICSharpCode.NRefactory.VB/AstBuilder/ExpressionBuilder.cs b/ICSharpCode.NRefactory.VB/AstBuilder/ExpressionBuilder.cs index 402dc449f6..7ac2ef32ce 100644 --- a/ICSharpCode.NRefactory.VB/AstBuilder/ExpressionBuilder.cs +++ b/ICSharpCode.NRefactory.VB/AstBuilder/ExpressionBuilder.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/AstBuilder/StatementBuilder.cs b/ICSharpCode.NRefactory.VB/AstBuilder/StatementBuilder.cs index 1f3541f15a..eb227171f9 100644 --- a/ICSharpCode.NRefactory.VB/AstBuilder/StatementBuilder.cs +++ b/ICSharpCode.NRefactory.VB/AstBuilder/StatementBuilder.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/IAstVisitor.cs b/ICSharpCode.NRefactory.VB/IAstVisitor.cs index a2f8ac6c75..c24e2b617b 100644 --- a/ICSharpCode.NRefactory.VB/IAstVisitor.cs +++ b/ICSharpCode.NRefactory.VB/IAstVisitor.cs @@ -9,18 +9,21 @@ namespace ICSharpCode.NRefactory.VB { public interface IAstVisitor { S VisitBlockStatement(BlockStatement blockStatement, T data); + S VisitComment(Comment comment, T data); S VisitCompilationUnit(CompilationUnit compilationUnit, T data); S VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern, T data); S VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, T data); S VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, T data); S VisitVBTokenNode(VBTokenNode vBTokenNode, T data); + S VisitEventMemberSpecifier(EventMemberSpecifier eventMemberSpecifier, T data); + S VisitInterfaceMemberSpecifier(InterfaceMemberSpecifier interfaceMemberSpecifier, T data); // Global scope S VisitAliasImportsClause(AliasImportsClause aliasImportsClause, T data); S VisitAttribute(Attribute attribute, T data); S VisitAttributeBlock(AttributeBlock attributeBlock, T data); S VisitImportsStatement(ImportsStatement importsStatement, T data); - S VisitMembersImportsClause(MemberImportsClause membersImportsClause, T data); + S VisitMemberImportsClause(MemberImportsClause memberImportsClause, T data); S VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, T data); S VisitOptionStatement(OptionStatement optionStatement, T data); S VisitTypeDeclaration(TypeDeclaration typeDeclaration, T data); @@ -29,12 +32,70 @@ namespace ICSharpCode.NRefactory.VB { S VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, T data); S VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, T data); + // TypeMember scope + S VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, T data); + S VisitMethodDeclaration(MethodDeclaration methodDeclaration, T data); + S VisitExternalMethodDeclaration(ExternalMethodDeclaration externalMethodDeclaration, T data); + S VisitFieldDeclaration(FieldDeclaration fieldDeclaration, T data); + S VisitVariableDeclaratorWithTypeAndInitializer(VariableDeclaratorWithTypeAndInitializer variableDeclaratorWithTypeAndInitializer, T data); + S VisitVariableDeclaratorWithObjectCreation(VariableDeclaratorWithObjectCreation variableDeclaratorWithObjectCreation, T data); + S VisitVariableIdentifier(VariableIdentifier variableIdentifier, T data); + 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); S VisitXmlIdentifier(XmlIdentifier xmlIdentifier, T data); S VisitXmlLiteralString(XmlLiteralString xmlLiteralString, T data); S VisitSimpleNameExpression(SimpleNameExpression identifierExpression, T data); S VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, T data); + S VisitInstanceExpression(InstanceExpression instanceExpression, T data); + S VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, T data); + S VisitGetTypeExpression(GetTypeExpression getTypeExpression, T data); + S VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, T data); + S VisitGetXmlNamespaceExpression(GetXmlNamespaceExpression getXmlNamespaceExpression, T data); + S VisitMemberAccessExpression(MemberAccessExpression memberAccessExpression, T data); + S VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, T data); + S VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, T data); + S VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, T data); + S VisitAssignmentExpression(AssignmentExpression assignmentExpression, T data); + S VisitIdentifierExpression(IdentifierExpression identifierExpression, T data); + S VisitInvocationExpression(InvocationExpression invocationExpression, T data); + S VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, T data); + S VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, T data); + S VisitObjectCreationExpression(ObjectCreationExpression objectCreationExpression, T data); + S VisitCastExpression(CastExpression castExpression, T data); + S VisitFieldInitializerExpression(FieldInitializerExpression fieldInitializerExpression, T data); + S VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, T data); + S VisitConditionalExpression(ConditionalExpression conditionalExpression, T data); + + // Statement scope + S VisitLabelDeclarationStatement(LabelDeclarationStatement labelDeclarationStatement, T data); + S VisitLocalDeclarationStatement(LocalDeclarationStatement localDeclarationStatement, T data); + S VisitExpressionStatement(ExpressionStatement expressionStatement, T data); + S VisitWithStatement(WithStatement withStatement, T data); + S VisitSyncLockStatement(SyncLockStatement syncLockStatement, T data); + S VisitIfElseStatement(IfElseStatement ifElseStatement, T data); + S VisitTryStatement(TryStatement tryStatement, T data); + S VisitThrowStatement(ThrowStatement throwStatement, T data); + 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 VisitContinueStatement(ContinueStatement continueStatement, T data); + S VisitSelectStatement(SelectStatement selectStatement, T data); + S VisitYieldStatement(YieldStatement yieldStatement, T data); + S VisitVariableInitializer(VariableInitializer variableInitializer, T data); + S VisitRangeCaseClause(RangeCaseClause rangeCaseClause, T data); + S VisitComparisonCaseClause(ComparisonCaseClause comparisonCaseClause, T data); + S VisitSimpleCaseClause(SimpleCaseClause simpleCaseClause, T data); + S VisitCaseStatement(CaseStatement caseStatement, T data); + S VisitDoLoopStatement(DoLoopStatement doLoopStatement, T data); + S VisitUsingStatement(UsingStatement usingStatement, T data); // TypeName S VisitPrimitiveType(PrimitiveType primitiveType, T data); @@ -42,5 +103,33 @@ namespace ICSharpCode.NRefactory.VB { S VisitComposedType(ComposedType composedType, T data); S VisitArraySpecifier(ArraySpecifier arraySpecifier, T data); S VisitSimpleType(SimpleType simpleType, T data); + + S VisitGoToStatement(GoToStatement goToStatement, T data); + + S VisitSingleLineSubLambdaExpression(SingleLineSubLambdaExpression singleLineSubLambdaExpression, T data); + S VisitMultiLineLambdaExpression(MultiLineLambdaExpression multiLineLambdaExpression, T data); + S VisitSingleLineFunctionLambdaExpression(SingleLineFunctionLambdaExpression singleLineFunctionLambdaExpression, T data); + + S VisitQueryExpression(QueryExpression queryExpression, T data); + + S VisitEmptyExpression(EmptyExpression emptyExpression, T data); + + S VisitAnonymousObjectCreationExpression(AnonymousObjectCreationExpression anonymousObjectCreationExpression, T data); + + S VisitCollectionRangeVariableDeclaration(CollectionRangeVariableDeclaration collectionRangeVariableDeclaration, T data); + + S VisitFromQueryOperator(FromQueryOperator fromQueryOperator, T data); + S VisitAggregateQueryOperator(AggregateQueryOperator aggregateQueryOperator, T data); + S VisitSelectQueryOperator(SelectQueryOperator selectQueryOperator, T data); + S VisitDistinctQueryOperator(DistinctQueryOperator distinctQueryOperator, T data); + S VisitWhereQueryOperator(WhereQueryOperator whereQueryOperator, T data); + S VisitOrderExpression(OrderExpression orderExpression, T data); + S VisitOrderByQueryOperator(OrderByQueryOperator orderByQueryOperator, T data); + S VisitPartitionQueryOperator(PartitionQueryOperator partitionQueryOperator, T data); + S VisitLetQueryOperator(LetQueryOperator letQueryOperator, T data); + S VisitGroupByQueryOperator(GroupByQueryOperator groupByQueryOperator, T data); + S VisitJoinQueryOperator(JoinQueryOperator joinQueryOperator, T data); + S VisitJoinCondition(JoinCondition joinCondition, T data); + S VisitGroupJoinQueryOperator(GroupJoinQueryOperator groupJoinQueryOperator, T data); } } diff --git a/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj b/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj index 1dac9e1d98..c100ed7176 100644 --- a/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj +++ b/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj @@ -3,16 +3,20 @@ {7B82B671-419F-45F4-B778-D9286F996EFA} Debug - x86 + AnyCPU Library ICSharpCode.NRefactory.VB ICSharpCode.NRefactory.VB v4.0 Properties Client + False + False + 4 + false - - x86 + + AnyCPU bin\Debug\ @@ -46,16 +50,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -70,7 +102,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -122,6 +182,7 @@ + @@ -130,6 +191,7 @@ + diff --git a/ICSharpCode.NRefactory.VB/Lexer/Block.cs b/ICSharpCode.NRefactory.VB/Lexer/Block.cs index c9ffba0d20..b568e0440d 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Block.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Block.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinder.cs b/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinder.cs index 15b9bdd6d2..cb6f236158 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinder.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinder.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinderState.cs b/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinderState.cs index 485ed3d237..0feda1f93e 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinderState.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/ExpressionFinderState.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Extensions.cs b/ICSharpCode.NRefactory.VB/Lexer/Extensions.cs index 7b5d4163a5..0107d3f088 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Extensions.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Extensions.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/LATextReader.cs b/ICSharpCode.NRefactory.VB/Lexer/LATextReader.cs index f11043307b..eff8b821eb 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/LATextReader.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/LATextReader.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/LookupTable.cs b/ICSharpCode.NRefactory.VB/Lexer/LookupTable.cs index 2ec80b687a..eb2c94dfcf 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/LookupTable.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/LookupTable.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Globalization; diff --git a/ICSharpCode.NRefactory.VB/Lexer/SavepointEventArgs.cs b/ICSharpCode.NRefactory.VB/Lexer/SavepointEventArgs.cs index f3ee77a93f..651ecb71b7 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/SavepointEventArgs.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/SavepointEventArgs.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Special/BlankLine.cs b/ICSharpCode.NRefactory.VB/Lexer/Special/BlankLine.cs index 5120bd7650..5821ca6a98 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Special/BlankLine.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Special/BlankLine.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Special/Comment.cs b/ICSharpCode.NRefactory.VB/Lexer/Special/Comment.cs index 82772f2d42..ecfc393fa4 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Special/Comment.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Special/Comment.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Special/CommentType.cs b/ICSharpCode.NRefactory.VB/Lexer/Special/CommentType.cs index 1c9bb63e92..7eac974d5c 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Special/CommentType.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Special/CommentType.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Special/ISpecial.cs b/ICSharpCode.NRefactory.VB/Lexer/Special/ISpecial.cs index a589642112..52c1abb37e 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Special/ISpecial.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Special/ISpecial.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Special/PreProcessingDirective.cs b/ICSharpCode.NRefactory.VB/Lexer/Special/PreProcessingDirective.cs index 97c0a7481a..4b9222190e 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Special/PreProcessingDirective.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Special/PreProcessingDirective.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Special/SpecialTracker.cs b/ICSharpCode.NRefactory.VB/Lexer/Special/SpecialTracker.cs index 2107163e4c..6ae334b2f6 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Special/SpecialTracker.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Special/SpecialTracker.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Special/TagComment.cs b/ICSharpCode.NRefactory.VB/Lexer/Special/TagComment.cs index 3209cf162e..39863d1256 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Special/TagComment.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Special/TagComment.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Lexer/Token.cs b/ICSharpCode.NRefactory.VB/Lexer/Token.cs index ae4ed7d63e..54df5cab67 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/Token.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/Token.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Lexer/VBLexer.cs b/ICSharpCode.NRefactory.VB/Lexer/VBLexer.cs index 6aac502c21..ea2dc116ee 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/VBLexer.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/VBLexer.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections; diff --git a/ICSharpCode.NRefactory.VB/Lexer/VBLexerMemento.cs b/ICSharpCode.NRefactory.VB/Lexer/VBLexerMemento.cs index 148475ccd8..30e9d0f8cd 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/VBLexerMemento.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/VBLexerMemento.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Lexer/XmlModeInfo.cs b/ICSharpCode.NRefactory.VB/Lexer/XmlModeInfo.cs index 4f3ef71e97..2141ac3532 100644 --- a/ICSharpCode.NRefactory.VB/Lexer/XmlModeInfo.cs +++ b/ICSharpCode.NRefactory.VB/Lexer/XmlModeInfo.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/OutputVisitor/IOutputFormatter.cs b/ICSharpCode.NRefactory.VB/OutputVisitor/IOutputFormatter.cs index a544eb0d00..056b0d1cda 100644 --- a/ICSharpCode.NRefactory.VB/OutputVisitor/IOutputFormatter.cs +++ b/ICSharpCode.NRefactory.VB/OutputVisitor/IOutputFormatter.cs @@ -16,7 +16,7 @@ namespace ICSharpCode.NRefactory.VB /// /// Writes an identifier. /// If the identifier conflicts with a keyword, the output visitor will - /// call WriteToken("@") before calling WriteIdentifier(). + /// call WriteToken("[") before and WriteToken("]") after calling WriteIdentifier(). /// void WriteIdentifier(string identifier); @@ -35,5 +35,10 @@ namespace ICSharpCode.NRefactory.VB void Unindent(); void NewLine(); + + void WriteComment(bool isDocumentation, string content); + + void MarkFoldStart(); + void MarkFoldEnd(); } } diff --git a/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs b/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs index f4085b6bc7..d359cb8973 100644 --- a/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs +++ b/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs @@ -1,9 +1,13 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; using System.IO; +using System.Linq; +using System.Text; using ICSharpCode.NRefactory.PatternMatching; using ICSharpCode.NRefactory.VB.Ast; @@ -21,6 +25,18 @@ namespace ICSharpCode.NRefactory.VB readonly Stack containerStack = new Stack(); readonly Stack positionStack = new Stack(); + /// + /// Used to insert the minimal amount of spaces so that the lexer recognizes the tokens that were written. + /// + LastWritten lastWritten; + + enum LastWritten + { + Whitespace, + Other, + KeywordOrIdentifier + } + public OutputVisitor(TextWriter textWriter, VBFormattingOptions formattingPolicy) { if (textWriter == null) @@ -41,7 +57,7 @@ namespace ICSharpCode.NRefactory.VB this.policy = formattingPolicy; } - public object VisitCompilationUnit(ICSharpCode.NRefactory.VB.Ast.CompilationUnit compilationUnit, object data) + public object VisitCompilationUnit(CompilationUnit compilationUnit, object data) { // don't do node tracking as we visit all children directly foreach (AstNode node in compilationUnit.Children) @@ -51,7 +67,12 @@ namespace ICSharpCode.NRefactory.VB public object VisitBlockStatement(BlockStatement blockStatement, object data) { - throw new NotImplementedException(); + StartNode(blockStatement); + foreach (var stmt in blockStatement) { + stmt.AcceptVisitor(this, data); + NewLine(); + } + return EndNode(blockStatement); } public object VisitPatternPlaceholder(AstNode placeholder, Pattern pattern, object data) @@ -61,17 +82,61 @@ namespace ICSharpCode.NRefactory.VB public object VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, object data) { - throw new NotImplementedException(); + StartNode(typeParameterDeclaration); + + switch (typeParameterDeclaration.Variance) { + case ICSharpCode.NRefactory.TypeSystem.VarianceModifier.Invariant: + break; + case ICSharpCode.NRefactory.TypeSystem.VarianceModifier.Covariant: + WriteKeyword("Out"); + break; + case ICSharpCode.NRefactory.TypeSystem.VarianceModifier.Contravariant: + WriteKeyword("In"); + break; + default: + throw new Exception("Invalid value for VarianceModifier"); + } + + WriteIdentifier(typeParameterDeclaration.Name); + if (typeParameterDeclaration.Constraints.Any()) { + WriteKeyword("As"); + if (typeParameterDeclaration.Constraints.Count > 1) + WriteToken("{", TypeParameterDeclaration.Roles.LBrace); + WriteCommaSeparatedList(typeParameterDeclaration.Constraints); + if (typeParameterDeclaration.Constraints.Count > 1) + WriteToken("}", TypeParameterDeclaration.Roles.RBrace); + } + + return EndNode(typeParameterDeclaration); } public object VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, object data) { - throw new NotImplementedException(); + StartNode(parameterDeclaration); + WriteAttributes(parameterDeclaration.Attributes); + WriteModifiers(parameterDeclaration.ModifierTokens); + WriteIdentifier(parameterDeclaration.Name.Name); + if (!parameterDeclaration.Type.IsNull) { + WriteKeyword("As"); + parameterDeclaration.Type.AcceptVisitor(this, data); + } + if (!parameterDeclaration.OptionalValue.IsNull) { + WriteToken("=", ParameterDeclaration.Roles.Assign); + parameterDeclaration.OptionalValue.AcceptVisitor(this, data); + } + return EndNode(parameterDeclaration); } public object VisitVBTokenNode(VBTokenNode vBTokenNode, object data) { - throw new NotImplementedException(); + var mod = vBTokenNode as VBModifierToken; + if (mod != null) { + StartNode(vBTokenNode); + WriteKeyword(VBModifierToken.GetModifierName(mod.Modifier)); + return EndNode(vBTokenNode); + } else { + throw new NotSupportedException("Should never visit individual tokens"); + } } public object VisitAliasImportsClause(AliasImportsClause aliasImportsClause, object data) @@ -81,27 +146,84 @@ namespace ICSharpCode.NRefactory.VB public object VisitAttribute(ICSharpCode.NRefactory.VB.Ast.Attribute attribute, object data) { - throw new NotImplementedException(); + StartNode(attribute); + + if (attribute.Target != AttributeTarget.None) { + switch (attribute.Target) { + case AttributeTarget.None: + break; + case AttributeTarget.Assembly: + WriteKeyword("Assembly"); + break; + case AttributeTarget.Module: + WriteKeyword("Module"); + break; + default: + throw new Exception("Invalid value for AttributeTarget"); + } + WriteToken(":", Ast.Attribute.Roles.Colon); + Space(); + } + attribute.Type.AcceptVisitor(this, data); + WriteCommaSeparatedListInParenthesis(attribute.Arguments, false); + + return EndNode(attribute); } public object VisitAttributeBlock(AttributeBlock attributeBlock, object data) { - throw new NotImplementedException(); + StartNode(attributeBlock); + + WriteToken("<", AttributeBlock.Roles.LChevron); + WriteCommaSeparatedList(attributeBlock.Attributes); + WriteToken(">", AttributeBlock.Roles.RChevron); + if (attributeBlock.Parent is ParameterDeclaration) + Space(); + else + NewLine(); + + return EndNode(attributeBlock); } public object VisitImportsStatement(ImportsStatement importsStatement, object data) { - throw new NotImplementedException(); + StartNode(importsStatement); + + WriteKeyword("Imports", AstNode.Roles.Keyword); + Space(); + WriteCommaSeparatedList(importsStatement.ImportsClauses); + NewLine(); + + return EndNode(importsStatement); } - public object VisitMembersImportsClause(MemberImportsClause membersImportsClause, object data) + public object VisitMemberImportsClause(MemberImportsClause memberImportsClause, object data) { - throw new NotImplementedException(); + StartNode(memberImportsClause); + memberImportsClause.Member.AcceptVisitor(this, data); + return EndNode(memberImportsClause); } public object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) { - throw new NotImplementedException(); + StartNode(namespaceDeclaration); + NewLine(); + WriteKeyword("Namespace"); + bool isFirst = true; + foreach (Identifier node in namespaceDeclaration.Identifiers) { + if (isFirst) { + isFirst = false; + } else { + WriteToken(".", NamespaceDeclaration.Roles.Dot); + } + node.AcceptVisitor(this, null); + } + NewLine(); + WriteMembers(namespaceDeclaration.Members); + WriteKeyword("End"); + WriteKeyword("Namespace"); + NewLine(); + return EndNode(namespaceDeclaration); } public object VisitOptionStatement(OptionStatement optionStatement, object data) @@ -111,7 +233,62 @@ namespace ICSharpCode.NRefactory.VB public object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) { - throw new NotImplementedException(); + StartNode(typeDeclaration); + WriteAttributes(typeDeclaration.Attributes); + WriteModifiers(typeDeclaration.ModifierTokens); + WriteClassTypeKeyword(typeDeclaration); + WriteIdentifier(typeDeclaration.Name.Name); + MarkFoldStart(); + NewLine(); + + if (!typeDeclaration.InheritsType.IsNull) { + Indent(); + WriteKeyword("Inherits"); + typeDeclaration.InheritsType.AcceptVisitor(this, data); + Unindent(); + NewLine(); + } + if (typeDeclaration.ImplementsTypes.Any()) { + Indent(); + WriteImplementsClause(typeDeclaration.ImplementsTypes); + Unindent(); + NewLine(); + } + + if (!typeDeclaration.InheritsType.IsNull || typeDeclaration.ImplementsTypes.Any()) + NewLine(); + + WriteMembers(typeDeclaration.Members); + + WriteKeyword("End"); + WriteClassTypeKeyword(typeDeclaration); + MarkFoldEnd(); + NewLine(); + return EndNode(typeDeclaration); + } + + void WriteClassTypeKeyword(TypeDeclaration typeDeclaration) + { + switch (typeDeclaration.ClassType) { + case ICSharpCode.NRefactory.TypeSystem.ClassType.Class: + WriteKeyword("Class"); + break; + case ICSharpCode.NRefactory.TypeSystem.ClassType.Enum: + break; + case ICSharpCode.NRefactory.TypeSystem.ClassType.Interface: + WriteKeyword("Interface"); + break; + case ICSharpCode.NRefactory.TypeSystem.ClassType.Struct: + WriteKeyword("Structure"); + break; + case ICSharpCode.NRefactory.TypeSystem.ClassType.Delegate: + break; + case ICSharpCode.NRefactory.TypeSystem.ClassType.Module: + WriteKeyword("Module"); + break; + default: + throw new Exception("Invalid value for ClassType"); + } } public object VisitXmlNamespaceImportsClause(XmlNamespaceImportsClause xmlNamespaceImportsClause, object data) @@ -121,22 +298,83 @@ namespace ICSharpCode.NRefactory.VB public object VisitEnumDeclaration(EnumDeclaration enumDeclaration, object data) { - throw new NotImplementedException(); + StartNode(enumDeclaration); + + WriteAttributes(enumDeclaration.Attributes); + WriteModifiers(enumDeclaration.ModifierTokens); + WriteKeyword("Enum"); + WriteIdentifier(enumDeclaration.Name.Name); + if (!enumDeclaration.UnderlyingType.IsNull) { + Space(); + WriteKeyword("As"); + enumDeclaration.UnderlyingType.AcceptVisitor(this, data); + } + MarkFoldStart(); + NewLine(); + + Indent(); + foreach (var member in enumDeclaration.Members) { + member.AcceptVisitor(this, null); + } + Unindent(); + + WriteKeyword("End"); + WriteKeyword("Enum"); + MarkFoldEnd(); + NewLine(); + + return EndNode(enumDeclaration); } public object VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, object data) { - throw new NotImplementedException(); + StartNode(enumMemberDeclaration); + + WriteAttributes(enumMemberDeclaration.Attributes); + WriteIdentifier(enumMemberDeclaration.Name.Name); + + if (!enumMemberDeclaration.Value.IsNull) { + Space(); + WriteToken("=", EnumMemberDeclaration.Roles.Assign); + Space(); + enumMemberDeclaration.Value.AcceptVisitor(this, data); + } + NewLine(); + + return EndNode(enumMemberDeclaration); } public object VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, object data) { - throw new NotImplementedException(); + StartNode(delegateDeclaration); + + WriteAttributes(delegateDeclaration.Attributes); + WriteModifiers(delegateDeclaration.ModifierTokens); + WriteKeyword("Delegate"); + if (delegateDeclaration.IsSub) + WriteKeyword("Sub"); + else + WriteKeyword("Function"); + WriteIdentifier(delegateDeclaration.Name.Name); + WriteTypeParameters(delegateDeclaration.TypeParameters); + WriteCommaSeparatedListInParenthesis(delegateDeclaration.Parameters, false); + if (!delegateDeclaration.IsSub) { + Space(); + WriteKeyword("As"); + WriteAttributes(delegateDeclaration.ReturnTypeAttributes); + delegateDeclaration.ReturnType.AcceptVisitor(this, data); + } + NewLine(); + + return EndNode(delegateDeclaration); } public object VisitIdentifier(Identifier identifier, object data) { - throw new NotImplementedException(); + StartNode(identifier); + WriteIdentifier(identifier.Name); + WriteTypeCharacter(identifier.TypeCharacter); + return EndNode(identifier); } public object VisitXmlIdentifier(XmlIdentifier xmlIdentifier, object data) @@ -149,41 +387,306 @@ namespace ICSharpCode.NRefactory.VB throw new NotImplementedException(); } - public object VisitSimpleNameExpression(SimpleNameExpression identifierExpression, object data) + public object VisitSimpleNameExpression(SimpleNameExpression simpleNameExpression, object data) { - throw new NotImplementedException(); + StartNode(simpleNameExpression); + + simpleNameExpression.Identifier.AcceptVisitor(this, data); + WriteTypeArguments(simpleNameExpression.TypeArguments); + + return EndNode(simpleNameExpression); } public object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) + { + StartNode(primitiveExpression); + + WritePrimitiveValue(primitiveExpression.Value); + + return EndNode(primitiveExpression); + } + + public object VisitInstanceExpression(InstanceExpression instanceExpression, object data) + { + StartNode(instanceExpression); + + switch (instanceExpression.Type) { + case InstanceExpressionType.Me: + WriteKeyword("Me"); + break; + case InstanceExpressionType.MyBase: + WriteKeyword("MyBase"); + break; + case InstanceExpressionType.MyClass: + WriteKeyword("MyClass"); + break; + default: + throw new Exception("Invalid value for InstanceExpressionType"); + } + + return EndNode(instanceExpression); + } + + public object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data) + { + StartNode(parenthesizedExpression); + + LPar(); + parenthesizedExpression.Expression.AcceptVisitor(this, data); + RPar(); + + return EndNode(parenthesizedExpression); + } + + public object VisitGetTypeExpression(GetTypeExpression getTypeExpression, object data) + { + StartNode(getTypeExpression); + + WriteKeyword("GetType"); + LPar(); + getTypeExpression.Type.AcceptVisitor(this, data); + RPar(); + + return EndNode(getTypeExpression); + } + + public object VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, object data) + { + StartNode(typeOfIsExpression); + + WriteKeyword("TypeOf"); + typeOfIsExpression.TypeOfExpression.AcceptVisitor(this, data); + WriteKeyword("Is"); + typeOfIsExpression.Type.AcceptVisitor(this, data); + + return EndNode(typeOfIsExpression); + } + + public object VisitGetXmlNamespaceExpression(GetXmlNamespaceExpression getXmlNamespaceExpression, object data) { throw new NotImplementedException(); } + public object VisitMemberAccessExpression(MemberAccessExpression memberAccessExpression, object data) + { + StartNode(memberAccessExpression); + + memberAccessExpression.Target.AcceptVisitor(this, data); + WriteToken(".", MemberAccessExpression.Roles.Dot); + memberAccessExpression.MemberName.AcceptVisitor(this, data); + WriteTypeArguments(memberAccessExpression.TypeArguments); + + return EndNode(memberAccessExpression); + } + + public object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data) + { + StartNode(typeReferenceExpression); + + typeReferenceExpression.Type.AcceptVisitor(this, data); + + return EndNode(typeReferenceExpression); + } + + public object VisitEventMemberSpecifier(EventMemberSpecifier eventMemberSpecifier, object data) + { + StartNode(eventMemberSpecifier); + + eventMemberSpecifier.Target.AcceptVisitor(this, data); + WriteToken(".", EventMemberSpecifier.Roles.Dot); + eventMemberSpecifier.Member.AcceptVisitor(this, data); + + return EndNode(eventMemberSpecifier); + } + + public object VisitInterfaceMemberSpecifier(InterfaceMemberSpecifier interfaceMemberSpecifier, object data) + { + StartNode(interfaceMemberSpecifier); + + interfaceMemberSpecifier.Target.AcceptVisitor(this, data); + WriteToken(".", EventMemberSpecifier.Roles.Dot); + interfaceMemberSpecifier.Member.AcceptVisitor(this, data); + + return EndNode(interfaceMemberSpecifier); + } + + #region TypeMembers + public object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data) + { + StartNode(constructorDeclaration); + + WriteAttributes(constructorDeclaration.Attributes); + WriteModifiers(constructorDeclaration.ModifierTokens); + WriteKeyword("Sub"); + WriteKeyword("New"); + WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, false); + MarkFoldStart(); + NewLine(); + + Indent(); + WriteBlock(constructorDeclaration.Body); + Unindent(); + + WriteKeyword("End"); + WriteKeyword("Sub"); + MarkFoldEnd(); + NewLine(); + + return EndNode(constructorDeclaration); + } + + public object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data) + { + StartNode(methodDeclaration); + + WriteAttributes(methodDeclaration.Attributes); + WriteModifiers(methodDeclaration.ModifierTokens); + if (methodDeclaration.IsSub) + WriteKeyword("Sub"); + else + WriteKeyword("Function"); + methodDeclaration.Name.AcceptVisitor(this, data); + WriteTypeParameters(methodDeclaration.TypeParameters); + WriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, false); + if (!methodDeclaration.IsSub && !methodDeclaration.ReturnType.IsNull) { + Space(); + WriteKeyword("As"); + WriteAttributes(methodDeclaration.ReturnTypeAttributes); + methodDeclaration.ReturnType.AcceptVisitor(this, data); + } + WriteHandlesClause(methodDeclaration.HandlesClause); + WriteImplementsClause(methodDeclaration.ImplementsClause); + if (!methodDeclaration.Body.IsNull) { + MarkFoldStart(); + NewLine(); + Indent(); + WriteBlock(methodDeclaration.Body); + Unindent(); + WriteKeyword("End"); + if (methodDeclaration.IsSub) + WriteKeyword("Sub"); + else + WriteKeyword("Function"); + MarkFoldEnd(); + } + NewLine(); + + return EndNode(methodDeclaration); + } + + public object VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data) + { + StartNode(fieldDeclaration); + + WriteAttributes(fieldDeclaration.Attributes); + WriteModifiers(fieldDeclaration.ModifierTokens); + WriteCommaSeparatedList(fieldDeclaration.Variables); + NewLine(); + + return EndNode(fieldDeclaration); + } + + public object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data) + { + StartNode(propertyDeclaration); + + WriteAttributes(propertyDeclaration.Attributes); + WriteModifiers(propertyDeclaration.ModifierTokens); + WriteKeyword("Property"); + WriteIdentifier(propertyDeclaration.Name.Name); + WriteCommaSeparatedListInParenthesis(propertyDeclaration.Parameters, false); + if (!propertyDeclaration.ReturnType.IsNull) { + Space(); + WriteKeyword("As"); + WriteAttributes(propertyDeclaration.ReturnTypeAttributes); + propertyDeclaration.ReturnType.AcceptVisitor(this, data); + } + + bool needsBody = !propertyDeclaration.Getter.Body.IsNull || !propertyDeclaration.Setter.Body.IsNull; + + if (needsBody) { + MarkFoldStart(); + NewLine(); + Indent(); + + if (!propertyDeclaration.Getter.Body.IsNull) { + propertyDeclaration.Getter.AcceptVisitor(this, data); + } + + if (!propertyDeclaration.Setter.Body.IsNull) { + propertyDeclaration.Setter.AcceptVisitor(this, data); + } + Unindent(); + + WriteKeyword("End"); + WriteKeyword("Property"); + MarkFoldEnd(); + } + NewLine(); + + return EndNode(propertyDeclaration); + } + #endregion + + #region TypeName public object VisitPrimitiveType(PrimitiveType primitiveType, object data) { - throw new NotImplementedException(); + StartNode(primitiveType); + + WriteKeyword(primitiveType.Keyword); + + return EndNode(primitiveType); } public object VisitQualifiedType(QualifiedType qualifiedType, object data) { - throw new NotImplementedException(); + StartNode(qualifiedType); + + qualifiedType.Target.AcceptVisitor(this, data); + WriteToken(".", AstNode.Roles.Dot); + WriteIdentifier(qualifiedType.Name); + WriteTypeArguments(qualifiedType.TypeArguments); + + return EndNode(qualifiedType); } public object VisitComposedType(ComposedType composedType, object data) { - throw new NotImplementedException(); + StartNode(composedType); + + composedType.BaseType.AcceptVisitor(this, data); + if (composedType.HasNullableSpecifier) + WriteToken("?", ComposedType.Roles.QuestionMark); + WriteArraySpecifiers(composedType.ArraySpecifiers); + + return EndNode(composedType); } public object VisitArraySpecifier(ArraySpecifier arraySpecifier, object data) { - throw new NotImplementedException(); + StartNode(arraySpecifier); + + LPar(); + for (int i = 0; i < arraySpecifier.Dimensions - 1; i++) { + WriteToken(",", ArraySpecifier.Roles.Comma); + } + RPar(); + + return EndNode(arraySpecifier); } public object VisitSimpleType(SimpleType simpleType, object data) { - throw new NotImplementedException(); + StartNode(simpleType); + + WriteIdentifier(simpleType.Identifier); + WriteTypeArguments(simpleType.TypeArguments); + + return EndNode(simpleType); } + #endregion + #region Pattern Matching public object VisitAnyNode(AnyNode anyNode, object data) { throw new NotImplementedException(); @@ -218,5 +721,1974 @@ namespace ICSharpCode.NRefactory.VB { throw new NotImplementedException(); } + #endregion + + #region StartNode/EndNode + void StartNode(AstNode node) + { + // Ensure that nodes are visited in the proper nested order. + // Jumps to different subtrees are allowed only for the child of a placeholder node. + Debug.Assert(containerStack.Count == 0 || node.Parent == containerStack.Peek()); + if (positionStack.Count > 0) + WriteSpecialsUpToNode(node); + containerStack.Push(node); + positionStack.Push(node.FirstChild); + formatter.StartNode(node); + } + + object EndNode(AstNode node) + { + Debug.Assert(node == containerStack.Peek()); + AstNode pos = positionStack.Pop(); + Debug.Assert(pos == null || pos.Parent == node); + WriteSpecials(pos, null); + containerStack.Pop(); + formatter.EndNode(node); + return null; + } + #endregion + + #region WriteSpecials + /// + /// Writes all specials from start to end (exclusive). Does not touch the positionStack. + /// + void WriteSpecials(AstNode start, AstNode end) + { + for (AstNode pos = start; pos != end; pos = pos.NextSibling) { + if (pos.Role == AstNode.Roles.Comment) { + pos.AcceptVisitor(this, null); + } + } + } + + /// + /// Writes all specials between the current position (in the positionStack) and the next + /// node with the specified role. Advances the current position. + /// + void WriteSpecialsUpToRole(Role role) + { + for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) { + if (pos.Role == role) { + WriteSpecials(positionStack.Pop(), pos); + positionStack.Push(pos); + break; + } + } + } + + /// + /// Writes all specials between the current position (in the positionStack) and the specified node. + /// Advances the current position. + /// + void WriteSpecialsUpToNode(AstNode node) + { + for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) { + if (pos == node) { + WriteSpecials(positionStack.Pop(), pos); + positionStack.Push(pos); + break; + } + } + } + + void WriteSpecialsUpToRole(Role role, AstNode nextNode) + { + // Look for the role between the current position and the nextNode. + for (AstNode pos = positionStack.Peek(); pos != null && pos != nextNode; pos = pos.NextSibling) { + if (pos.Role == AstNode.Roles.Comma) { + WriteSpecials(positionStack.Pop(), pos); + positionStack.Push(pos); + break; + } + } + } + #endregion + + #region Comma + /// + /// Writes a comma. + /// + /// The next node after the comma. + /// When set prevents printing a space after comma. + void Comma(AstNode nextNode, bool noSpaceAfterComma = false) + { + WriteSpecialsUpToRole(AstNode.Roles.Comma, nextNode); + formatter.WriteToken(","); + lastWritten = LastWritten.Other; + Space(!noSpaceAfterComma); // TODO: Comma policy has changed. + } + + void WriteCommaSeparatedList(IEnumerable list) + { + bool isFirst = true; + foreach (AstNode node in list) { + if (isFirst) { + isFirst = false; + } else { + Comma(node); + } + node.AcceptVisitor(this, null); + } + } + + void WriteCommaSeparatedListInParenthesis(IEnumerable list, bool spaceWithin) + { + LPar(); + if (list.Any()) { + Space(spaceWithin); + WriteCommaSeparatedList(list); + Space(spaceWithin); + } + RPar(); + } + + #if DOTNET35 + void WriteCommaSeparatedList(IEnumerable list) + { + WriteCommaSeparatedList(list); + } + + void WriteCommaSeparatedList(IEnumerable list) + { + WriteCommaSeparatedList(list); + } + + void WriteCommaSeparatedListInParenthesis(IEnumerable list, bool spaceWithin) + { + WriteCommaSeparatedListInParenthesis(list.SafeCast(), spaceWithin); + } + + void WriteCommaSeparatedListInParenthesis(IEnumerable list, bool spaceWithin) + { + WriteCommaSeparatedListInParenthesis(list.SafeCast(), spaceWithin); + } + + #endif + + void WriteCommaSeparatedListInBrackets(IEnumerable list, bool spaceWithin) + { + WriteToken("[", AstNode.Roles.LBracket); + if (list.Any()) { + Space(spaceWithin); + WriteCommaSeparatedList(list); + Space(spaceWithin); + } + WriteToken("]", AstNode.Roles.RBracket); + } + + void WriteCommaSeparatedListInBrackets(IEnumerable list) + { + WriteToken ("[", AstNode.Roles.LBracket); + if (list.Any ()) { + Space(); + WriteCommaSeparatedList(list); + Space(); + } + WriteToken ("]", AstNode.Roles.RBracket); + } + #endregion + + #region Write tokens + /// + /// Writes a keyword, and all specials up to + /// + void WriteKeyword(string keyword, Role tokenRole = null) + { + WriteSpecialsUpToRole(tokenRole ?? AstNode.Roles.Keyword); + if (lastWritten == LastWritten.KeywordOrIdentifier) + formatter.Space(); + formatter.WriteKeyword(keyword); + lastWritten = LastWritten.KeywordOrIdentifier; + } + + void WriteIdentifier(string identifier, Role identifierRole = null) + { + WriteSpecialsUpToRole(identifierRole ?? AstNode.Roles.Identifier); + if (IsKeyword(identifier, containerStack.Peek())) { + if (lastWritten == LastWritten.KeywordOrIdentifier) + Space(); // this space is not strictly required, so we call Space() + formatter.WriteToken("["); + } else if (lastWritten == LastWritten.KeywordOrIdentifier) { + formatter.Space(); // this space is strictly required, so we directly call the formatter + } + formatter.WriteIdentifier(identifier); + if (IsKeyword(identifier, containerStack.Peek())) { + formatter.WriteToken("]"); + } + lastWritten = LastWritten.KeywordOrIdentifier; + } + + void WriteToken(string token, Role tokenRole) + { + WriteSpecialsUpToRole(tokenRole); + // Avoid that two +, - or ? tokens are combined into a ++, -- or ?? token. + // Note that we don't need to handle tokens like = because there's no valid + // C# program that contains the single token twice in a row. + // (for +, - and &, this can happen with unary operators; + // for ?, this can happen in "a is int? ? b : c" or "a as int? ?? 0"; + // and for /, this can happen with "1/ *ptr" or "1/ //comment".) +// if (lastWritten == LastWritten.Plus && token[0] == '+' +// || lastWritten == LastWritten.Minus && token[0] == '-' +// || lastWritten == LastWritten.Ampersand && token[0] == '&' +// || lastWritten == LastWritten.QuestionMark && token[0] == '?' +// || lastWritten == LastWritten.Division && token[0] == '*') +// { +// formatter.Space(); +// } + formatter.WriteToken(token); +// if (token == "+") +// lastWritten = LastWritten.Plus; +// else if (token == "-") +// lastWritten = LastWritten.Minus; +// else if (token == "&") +// lastWritten = LastWritten.Ampersand; +// else if (token == "?") +// lastWritten = LastWritten.QuestionMark; +// else if (token == "/") +// lastWritten = LastWritten.Division; +// else + lastWritten = LastWritten.Other; + } + + void WriteTypeCharacter(TypeCode typeCharacter) + { + switch (typeCharacter) { + case TypeCode.Empty: + case TypeCode.Object: + case TypeCode.DBNull: + case TypeCode.Boolean: + case TypeCode.Char: + + break; + case TypeCode.SByte: + + break; + case TypeCode.Byte: + + break; + case TypeCode.Int16: + + break; + case TypeCode.UInt16: + + break; + case TypeCode.Int32: + WriteToken("%", null); + break; + case TypeCode.UInt32: + + break; + case TypeCode.Int64: + WriteToken("&", null); + break; + case TypeCode.UInt64: + + break; + case TypeCode.Single: + WriteToken("!", null); + break; + case TypeCode.Double: + WriteToken("#", null); + break; + case TypeCode.Decimal: + WriteToken("@", null); + break; + case TypeCode.DateTime: + + break; + case TypeCode.String: + WriteToken("$", null); + break; + default: + throw new Exception("Invalid value for TypeCode"); + } + } + + void LPar() + { + WriteToken("(", AstNode.Roles.LPar); + } + + void RPar() + { + WriteToken(")", AstNode.Roles.LPar); + } + + /// + /// Writes a space depending on policy. + /// + void Space(bool addSpace = true) + { + if (addSpace) { + formatter.Space(); + lastWritten = LastWritten.Whitespace; + } + } + + void NewLine() + { + formatter.NewLine(); + lastWritten = LastWritten.Whitespace; + } + + void Indent() + { + formatter.Indent(); + } + + void Unindent() + { + formatter.Unindent(); + } + + void MarkFoldStart() + { + formatter.MarkFoldStart(); + } + + void MarkFoldEnd() + { + formatter.MarkFoldEnd(); + } + #endregion + + #region IsKeyword Test + static readonly HashSet unconditionalKeywords = new HashSet { + "AddHandler", "AddressOf", "Alias", "And", "AndAlso", "As", "Boolean", "ByRef", "Byte", + "ByVal", "Call", "Case", "Catch", "CBool", "CByte", "CChar", "CInt", "Class", "CLng", + "CObj", "Const", "Continue", "CSByte", "CShort", "CSng", "CStr", "CType", "CUInt", + "CULng", "CUShort", "Date", "Decimal", "Declare", "Default", "Delegate", "Dim", + "DirectCast", "Do", "Double", "Each", "Else", "ElseIf", "End", "EndIf", "Enum", "Erase", + "Error", "Event", "Exit", "False", "Finally", "For", "Friend", "Function", "Get", + "GetType", "GetXmlNamespace", "Global", "GoSub", "GoTo", "Handles", "If", "Implements", + "Imports", "In", "Inherits", "Integer", "Interface", "Is", "IsNot", "Let", "Lib", "Like", + "Long", "Loop", "Me", "Mod", "Module", "MustInherit", "MustOverride", "MyBase", "MyClass", + "Namespace", "Narrowing", "New", "Next", "Not", "Nothing", "NotInheritable", "NotOverridable", + "Object", "Of", "On", "Operator", "Option", "Optional", "Or", "OrElse", "Overloads", + "Overridable", "Overrides", "ParamArray", "Partial", "Private", "Property", "Protected", + "Public", "RaiseEvent", "ReadOnly", "ReDim", "REM", "RemoveHandler", "Resume", "Return", + "SByte", "Select", "Set", "Shadows", "Shared", "Short", "Single", "Static", "Step", "Stop", + "String", "Structure", "Sub", "SyncLock", "Then", "Throw", "To", "True", "Try", "TryCast", + "TypeOf", "UInteger", "ULong", "UShort", "Using", "Variant", "Wend", "When", "While", + "Widening", "With", "WithEvents", "WriteOnly", "Xor" + }; + + static readonly HashSet queryKeywords = new HashSet { + + }; + + /// + /// Determines whether the specified identifier is a keyword in the given context. + /// + public static bool IsKeyword(string identifier, AstNode context) + { + if (unconditionalKeywords.Contains(identifier)) + return true; +// if (context.Ancestors.Any(a => a is QueryExpression)) { +// if (queryKeywords.Contains(identifier)) +// return true; +// } + return false; + } + #endregion + + #region Write constructs + void WriteTypeArguments(IEnumerable typeArguments) + { + if (typeArguments.Any()) { + LPar(); + WriteKeyword("Of"); + WriteCommaSeparatedList(typeArguments); + RPar(); + } + } + + void WriteTypeParameters(IEnumerable typeParameters) + { + if (typeParameters.Any()) { + LPar(); + WriteKeyword("Of"); + WriteCommaSeparatedList(typeParameters); + RPar(); + } + } + + void WriteModifiers(IEnumerable modifierTokens) + { + foreach (VBModifierToken modifier in modifierTokens) { + modifier.AcceptVisitor(this, null); + } + } + + void WriteArraySpecifiers(IEnumerable arraySpecifiers) + { + foreach (ArraySpecifier specifier in arraySpecifiers) { + specifier.AcceptVisitor(this, null); + } + } + + void WriteQualifiedIdentifier(IEnumerable identifiers) + { + bool first = true; + foreach (Identifier ident in identifiers) { + if (first) { + first = false; + if (lastWritten == LastWritten.KeywordOrIdentifier) + formatter.Space(); + } else { + WriteSpecialsUpToRole(AstNode.Roles.Dot, ident); + formatter.WriteToken("."); + lastWritten = LastWritten.Other; + } + WriteSpecialsUpToNode(ident); + formatter.WriteIdentifier(ident.Name); + lastWritten = LastWritten.KeywordOrIdentifier; + } + } + + void WriteEmbeddedStatement(Statement embeddedStatement) + { + if (embeddedStatement.IsNull) + return; + BlockStatement block = embeddedStatement as BlockStatement; + if (block != null) + VisitBlockStatement(block, null); + else + embeddedStatement.AcceptVisitor(this, null); + } + + void WriteBlock(BlockStatement body) + { + if (body.IsNull) + NewLine(); + else + VisitBlockStatement(body, null); + } + + void WriteMembers(IEnumerable members) + { + Indent(); + bool isFirst = true; + foreach (var member in members) { + if (isFirst) { + isFirst = false; + } else { + NewLine(); + } + member.AcceptVisitor(this, null); + } + Unindent(); + } + + void WriteAttributes(IEnumerable attributes) + { + foreach (AttributeBlock attr in attributes) { + attr.AcceptVisitor(this, null); + } + } + + void WritePrivateImplementationType(AstType privateImplementationType) + { + if (!privateImplementationType.IsNull) { + privateImplementationType.AcceptVisitor(this, null); + WriteToken(".", AstNode.Roles.Dot); + } + } + + void WriteImplementsClause(AstNodeCollection implementsClause) + { + if (implementsClause.Any()) { + Space(); + WriteKeyword("Implements"); + WriteCommaSeparatedList(implementsClause); + } + } + + void WriteImplementsClause(AstNodeCollection implementsClause) + { + if (implementsClause.Any()) { + WriteKeyword("Implements"); + WriteCommaSeparatedList(implementsClause); + } + } + + void WriteHandlesClause(AstNodeCollection handlesClause) + { + if (handlesClause.Any()) { + Space(); + WriteKeyword("Handles"); + WriteCommaSeparatedList(handlesClause); + } + } + + void WritePrimitiveValue(object val) + { + if (val == null) { + WriteKeyword("Nothing"); + return; + } + + if (val is bool) { + if ((bool)val) { + WriteKeyword("True"); + } else { + WriteKeyword("False"); + } + return; + } + + if (val is string) { + formatter.WriteToken("\"" + ConvertString(val.ToString()) + "\""); + lastWritten = LastWritten.Other; + } else if (val is char) { + formatter.WriteToken("\"" + ConvertCharLiteral((char)val) + "\"c"); + lastWritten = LastWritten.Other; + } else if (val is decimal) { + formatter.WriteToken(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "D"); + lastWritten = LastWritten.Other; + } else if (val is float) { + float f = (float)val; + if (float.IsInfinity(f) || float.IsNaN(f)) { + // Strictly speaking, these aren't PrimitiveExpressions; + // but we still support writing these to make life easier for code generators. + WriteKeyword("Single"); + WriteToken(".", AstNode.Roles.Dot); + if (float.IsPositiveInfinity(f)) + WriteIdentifier("PositiveInfinity"); + else if (float.IsNegativeInfinity(f)) + WriteIdentifier("NegativeInfinity"); + else + WriteIdentifier("NaN"); + return; + } + formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "F"); + lastWritten = LastWritten.Other; + } else if (val is double) { + double f = (double)val; + if (double.IsInfinity(f) || double.IsNaN(f)) { + // Strictly speaking, these aren't PrimitiveExpressions; + // but we still support writing these to make life easier for code generators. + WriteKeyword("Double"); + WriteToken(".", AstNode.Roles.Dot); + if (double.IsPositiveInfinity(f)) + WriteIdentifier("PositiveInfinity"); + else if (double.IsNegativeInfinity(f)) + WriteIdentifier("NegativeInfinity"); + else + WriteIdentifier("NaN"); + return; + } + string number = f.ToString("R", NumberFormatInfo.InvariantInfo); + if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0) + number += ".0"; + formatter.WriteToken(number); + // needs space if identifier follows number; this avoids mistaking the following identifier as type suffix + lastWritten = LastWritten.KeywordOrIdentifier; + } else if (val is IFormattable) { + StringBuilder b = new StringBuilder(); +// if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) { +// b.Append("0x"); +// b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo)); +// } else { + b.Append(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo)); +// } + if (val is uint || val is ulong) { + b.Append("U"); + } + if (val is long || val is ulong) { + b.Append("L"); + } + formatter.WriteToken(b.ToString()); + // needs space if identifier follows number; this avoids mistaking the following identifier as type suffix + lastWritten = LastWritten.KeywordOrIdentifier; + } else { + formatter.WriteToken(val.ToString()); + lastWritten = LastWritten.Other; + } + } + #endregion + + #region ConvertLiteral + static string ConvertCharLiteral(char ch) + { + if (ch == '"') return "\"\""; + return ch.ToString(); + } + + static string ConvertString(string str) + { + StringBuilder sb = new StringBuilder(); + foreach (char ch in str) { + sb.Append(ConvertCharLiteral(ch)); + } + return sb.ToString(); + } + #endregion + + public object VisitVariableIdentifier(VariableIdentifier variableIdentifier, object data) + { + StartNode(variableIdentifier); + + WriteIdentifier(variableIdentifier.Name.Name); + if (variableIdentifier.HasNullableSpecifier) + WriteToken("?", VariableIdentifier.Roles.QuestionMark); + WriteArraySpecifiers(variableIdentifier.ArraySpecifiers); + + return EndNode(variableIdentifier); + } + + public object VisitAccessor(Accessor accessor, object data) + { + StartNode(accessor); + WriteAttributes(accessor.Attributes); + WriteModifiers(accessor.ModifierTokens); + if (accessor.Role == PropertyDeclaration.GetterRole) { + WriteKeyword("Get"); + } else if (accessor.Role == PropertyDeclaration.SetterRole) { + WriteKeyword("Set"); + } else if (accessor.Role == EventDeclaration.AddHandlerRole) { + WriteKeyword("AddHandler"); + } else if (accessor.Role == EventDeclaration.RemoveHandlerRole) { + WriteKeyword("RemoveHandler"); + } else if (accessor.Role == EventDeclaration.RaiseEventRole) { + WriteKeyword("RaiseEvent"); + } + if (accessor.Parameters.Any()) + WriteCommaSeparatedListInParenthesis(accessor.Parameters, false); + NewLine(); + Indent(); + WriteBlock(accessor.Body); + Unindent(); + WriteKeyword("End"); + + if (accessor.Role == PropertyDeclaration.GetterRole) { + WriteKeyword("Get"); + } else if (accessor.Role == PropertyDeclaration.SetterRole) { + WriteKeyword("Set"); + } else if (accessor.Role == EventDeclaration.AddHandlerRole) { + WriteKeyword("AddHandler"); + } else if (accessor.Role == EventDeclaration.RemoveHandlerRole) { + WriteKeyword("RemoveHandler"); + } else if (accessor.Role == EventDeclaration.RaiseEventRole) { + WriteKeyword("RaiseEvent"); + } + NewLine(); + + return EndNode(accessor); + } + + + public object VisitLabelDeclarationStatement(LabelDeclarationStatement labelDeclarationStatement, object data) + { + StartNode(labelDeclarationStatement); + + labelDeclarationStatement.Label.AcceptVisitor(this, data); + WriteToken(":", LabelDeclarationStatement.Roles.Colon); + + return EndNode(labelDeclarationStatement); + } + + public object VisitLocalDeclarationStatement(LocalDeclarationStatement localDeclarationStatement, object data) + { + StartNode(localDeclarationStatement); + + if (localDeclarationStatement.ModifierToken != null && !localDeclarationStatement.ModifierToken.IsNull) + WriteModifiers(new [] { localDeclarationStatement.ModifierToken }); + WriteCommaSeparatedList(localDeclarationStatement.Variables); + + return EndNode(localDeclarationStatement); + } + + public object VisitWithStatement(WithStatement withStatement, object data) + { + 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) + { + 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) + { + StartNode(tryStatement); + WriteKeyword("Try"); + NewLine(); + Indent(); + tryStatement.Body.AcceptVisitor(this, data); + Unindent(); + foreach (var clause in tryStatement.CatchBlocks) { + clause.AcceptVisitor(this, data); + } + if (!tryStatement.FinallyBlock.IsNull) { + WriteKeyword("Finally"); + NewLine(); + Indent(); + tryStatement.FinallyBlock.AcceptVisitor(this, data); + Unindent(); + } + WriteKeyword("End"); + WriteKeyword("Try"); + return EndNode(tryStatement); + } + + public object VisitCatchBlock(CatchBlock catchBlock, object data) + { + StartNode(catchBlock); + WriteKeyword("Catch"); + catchBlock.ExceptionVariable.AcceptVisitor(this, data); + if (!catchBlock.ExceptionType.IsNull) { + WriteKeyword("As"); + catchBlock.ExceptionType.AcceptVisitor(this, data); + } + NewLine(); + Indent(); + foreach (var stmt in catchBlock) { + stmt.AcceptVisitor(this, data); + NewLine(); + } + Unindent(); + return EndNode(catchBlock); + } + + public object VisitExpressionStatement(ExpressionStatement expressionStatement, object data) + { + StartNode(expressionStatement); + expressionStatement.Expression.AcceptVisitor(this, data); + return EndNode(expressionStatement); + } + + public object VisitThrowStatement(ThrowStatement throwStatement, object data) + { + StartNode(throwStatement); + + WriteKeyword("Throw"); + throwStatement.Expression.AcceptVisitor(this, data); + + return EndNode(throwStatement); + } + + public object VisitIfElseStatement(IfElseStatement ifElseStatement, object data) + { + StartNode(ifElseStatement); + WriteKeyword("If"); + ifElseStatement.Condition.AcceptVisitor(this, data); + Space(); + WriteKeyword("Then"); + NewLine(); + Indent(); + ifElseStatement.Body.AcceptVisitor(this, data); + Unindent(); + if (!ifElseStatement.ElseBlock.IsNull) { + WriteKeyword("Else"); + NewLine(); + Indent(); + ifElseStatement.ElseBlock.AcceptVisitor(this, data); + Unindent(); + } + WriteKeyword("End"); + WriteKeyword("If"); + return EndNode(ifElseStatement); + } + + public object VisitReturnStatement(ReturnStatement returnStatement, object data) + { + StartNode(returnStatement); + WriteKeyword("Return"); + returnStatement.Expression.AcceptVisitor(this, data); + return EndNode(returnStatement); + } + + public object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) + { + StartNode(binaryOperatorExpression); + binaryOperatorExpression.Left.AcceptVisitor(this, data); + Space(); + switch (binaryOperatorExpression.Operator) { + case BinaryOperatorType.BitwiseAnd: + WriteKeyword("And"); + break; + case BinaryOperatorType.BitwiseOr: + WriteKeyword("Or"); + break; + case BinaryOperatorType.LogicalAnd: + WriteKeyword("AndAlso"); + break; + case BinaryOperatorType.LogicalOr: + WriteKeyword("OrElse"); + break; + case BinaryOperatorType.ExclusiveOr: + WriteKeyword("Xor"); + break; + case BinaryOperatorType.GreaterThan: + WriteToken(">", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.GreaterThanOrEqual: + WriteToken(">=", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Equality: + WriteToken("=", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.InEquality: + WriteToken("<>", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.LessThan: + WriteToken("<", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.LessThanOrEqual: + WriteToken("<=", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Add: + WriteToken("+", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Subtract: + WriteToken("-", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Multiply: + WriteToken("*", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Divide: + WriteToken("/", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Modulus: + WriteKeyword("Mod"); + break; + case BinaryOperatorType.DivideInteger: + WriteToken("\\", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Power: + WriteToken("*", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.Concat: + WriteToken("&", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.ShiftLeft: + WriteToken("<<", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.ShiftRight: + WriteToken(">>", BinaryOperatorExpression.OperatorRole); + break; + case BinaryOperatorType.ReferenceEquality: + WriteKeyword("Is"); + break; + case BinaryOperatorType.ReferenceInequality: + WriteKeyword("IsNot"); + break; + case BinaryOperatorType.Like: + WriteKeyword("Like"); + break; + case BinaryOperatorType.DictionaryAccess: + WriteToken("!", BinaryOperatorExpression.OperatorRole); + break; + default: + throw new Exception("Invalid value for BinaryOperatorType: " + binaryOperatorExpression.Operator); + } + Space(); + binaryOperatorExpression.Right.AcceptVisitor(this, data); + return EndNode(binaryOperatorExpression); + } + + public object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) + { + StartNode(identifierExpression); + identifierExpression.Identifier.AcceptVisitor(this, data); + WriteTypeArguments(identifierExpression.TypeArguments); + return EndNode(identifierExpression); + } + + public object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) + { + StartNode(assignmentExpression); + assignmentExpression.Left.AcceptVisitor(this, data); + Space(); + switch (assignmentExpression.Operator) { + case AssignmentOperatorType.Assign: + WriteToken("=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.Add: + WriteToken("+=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.Subtract: + WriteToken("-=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.Multiply: + WriteToken("*=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.Divide: + WriteToken("/=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.Power: + WriteToken("^=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.DivideInteger: + WriteToken("\\=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.ConcatString: + WriteToken("&=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.ShiftLeft: + WriteToken("<<=", AssignmentExpression.OperatorRole); + break; + case AssignmentOperatorType.ShiftRight: + WriteToken(">>=", AssignmentExpression.OperatorRole); + break; + default: + throw new Exception("Invalid value for AssignmentOperatorType: " + assignmentExpression.Operator); + } + Space(); + assignmentExpression.Right.AcceptVisitor(this, data); + return EndNode(assignmentExpression); + } + + public object VisitInvocationExpression(InvocationExpression invocationExpression, object data) + { + StartNode(invocationExpression); + invocationExpression.Target.AcceptVisitor(this, data); + WriteCommaSeparatedListInParenthesis(invocationExpression.Arguments, false); + return EndNode(invocationExpression); + } + + public object VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data) + { + StartNode(arrayInitializerExpression); + WriteToken("{", ArrayInitializerExpression.Roles.LBrace); + Space(); + WriteCommaSeparatedList(arrayInitializerExpression.Elements); + Space(); + WriteToken("}", ArrayInitializerExpression.Roles.RBrace); + return EndNode(arrayInitializerExpression); + } + + public object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data) + { + StartNode(arrayCreateExpression); + WriteKeyword("New"); + Space(); + arrayCreateExpression.Type.AcceptVisitor(this, data); + WriteCommaSeparatedListInParenthesis(arrayCreateExpression.Arguments, false); + foreach (var specifier in arrayCreateExpression.AdditionalArraySpecifiers) { + specifier.AcceptVisitor(this, data); + } + if (!arrayCreateExpression.Initializer.IsNull) { + Space(); + WriteToken("=", ArrayCreateExpression.Roles.Assign); + Space(); + arrayCreateExpression.Initializer.AcceptVisitor(this, data); + } + return EndNode(arrayCreateExpression); + } + + public object VisitObjectCreationExpression(ObjectCreationExpression objectCreationExpression, object data) + { + StartNode(objectCreationExpression); + + WriteKeyword("New"); + objectCreationExpression.Type.AcceptVisitor(this, data); + WriteCommaSeparatedListInParenthesis(objectCreationExpression.Arguments, false); + if (!objectCreationExpression.Initializer.IsNull) { + Space(); + objectCreationExpression.Initializer.AcceptVisitor(this, data); + } + + return EndNode(objectCreationExpression); + } + + public object VisitCastExpression(CastExpression castExpression, object data) + { + StartNode(castExpression); + + switch (castExpression.CastType) { + case CastType.DirectCast: + WriteKeyword("DirectCast"); + break; + case CastType.TryCast: + WriteKeyword("TryCast"); + break; + case CastType.CType: + WriteKeyword("CType"); + break; + case CastType.CBool: + WriteKeyword("CBool"); + break; + case CastType.CByte: + WriteKeyword("CByte"); + break; + case CastType.CChar: + WriteKeyword("CChar"); + break; + case CastType.CDate: + WriteKeyword("CDate"); + break; + case CastType.CDec: + WriteKeyword("CType"); + break; + case CastType.CDbl: + WriteKeyword("CDec"); + break; + case CastType.CInt: + WriteKeyword("CInt"); + break; + case CastType.CLng: + WriteKeyword("CLng"); + break; + case CastType.CObj: + WriteKeyword("CObj"); + break; + case CastType.CSByte: + WriteKeyword("CSByte"); + break; + case CastType.CShort: + WriteKeyword("CShort"); + break; + case CastType.CSng: + WriteKeyword("CSng"); + break; + case CastType.CStr: + WriteKeyword("CStr"); + break; + case CastType.CUInt: + WriteKeyword("CUInt"); + break; + case CastType.CULng: + WriteKeyword("CULng"); + break; + case CastType.CUShort: + WriteKeyword("CUShort"); + break; + default: + throw new Exception("Invalid value for CastType"); + } + + WriteToken("(", CastExpression.Roles.LPar); + castExpression.Expression.AcceptVisitor(this, data); + + if (castExpression.CastType == CastType.CType || + castExpression.CastType == CastType.DirectCast || + castExpression.CastType == CastType.TryCast) { + WriteToken(",", CastExpression.Roles.Comma); + Space(); + castExpression.Type.AcceptVisitor(this, data); + } + + WriteToken(")", CastExpression.Roles.RPar); + + return EndNode(castExpression); + } + + public object VisitComment(Comment comment, object data) + { + formatter.WriteComment(comment.IsDocumentationComment, comment.Content); + return null; + } + + public object VisitEventDeclaration(EventDeclaration eventDeclaration, object data) + { + StartNode(eventDeclaration); + + WriteAttributes(eventDeclaration.Attributes); + WriteModifiers(eventDeclaration.ModifierTokens); + if (eventDeclaration.IsCustom) + WriteKeyword("Custom"); + WriteKeyword("Event"); + WriteIdentifier(eventDeclaration.Name.Name); + if (!eventDeclaration.IsCustom && eventDeclaration.ReturnType.IsNull) + WriteCommaSeparatedListInParenthesis(eventDeclaration.Parameters, false); + if (!eventDeclaration.ReturnType.IsNull) { + Space(); + WriteKeyword("As"); + eventDeclaration.ReturnType.AcceptVisitor(this, data); + } + WriteImplementsClause(eventDeclaration.ImplementsClause); + + if (eventDeclaration.IsCustom) { + MarkFoldStart(); + NewLine(); + Indent(); + + eventDeclaration.AddHandlerBlock.AcceptVisitor(this, data); + eventDeclaration.RemoveHandlerBlock.AcceptVisitor(this, data); + eventDeclaration.RaiseEventBlock.AcceptVisitor(this, data); + + Unindent(); + WriteKeyword("End"); + WriteKeyword("Event"); + MarkFoldEnd(); + } + NewLine(); + + return EndNode(eventDeclaration); + } + + public object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data) + { + StartNode(unaryOperatorExpression); + + switch (unaryOperatorExpression.Operator) { + case UnaryOperatorType.Not: + WriteKeyword("Not"); + break; + case UnaryOperatorType.Minus: + WriteToken("-", UnaryOperatorExpression.OperatorRole); + break; + case UnaryOperatorType.Plus: + WriteToken("+", UnaryOperatorExpression.OperatorRole); + break; + case UnaryOperatorType.AddressOf: + WriteKeyword("AddressOf"); + break; + case UnaryOperatorType.Await: + WriteKeyword("Await"); + break; + default: + throw new Exception("Invalid value for UnaryOperatorType"); + } + + unaryOperatorExpression.Expression.AcceptVisitor(this, data); + + return EndNode(unaryOperatorExpression); + } + + public object VisitFieldInitializerExpression(FieldInitializerExpression fieldInitializerExpression, object data) + { + StartNode(fieldInitializerExpression); + + if (fieldInitializerExpression.IsKey) { + WriteKeyword("Key"); + Space(); + } + + WriteToken(".", FieldInitializerExpression.Roles.Dot); + fieldInitializerExpression.Identifier.AcceptVisitor(this, data); + + Space(); + WriteToken("=", FieldInitializerExpression.Roles.Assign); + Space(); + fieldInitializerExpression.Expression.AcceptVisitor(this, data); + + return EndNode(fieldInitializerExpression); + } + + public object VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, object data) + { + throw new NotImplementedException(); + } + + public object VisitConditionalExpression(ConditionalExpression conditionalExpression, object data) + { + StartNode(conditionalExpression); + + WriteKeyword("If"); + WriteToken("(", ConditionalExpression.Roles.LPar); + + conditionalExpression.ConditionExpression.AcceptVisitor(this, data); + WriteToken(",", ConditionalExpression.Roles.Comma); + Space(); + + if (!conditionalExpression.TrueExpression.IsNull) { + conditionalExpression.TrueExpression.AcceptVisitor(this, data); + WriteToken(",", ConditionalExpression.Roles.Comma); + Space(); + } + + conditionalExpression.FalseExpression.AcceptVisitor(this, data); + + WriteToken(")", ConditionalExpression.Roles.RPar); + + return EndNode(conditionalExpression); + } + + public object VisitWhileStatement(WhileStatement whileStatement, object data) + { + StartNode(whileStatement); + + WriteKeyword("While"); + Space(); + whileStatement.Condition.AcceptVisitor(this, data); + NewLine(); + Indent(); + whileStatement.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("End"); + WriteKeyword("While"); + + 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); + + WriteKeyword("For"); + forStatement.Variable.AcceptVisitor(this, data); + WriteKeyword("To"); + forStatement.ToExpression.AcceptVisitor(this, data); + if (!forStatement.StepExpression.IsNull) { + WriteKeyword("Step"); + Space(); + forStatement.StepExpression.AcceptVisitor(this, data); + } + NewLine(); + Indent(); + forStatement.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("Next"); + + return EndNode(forStatement); + } + + public object VisitForEachStatement(ForEachStatement forEachStatement, object data) + { + StartNode(forEachStatement); + + WriteKeyword("For"); + WriteKeyword("Each"); + forEachStatement.Variable.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) { + MarkFoldStart(); + NewLine(); + Indent(); + WriteBlock(operatorDeclaration.Body); + Unindent(); + WriteKeyword("End"); + WriteKeyword("Operator"); + MarkFoldEnd(); + } + NewLine(); + + return EndNode(operatorDeclaration); + } + + public object VisitSelectStatement(SelectStatement selectStatement, object data) + { + StartNode(selectStatement); + + WriteKeyword("Select"); + WriteKeyword("Case"); + selectStatement.Expression.AcceptVisitor(this, data); + NewLine(); + Indent(); + + foreach (CaseStatement stmt in selectStatement.Cases) { + stmt.AcceptVisitor(this, data); + } + + Unindent(); + WriteKeyword("End"); + WriteKeyword("Select"); + + return EndNode(selectStatement); + } + + public object VisitCaseStatement(CaseStatement caseStatement, object data) + { + StartNode(caseStatement); + + WriteKeyword("Case"); + if (caseStatement.Clauses.Count == 1 && caseStatement.Clauses.First().Expression.IsNull) + WriteKeyword("Else"); + else { + Space(); + WriteCommaSeparatedList(caseStatement.Clauses); + } + NewLine(); + Indent(); + caseStatement.Body.AcceptVisitor(this, data); + Unindent(); + + return EndNode(caseStatement); + } + + public object VisitSimpleCaseClause(SimpleCaseClause simpleCaseClause, object data) + { + StartNode(simpleCaseClause); + simpleCaseClause.Expression.AcceptVisitor(this, data); + return EndNode(simpleCaseClause); + } + + public object VisitRangeCaseClause(RangeCaseClause rangeCaseClause, object data) + { + StartNode(rangeCaseClause); + rangeCaseClause.Expression.AcceptVisitor(this, data); + WriteKeyword("To"); + rangeCaseClause.ToExpression.AcceptVisitor(this, data); + return EndNode(rangeCaseClause); + } + + public object VisitComparisonCaseClause(ComparisonCaseClause comparisonCaseClause, object data) + { + StartNode(comparisonCaseClause); + switch (comparisonCaseClause.Operator) { + case ComparisonOperator.Equality: + WriteToken("=", ComparisonCaseClause.OperatorRole); + break; + case ComparisonOperator.InEquality: + WriteToken("<>", ComparisonCaseClause.OperatorRole); + break; + case ComparisonOperator.LessThan: + WriteToken("<", ComparisonCaseClause.OperatorRole); + break; + case ComparisonOperator.GreaterThan: + WriteToken(">", ComparisonCaseClause.OperatorRole); + break; + case ComparisonOperator.LessThanOrEqual: + WriteToken("<=", ComparisonCaseClause.OperatorRole); + break; + case ComparisonOperator.GreaterThanOrEqual: + WriteToken(">=", ComparisonCaseClause.OperatorRole); + break; + default: + throw new Exception("Invalid value for ComparisonOperator"); + } + Space(); + comparisonCaseClause.Expression.AcceptVisitor(this, data); + return EndNode(comparisonCaseClause); + } + + + public object VisitYieldStatement(YieldStatement yieldStatement, object data) + { + StartNode(yieldStatement); + WriteKeyword("Yield"); + yieldStatement.Expression.AcceptVisitor(this, data); + return EndNode(yieldStatement); + } + + public object VisitVariableInitializer(VariableInitializer variableInitializer, object data) + { + StartNode(variableInitializer); + + variableInitializer.Identifier.AcceptVisitor(this, data); + if (!variableInitializer.Type.IsNull) { + WriteKeyword("As"); + variableInitializer.Type.AcceptVisitor(this, data); + } + if (!variableInitializer.Expression.IsNull) { + Space(); + WriteToken("=", VariableInitializer.Roles.Assign); + Space(); + variableInitializer.Expression.AcceptVisitor(this, data); + } + + return EndNode(variableInitializer); + } + + public object VisitVariableDeclaratorWithTypeAndInitializer(VariableDeclaratorWithTypeAndInitializer variableDeclaratorWithTypeAndInitializer, object data) + { + StartNode(variableDeclaratorWithTypeAndInitializer); + + WriteCommaSeparatedList(variableDeclaratorWithTypeAndInitializer.Identifiers); + WriteKeyword("As"); + variableDeclaratorWithTypeAndInitializer.Type.AcceptVisitor(this, data); + if (!variableDeclaratorWithTypeAndInitializer.Initializer.IsNull) { + Space(); + WriteToken("=", VariableDeclarator.Roles.Assign); + Space(); + variableDeclaratorWithTypeAndInitializer.Initializer.AcceptVisitor(this, data); + } + + return EndNode(variableDeclaratorWithTypeAndInitializer); + } + + public object VisitVariableDeclaratorWithObjectCreation(VariableDeclaratorWithObjectCreation variableDeclaratorWithObjectCreation, object data) + { + StartNode(variableDeclaratorWithObjectCreation); + + WriteCommaSeparatedList(variableDeclaratorWithObjectCreation.Identifiers); + WriteKeyword("As"); + variableDeclaratorWithObjectCreation.Initializer.AcceptVisitor(this, data); + + return EndNode(variableDeclaratorWithObjectCreation); + } + + public object VisitDoLoopStatement(DoLoopStatement doLoopStatement, object data) + { + StartNode(doLoopStatement); + + WriteKeyword("Do"); + if (doLoopStatement.ConditionType == ConditionType.DoUntil) { + WriteKeyword("Until"); + doLoopStatement.Expression.AcceptVisitor(this, data); + } + if (doLoopStatement.ConditionType == ConditionType.DoWhile) { + WriteKeyword("While"); + doLoopStatement.Expression.AcceptVisitor(this, data); + } + NewLine(); + Indent(); + doLoopStatement.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("Loop"); + if (doLoopStatement.ConditionType == ConditionType.LoopUntil) { + WriteKeyword("Until"); + doLoopStatement.Expression.AcceptVisitor(this, data); + } + if (doLoopStatement.ConditionType == ConditionType.LoopWhile) { + WriteKeyword("While"); + doLoopStatement.Expression.AcceptVisitor(this, data); + } + + return EndNode(doLoopStatement); + } + + public object VisitUsingStatement(UsingStatement usingStatement, object data) + { + StartNode(usingStatement); + + WriteKeyword("Using"); + WriteCommaSeparatedList(usingStatement.Resources); + NewLine(); + Indent(); + usingStatement.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("End"); + WriteKeyword("Using"); + + return EndNode(usingStatement); + } + + public object VisitGoToStatement(GoToStatement goToStatement, object data) + { + StartNode(goToStatement); + + WriteKeyword("GoTo"); + goToStatement.Label.AcceptVisitor(this, data); + + return EndNode(goToStatement); + } + + public object VisitSingleLineSubLambdaExpression(SingleLineSubLambdaExpression singleLineSubLambdaExpression, object data) + { + StartNode(singleLineSubLambdaExpression); + + WriteModifiers(singleLineSubLambdaExpression.ModifierTokens); + WriteKeyword("Sub"); + WriteCommaSeparatedListInParenthesis(singleLineSubLambdaExpression.Parameters, false); + Space(); + singleLineSubLambdaExpression.EmbeddedStatement.AcceptVisitor(this, data); + + return EndNode(singleLineSubLambdaExpression); + } + + public object VisitSingleLineFunctionLambdaExpression(SingleLineFunctionLambdaExpression singleLineFunctionLambdaExpression, object data) + { + StartNode(singleLineFunctionLambdaExpression); + + WriteModifiers(singleLineFunctionLambdaExpression.ModifierTokens); + WriteKeyword("Function"); + WriteCommaSeparatedListInParenthesis(singleLineFunctionLambdaExpression.Parameters, false); + Space(); + singleLineFunctionLambdaExpression.EmbeddedExpression.AcceptVisitor(this, data); + + return EndNode(singleLineFunctionLambdaExpression); + } + + public object VisitMultiLineLambdaExpression(MultiLineLambdaExpression multiLineLambdaExpression, object data) + { + StartNode(multiLineLambdaExpression); + + WriteModifiers(multiLineLambdaExpression.ModifierTokens); + if (multiLineLambdaExpression.IsSub) + WriteKeyword("Sub"); + else + WriteKeyword("Function"); + WriteCommaSeparatedListInParenthesis(multiLineLambdaExpression.Parameters, false); + NewLine(); + Indent(); + multiLineLambdaExpression.Body.AcceptVisitor(this, data); + Unindent(); + WriteKeyword("End"); + if (multiLineLambdaExpression.IsSub) + WriteKeyword("Sub"); + else + WriteKeyword("Function"); + + return EndNode(multiLineLambdaExpression); + } + + public object VisitQueryExpression(QueryExpression queryExpression, object data) + { + StartNode(queryExpression); + + foreach (var op in queryExpression.QueryOperators) { + op.AcceptVisitor(this, data); + } + + return EndNode(queryExpression); + } + + public object VisitContinueStatement(ContinueStatement continueStatement, object data) + { + StartNode(continueStatement); + + WriteKeyword("Continue"); + + switch (continueStatement.ContinueKind) { + case ContinueKind.Do: + WriteKeyword("Do"); + break; + case ContinueKind.For: + WriteKeyword("For"); + break; + case ContinueKind.While: + WriteKeyword("While"); + break; + default: + throw new Exception("Invalid value for ContinueKind"); + } + + return EndNode(continueStatement); + } + + public object VisitExternalMethodDeclaration(ExternalMethodDeclaration externalMethodDeclaration, object data) + { + StartNode(externalMethodDeclaration); + + WriteAttributes(externalMethodDeclaration.Attributes); + WriteModifiers(externalMethodDeclaration.ModifierTokens); + WriteKeyword("Declare"); + switch (externalMethodDeclaration.CharsetModifier) { + case CharsetModifier.None: + break; + case CharsetModifier.Auto: + WriteKeyword("Auto"); + break; + case CharsetModifier.Unicode: + WriteKeyword("Unicode"); + break; + case CharsetModifier.Ansi: + WriteKeyword("Ansi"); + break; + default: + throw new Exception("Invalid value for CharsetModifier"); + } + if (externalMethodDeclaration.IsSub) + WriteKeyword("Sub"); + else + WriteKeyword("Function"); + externalMethodDeclaration.Name.AcceptVisitor(this, data); + WriteKeyword("Lib"); + Space(); + WritePrimitiveValue(externalMethodDeclaration.Library); + Space(); + if (externalMethodDeclaration.Alias != null) { + WriteKeyword("Alias"); + Space(); + WritePrimitiveValue(externalMethodDeclaration.Alias); + Space(); + } + WriteCommaSeparatedListInParenthesis(externalMethodDeclaration.Parameters, false); + if (!externalMethodDeclaration.IsSub && !externalMethodDeclaration.ReturnType.IsNull) { + Space(); + WriteKeyword("As"); + WriteAttributes(externalMethodDeclaration.ReturnTypeAttributes); + externalMethodDeclaration.ReturnType.AcceptVisitor(this, data); + } + NewLine(); + + return EndNode(externalMethodDeclaration); + } + + public static string ToVBNetString(PrimitiveExpression primitiveExpression) + { + var writer = new StringWriter(); + new OutputVisitor(writer, new VBFormattingOptions()).WritePrimitiveValue(primitiveExpression.Value); + return writer.ToString(); + } + + public object VisitEmptyExpression(EmptyExpression emptyExpression, object data) + { + StartNode(emptyExpression); + + return EndNode(emptyExpression); + } + + public object VisitAnonymousObjectCreationExpression(AnonymousObjectCreationExpression anonymousObjectCreationExpression, object data) + { + StartNode(anonymousObjectCreationExpression); + + WriteKeyword("New"); + WriteKeyword("With"); + + WriteToken("{", AnonymousObjectCreationExpression.Roles.LBrace); + Space(); + WriteCommaSeparatedList(anonymousObjectCreationExpression.Initializer); + Space(); + WriteToken("}", AnonymousObjectCreationExpression.Roles.RBrace); + + return EndNode(anonymousObjectCreationExpression); + } + + public object VisitCollectionRangeVariableDeclaration(CollectionRangeVariableDeclaration collectionRangeVariableDeclaration, object data) + { + StartNode(collectionRangeVariableDeclaration); + + collectionRangeVariableDeclaration.Identifier.AcceptVisitor(this, data); + if (!collectionRangeVariableDeclaration.Type.IsNull) { + WriteKeyword("As"); + collectionRangeVariableDeclaration.Type.AcceptVisitor(this, data); + } + WriteKeyword("In"); + collectionRangeVariableDeclaration.Expression.AcceptVisitor(this, data); + + return EndNode(collectionRangeVariableDeclaration); + } + + public object VisitFromQueryOperator(FromQueryOperator fromQueryOperator, object data) + { + StartNode(fromQueryOperator); + + WriteKeyword("From"); + WriteCommaSeparatedList(fromQueryOperator.Variables); + + return EndNode(fromQueryOperator); + } + + public object VisitAggregateQueryOperator(AggregateQueryOperator aggregateQueryOperator, object data) + { + StartNode(aggregateQueryOperator); + + WriteKeyword("Aggregate"); + aggregateQueryOperator.Variable.AcceptVisitor(this, data); + + foreach (var operators in aggregateQueryOperator.SubQueryOperators) { + operators.AcceptVisitor(this, data); + } + + WriteKeyword("Into"); + WriteCommaSeparatedList(aggregateQueryOperator.IntoExpressions); + + return EndNode(aggregateQueryOperator); + } + + public object VisitSelectQueryOperator(SelectQueryOperator selectQueryOperator, object data) + { + StartNode(selectQueryOperator); + + WriteKeyword("Select"); + WriteCommaSeparatedList(selectQueryOperator.Variables); + + return EndNode(selectQueryOperator); + } + + public object VisitDistinctQueryOperator(DistinctQueryOperator distinctQueryOperator, object data) + { + StartNode(distinctQueryOperator); + + WriteKeyword("Distinct"); + + return EndNode(distinctQueryOperator); + } + + public object VisitWhereQueryOperator(WhereQueryOperator whereQueryOperator, object data) + { + StartNode(whereQueryOperator); + + WriteKeyword("Where"); + whereQueryOperator.Condition.AcceptVisitor(this, data); + + return EndNode(whereQueryOperator); + } + + public object VisitPartitionQueryOperator(PartitionQueryOperator partitionQueryOperator, object data) + { + StartNode(partitionQueryOperator); + + switch (partitionQueryOperator.Kind) { + case PartitionKind.Take: + WriteKeyword("Take"); + break; + case PartitionKind.TakeWhile: + WriteKeyword("Take"); + WriteKeyword("While"); + break; + case PartitionKind.Skip: + WriteKeyword("Skip"); + break; + case PartitionKind.SkipWhile: + WriteKeyword("Skip"); + WriteKeyword("While"); + break; + default: + throw new Exception("Invalid value for PartitionKind"); + } + + partitionQueryOperator.Expression.AcceptVisitor(this, data); + + return EndNode(partitionQueryOperator); + } + + public object VisitOrderExpression(OrderExpression orderExpression, object data) + { + StartNode(orderExpression); + + orderExpression.Expression.AcceptVisitor(this, data); + + switch (orderExpression.Direction) { + case QueryOrderingDirection.None: + break; + case QueryOrderingDirection.Ascending: + WriteKeyword("Ascending"); + break; + case QueryOrderingDirection.Descending: + WriteKeyword("Descending"); + break; + default: + throw new Exception("Invalid value for QueryExpressionOrderingDirection"); + } + + return EndNode(orderExpression); + } + + public object VisitOrderByQueryOperator(OrderByQueryOperator orderByQueryOperator, object data) + { + StartNode(orderByQueryOperator); + + WriteKeyword("Order"); + WriteKeyword("By"); + WriteCommaSeparatedList(orderByQueryOperator.Expressions); + + return EndNode(orderByQueryOperator); + } + + public object VisitLetQueryOperator(LetQueryOperator letQueryOperator, object data) + { + StartNode(letQueryOperator); + + WriteKeyword("Let"); + WriteCommaSeparatedList(letQueryOperator.Variables); + + return EndNode(letQueryOperator); + } + + public object VisitGroupByQueryOperator(GroupByQueryOperator groupByQueryOperator, object data) + { + StartNode(groupByQueryOperator); + + WriteKeyword("Group"); + WriteCommaSeparatedList(groupByQueryOperator.GroupExpressions); + WriteKeyword("By"); + WriteCommaSeparatedList(groupByQueryOperator.ByExpressions); + WriteKeyword("Into"); + WriteCommaSeparatedList(groupByQueryOperator.IntoExpressions); + + return EndNode(groupByQueryOperator); + } + + public object VisitJoinQueryOperator(JoinQueryOperator joinQueryOperator, object data) + { + StartNode(joinQueryOperator); + + WriteKeyword("Join"); + joinQueryOperator.JoinVariable.AcceptVisitor(this, data); + if (!joinQueryOperator.SubJoinQuery.IsNull) { + joinQueryOperator.SubJoinQuery.AcceptVisitor(this, data); + } + WriteKeyword("On"); + bool first = true; + foreach (var cond in joinQueryOperator.JoinConditions) { + if (first) + first = false; + else + WriteKeyword("And"); + cond.AcceptVisitor(this, data); + } + + return EndNode(joinQueryOperator); + } + + public object VisitJoinCondition(JoinCondition joinCondition, object data) + { + StartNode(joinCondition); + + joinCondition.Left.AcceptVisitor(this, data); + WriteKeyword("Equals"); + joinCondition.Right.AcceptVisitor(this, data); + + return EndNode(joinCondition); + } + + public object VisitGroupJoinQueryOperator(GroupJoinQueryOperator groupJoinQueryOperator, object data) + { + StartNode(groupJoinQueryOperator); + + WriteKeyword("Group"); + WriteKeyword("Join"); + groupJoinQueryOperator.JoinVariable.AcceptVisitor(this, data); + if (!groupJoinQueryOperator.SubJoinQuery.IsNull) { + groupJoinQueryOperator.SubJoinQuery.AcceptVisitor(this, data); + } + WriteKeyword("On"); + bool first = true; + foreach (var cond in groupJoinQueryOperator.JoinConditions) { + if (first) + first = false; + else + WriteKeyword("And"); + cond.AcceptVisitor(this, data); + } + WriteKeyword("Into"); + WriteCommaSeparatedList(groupJoinQueryOperator.IntoExpressions); + + return EndNode(groupJoinQueryOperator); + } } } diff --git a/ICSharpCode.NRefactory.VB/OutputVisitor/TextWriterOutputFormatter.cs b/ICSharpCode.NRefactory.VB/OutputVisitor/TextWriterOutputFormatter.cs index cc2df64ed0..f5b610d163 100644 --- a/ICSharpCode.NRefactory.VB/OutputVisitor/TextWriterOutputFormatter.cs +++ b/ICSharpCode.NRefactory.VB/OutputVisitor/TextWriterOutputFormatter.cs @@ -79,5 +79,23 @@ namespace ICSharpCode.NRefactory.VB public virtual void EndNode(AstNode node) { } + + public void WriteComment(bool isDocumentation, string content) + { + WriteIndentation(); + if (isDocumentation) + textWriter.Write("'''"); + else + textWriter.Write("'"); + textWriter.WriteLine(content); + } + + public void MarkFoldStart() + { + } + + public void MarkFoldEnd() + { + } } } diff --git a/ICSharpCode.NRefactory.VB/OutputVisitor/VBFormattingOptions.cs b/ICSharpCode.NRefactory.VB/OutputVisitor/VBFormattingOptions.cs index 8888bf2ffe..5dbf95054c 100644 --- a/ICSharpCode.NRefactory.VB/OutputVisitor/VBFormattingOptions.cs +++ b/ICSharpCode.NRefactory.VB/OutputVisitor/VBFormattingOptions.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/Parser/Errors.cs b/ICSharpCode.NRefactory.VB/Parser/Errors.cs index 6cd0b2e249..ab9e615bdd 100644 --- a/ICSharpCode.NRefactory.VB/Parser/Errors.cs +++ b/ICSharpCode.NRefactory.VB/Parser/Errors.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Text; diff --git a/ICSharpCode.NRefactory.VB/Parser/VBParser.cs b/ICSharpCode.NRefactory.VB/Parser/VBParser.cs index c099d7981d..bb3516cb2d 100644 --- a/ICSharpCode.NRefactory.VB/Parser/VBParser.cs +++ b/ICSharpCode.NRefactory.VB/Parser/VBParser.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractOutputFormatter.cs b/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractOutputFormatter.cs index c69a56b126..c858d664bf 100644 --- a/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractOutputFormatter.cs +++ b/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractOutputFormatter.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections; diff --git a/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractPrettyPrintOptions.cs b/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractPrettyPrintOptions.cs index 438fc54a3b..7da8a578cd 100644 --- a/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractPrettyPrintOptions.cs +++ b/ICSharpCode.NRefactory.VB/PrettyPrinter/AbstractPrettyPrintOptions.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) namespace ICSharpCode.NRefactory.VB.PrettyPrinter { diff --git a/ICSharpCode.NRefactory.VB/PrettyPrinter/IOutputAstVisitor.cs b/ICSharpCode.NRefactory.VB/PrettyPrinter/IOutputAstVisitor.cs index 71ccb5d0f0..049696dad4 100644 --- a/ICSharpCode.NRefactory.VB/PrettyPrinter/IOutputAstVisitor.cs +++ b/ICSharpCode.NRefactory.VB/PrettyPrinter/IOutputAstVisitor.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using ICSharpCode.NRefactory.VB.Parser; diff --git a/ICSharpCode.NRefactory.VB/PrettyPrinter/SpecialNodesInserter.cs b/ICSharpCode.NRefactory.VB/PrettyPrinter/SpecialNodesInserter.cs index 95fdcf389c..f44d91263c 100644 --- a/ICSharpCode.NRefactory.VB/PrettyPrinter/SpecialNodesInserter.cs +++ b/ICSharpCode.NRefactory.VB/PrettyPrinter/SpecialNodesInserter.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputFormatter.cs b/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputFormatter.cs index ca2325bbad..aadd790af1 100644 --- a/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputFormatter.cs +++ b/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputFormatter.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using ICSharpCode.NRefactory.VB.Parser; diff --git a/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputVisitor.cs b/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputVisitor.cs index 972c09260f..d4635d1d12 100644 --- a/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputVisitor.cs +++ b/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetOutputVisitor.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Linq; diff --git a/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetPrettyPrintOptions.cs b/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetPrettyPrintOptions.cs index 0b6170a07d..8178afde06 100644 --- a/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetPrettyPrintOptions.cs +++ b/ICSharpCode.NRefactory.VB/PrettyPrinter/VBNet/VBNetPrettyPrintOptions.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; diff --git a/ICSharpCode.NRefactory.VB/VBParser.cs b/ICSharpCode.NRefactory.VB/VBParser.cs index 27d244be1b..5f62f952ae 100644 --- a/ICSharpCode.NRefactory.VB/VBParser.cs +++ b/ICSharpCode.NRefactory.VB/VBParser.cs @@ -1,5 +1,5 @@ // 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) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; using System.Collections.Generic; diff --git a/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs b/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs new file mode 100644 index 0000000000..10d142671b --- /dev/null +++ b/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs @@ -0,0 +1,2206 @@ +// 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.Collections.Generic; +using System.Linq; + +using ICSharpCode.NRefactory.PatternMatching; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.VB.Ast; + +namespace ICSharpCode.NRefactory.VB.Visitors +{ + public interface IEnvironmentProvider + { + string RootNamespace { get; } + string GetTypeNameForAttribute(CSharp.Attribute attribute); + ClassType GetClassTypeForAstType(CSharp.AstType type); + TypeCode ResolveExpression(CSharp.Expression expression); + bool? IsReferenceType(CSharp.Expression expression); + ITypeResolveContext ResolveContext { get; } + IType ResolveType(AstType type, TypeDeclaration entity = null); + } + + /// + /// Description of CSharpToVBConverterVisitor. + /// + public class CSharpToVBConverterVisitor : CSharp.IAstVisitor + { + IEnvironmentProvider provider; + Stack blocks; + Stack types; + Stack members; + + class MemberInfo + { + public bool inIterator; + } + + public CSharpToVBConverterVisitor(IEnvironmentProvider provider) + { + this.provider = provider; + this.blocks = new Stack(); + this.types = new Stack(); + this.members = new Stack(); + } + + public AstNode VisitAnonymousMethodExpression(CSharp.AnonymousMethodExpression anonymousMethodExpression, object data) + { + members.Push(new MemberInfo()); + + var expr = new MultiLineLambdaExpression() { + IsSub = true, + Body = (BlockStatement)anonymousMethodExpression.Body.AcceptVisitor(this, data) + }; + + ConvertNodes(anonymousMethodExpression.Parameters, expr.Parameters); + + if (members.Pop().inIterator) { + expr.Modifiers |= LambdaExpressionModifiers.Iterator; + } + + return EndNode(anonymousMethodExpression, expr); + } + + public AstNode VisitUndocumentedExpression(CSharp.UndocumentedExpression undocumentedExpression, object data) + { + var invocation = new InvocationExpression(); + + switch (undocumentedExpression.UndocumentedExpressionType) { + case CSharp.UndocumentedExpressionType.ArgListAccess: + case CSharp.UndocumentedExpressionType.ArgList: + invocation.Target = new IdentifierExpression { Identifier = "__ArgList" }; + break; + case CSharp.UndocumentedExpressionType.RefValue: + invocation.Target = new IdentifierExpression { Identifier = "__RefValue" }; + break; + case CSharp.UndocumentedExpressionType.RefType: + invocation.Target = new IdentifierExpression { Identifier = "__RefType" }; + break; + case CSharp.UndocumentedExpressionType.MakeRef: + invocation.Target = new IdentifierExpression { Identifier = "__MakeRef" }; + break; + default: + throw new Exception("Invalid value for UndocumentedExpressionType"); + } + + ConvertNodes(undocumentedExpression.Arguments, invocation.Arguments); + + return EndNode(undocumentedExpression, invocation); + } + + public AstNode VisitArrayCreateExpression(CSharp.ArrayCreateExpression arrayCreateExpression, object data) + { + var expr = new ArrayCreateExpression() { + Type = (AstType)arrayCreateExpression.Type.AcceptVisitor(this, data), + Initializer = (ArrayInitializerExpression)arrayCreateExpression.Initializer.AcceptVisitor(this, data) + }; + ConvertNodes(arrayCreateExpression.Arguments, expr.Arguments); + ConvertNodes(arrayCreateExpression.AdditionalArraySpecifiers, expr.AdditionalArraySpecifiers); + + return EndNode(arrayCreateExpression, expr); + } + + public AstNode VisitArrayInitializerExpression(CSharp.ArrayInitializerExpression arrayInitializerExpression, object data) + { + var expr = new ArrayInitializerExpression(); + ConvertNodes(arrayInitializerExpression.Elements, expr.Elements); + + return EndNode(arrayInitializerExpression, expr); + } + + public AstNode VisitAsExpression(CSharp.AsExpression asExpression, object data) + { + return EndNode(asExpression, new CastExpression(CastType.TryCast, (AstType)asExpression.Type.AcceptVisitor(this, data), (Expression)asExpression.Expression.AcceptVisitor(this, data))); + } + + public AstNode VisitAssignmentExpression(CSharp.AssignmentExpression assignmentExpression, object data) + { + var left = (Expression)assignmentExpression.Left.AcceptVisitor(this, data); + var op = AssignmentOperatorType.None; + var right = (Expression)assignmentExpression.Right.AcceptVisitor(this, data); + + switch (assignmentExpression.Operator) { + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Assign: + op = AssignmentOperatorType.Assign; + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Add: + op = AssignmentOperatorType.Add; + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Subtract: + op = AssignmentOperatorType.Subtract; + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Multiply: + op = AssignmentOperatorType.Multiply; + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Divide: + op = AssignmentOperatorType.Divide; + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Modulus: + op = AssignmentOperatorType.Assign; + right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.Modulus, right); + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftLeft: + op = AssignmentOperatorType.ShiftLeft; + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftRight: + op = AssignmentOperatorType.ShiftRight; + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseAnd: + op = AssignmentOperatorType.Assign; + right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.BitwiseAnd, right); + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseOr: + op = AssignmentOperatorType.Assign; + right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.BitwiseOr, right); + break; + case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ExclusiveOr: + op = AssignmentOperatorType.Assign; + right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.ExclusiveOr, right); + break; + default: + throw new Exception("Invalid value for AssignmentOperatorType: " + assignmentExpression.Operator); + } + + var expr = new AssignmentExpression(left, op, right); + return EndNode(assignmentExpression, expr); + } + + public AstNode VisitBaseReferenceExpression(CSharp.BaseReferenceExpression baseReferenceExpression, object data) + { + InstanceExpression result = new InstanceExpression(InstanceExpressionType.MyBase, ConvertLocation(baseReferenceExpression.StartLocation)); + + return EndNode(baseReferenceExpression, result); + } + + public AstNode VisitBinaryOperatorExpression(CSharp.BinaryOperatorExpression binaryOperatorExpression, object data) + { + var left = (Expression)binaryOperatorExpression.Left.AcceptVisitor(this, data); + var op = BinaryOperatorType.None; + var right = (Expression)binaryOperatorExpression.Right.AcceptVisitor(this, data); + + switch (binaryOperatorExpression.Operator) { + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.BitwiseAnd: + op = BinaryOperatorType.BitwiseAnd; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.BitwiseOr: + op = BinaryOperatorType.BitwiseOr; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ConditionalAnd: + op = BinaryOperatorType.LogicalAnd; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ConditionalOr: + op = BinaryOperatorType.LogicalOr; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ExclusiveOr: + op = BinaryOperatorType.ExclusiveOr; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.GreaterThan: + op = BinaryOperatorType.GreaterThan; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.GreaterThanOrEqual: + op = BinaryOperatorType.GreaterThanOrEqual; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Equality: + if (IsReferentialEquality(binaryOperatorExpression)) + op = BinaryOperatorType.ReferenceEquality; + else + op = BinaryOperatorType.Equality; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.InEquality: + if (IsReferentialEquality(binaryOperatorExpression)) + op = BinaryOperatorType.ReferenceInequality; + else + op = BinaryOperatorType.InEquality; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.LessThan: + op = BinaryOperatorType.LessThan; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.LessThanOrEqual: + op = BinaryOperatorType.LessThanOrEqual; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Add: + // TODO might be string concatenation + op = BinaryOperatorType.Add; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Subtract: + op = BinaryOperatorType.Subtract; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Multiply: + op = BinaryOperatorType.Multiply; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Divide: + op = BinaryOperatorType.Divide; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.Modulus: + op = BinaryOperatorType.Modulus; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ShiftLeft: + op = BinaryOperatorType.ShiftLeft; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.ShiftRight: + op = BinaryOperatorType.ShiftRight; + break; + case ICSharpCode.NRefactory.CSharp.BinaryOperatorType.NullCoalescing: + var nullCoalescing = new ConditionalExpression { + ConditionExpression = left, + FalseExpression = right + }; + return EndNode(binaryOperatorExpression, nullCoalescing); + default: + throw new Exception("Invalid value for BinaryOperatorType: " + binaryOperatorExpression.Operator); + } + + return EndNode(binaryOperatorExpression, new BinaryOperatorExpression(left, op, right)); + } + + bool IsReferentialEquality(CSharp.BinaryOperatorExpression binaryOperatorExpression) + { + var left = provider.IsReferenceType(binaryOperatorExpression.Left); + var right = provider.IsReferenceType(binaryOperatorExpression.Right); + + var leftCode = provider.ResolveExpression(binaryOperatorExpression.Left); + var rightCode = provider.ResolveExpression(binaryOperatorExpression.Right); + + return (left == true || right == true) && (leftCode != TypeCode.String && rightCode != TypeCode.String); + } + + public AstNode VisitCastExpression(CSharp.CastExpression castExpression, object data) + { + var expr = new CastExpression(); + + expr.Type = (AstType)castExpression.Type.AcceptVisitor(this, data); + // TODO read additional type information from annotation + // (int)x is equivalent to CInt(Math.Truncate(x)) + expr.CastType = GetCastType(expr.Type, null); + expr.Expression = (Expression)castExpression.Expression.AcceptVisitor(this, data); + + if (expr.CastType != CastType.CType) + expr.Type = null; + + return EndNode(castExpression, expr); + } + + CastType GetCastType(AstType type, object typeInformation) + { + var primType = type as PrimitiveType; + if (primType == null) + return CastType.CType; + + switch (primType.Keyword) { + case "Boolean": + return CastType.CBool; + case "Byte": + return CastType.CByte; + case "Char": + return CastType.CChar; + case "Date": + return CastType.CDate; + case "Double": + return CastType.CDbl; + case "Decimal": + return CastType.CDec; + case "Integer": + return CastType.CInt; + case "Long": + return CastType.CLng; + case "Object": + return CastType.CObj; + case "SByte": + return CastType.CSByte; + case "Short": + return CastType.CShort; + case "Single": + return CastType.CSng; + case "String": + return CastType.CStr; + case "UInteger": + return CastType.CUInt; + case "ULong": + return CastType.CULng; + case "UShort": + return CastType.CUShort; + } + + return CastType.CType; + } + + public AstNode VisitCheckedExpression(CSharp.CheckedExpression checkedExpression, object data) + { + blocks.Peek().AddChild(new Comment(" The following expression was wrapped in a checked-expression", false), AstNode.Roles.Comment); + return EndNode(checkedExpression, checkedExpression.Expression.AcceptVisitor(this, data)); + } + + public AstNode VisitConditionalExpression(CSharp.ConditionalExpression conditionalExpression, object data) + { + var cond = new ConditionalExpression() { + ConditionExpression = (Expression)conditionalExpression.Condition.AcceptVisitor(this, data), + TrueExpression = (Expression)conditionalExpression.TrueExpression.AcceptVisitor(this, data), + FalseExpression = (Expression)conditionalExpression.FalseExpression.AcceptVisitor(this, data) + }; + + return EndNode(conditionalExpression, cond); + } + + public AstNode VisitDefaultValueExpression(CSharp.DefaultValueExpression defaultValueExpression, object data) + { + // Nothing is equivalent to default(T) for reference and value types. + return EndNode(defaultValueExpression, new PrimitiveExpression(null)); + } + + public AstNode VisitDirectionExpression(CSharp.DirectionExpression directionExpression, object data) + { + return EndNode(directionExpression, (Expression)directionExpression.Expression.AcceptVisitor(this, data)); + } + + public AstNode VisitIdentifierExpression(CSharp.IdentifierExpression identifierExpression, object data) + { + var expr = new IdentifierExpression(); + expr.Identifier = new Identifier(identifierExpression.Identifier, AstLocation.Empty); + ConvertNodes(identifierExpression.TypeArguments, expr.TypeArguments); + + return EndNode(identifierExpression, expr); + } + + public AstNode VisitIndexerExpression(CSharp.IndexerExpression indexerExpression, object data) + { + var expr = new InvocationExpression((Expression)indexerExpression.Target.AcceptVisitor(this, data)); + ConvertNodes(indexerExpression.Arguments, expr.Arguments); + return EndNode(indexerExpression, expr); + } + + public AstNode VisitInvocationExpression(CSharp.InvocationExpression invocationExpression, object data) + { + var expr = new InvocationExpression( + (Expression)invocationExpression.Target.AcceptVisitor(this, data)); + ConvertNodes(invocationExpression.Arguments, expr.Arguments); + + return EndNode(invocationExpression, expr); + } + + public AstNode VisitIsExpression(CSharp.IsExpression isExpression, object data) + { + var expr = new TypeOfIsExpression() { + Type = (AstType)isExpression.Type.AcceptVisitor(this, data), + TypeOfExpression = (Expression)isExpression.Expression.AcceptVisitor(this, data) + }; + + return EndNode(isExpression, expr); + } + + public AstNode VisitLambdaExpression(CSharp.LambdaExpression lambdaExpression, object data) + { + LambdaExpression expr = null; + + if (lambdaExpression.Body is CSharp.Expression) { + var singleLine = new SingleLineFunctionLambdaExpression() { + EmbeddedExpression = (Expression)lambdaExpression.Body.AcceptVisitor(this, data) + }; + ConvertNodes(lambdaExpression.Parameters, singleLine.Parameters); + expr = singleLine; + } else + throw new NotImplementedException(); + + return EndNode(lambdaExpression, expr); + } + + public AstNode VisitMemberReferenceExpression(CSharp.MemberReferenceExpression memberReferenceExpression, object data) + { + var memberAccessExpression = new MemberAccessExpression(); + + memberAccessExpression.Target = (Expression)memberReferenceExpression.Target.AcceptVisitor(this, data); + memberAccessExpression.MemberName = new Identifier(memberReferenceExpression.MemberName, AstLocation.Empty); + ConvertNodes(memberReferenceExpression.TypeArguments, memberAccessExpression.TypeArguments); + + return EndNode(memberReferenceExpression, memberAccessExpression); + } + + public AstNode VisitNamedArgumentExpression(CSharp.NamedArgumentExpression namedArgumentExpression, object data) + { + Expression expr; + + if (namedArgumentExpression.Parent is CSharp.ArrayInitializerExpression) { + expr = new FieldInitializerExpression { + IsKey = true, + Identifier = namedArgumentExpression.Identifier, + Expression = (Expression)namedArgumentExpression.Expression.AcceptVisitor(this, data) + }; + } else { + expr = new NamedArgumentExpression { + Identifier = namedArgumentExpression.Identifier, + Expression = (Expression)namedArgumentExpression.Expression.AcceptVisitor(this, data) + }; + } + + return EndNode(namedArgumentExpression, expr); + } + + public AstNode VisitNullReferenceExpression(CSharp.NullReferenceExpression nullReferenceExpression, object data) + { + return EndNode(nullReferenceExpression, new PrimitiveExpression(null)); + } + + public AstNode VisitObjectCreateExpression(CSharp.ObjectCreateExpression objectCreateExpression, object data) + { + var expr = new ObjectCreationExpression((AstType)objectCreateExpression.Type.AcceptVisitor(this, data)); + ConvertNodes(objectCreateExpression.Arguments, expr.Arguments); + if (!objectCreateExpression.Initializer.IsNull) + expr.Initializer = (ArrayInitializerExpression)objectCreateExpression.Initializer.AcceptVisitor(this, data); + + return EndNode(objectCreateExpression, expr); + } + + public AstNode VisitAnonymousTypeCreateExpression(CSharp.AnonymousTypeCreateExpression anonymousTypeCreateExpression, object data) + { + var expr = new AnonymousObjectCreationExpression(); + + ConvertNodes(anonymousTypeCreateExpression.Initializer, expr.Initializer); + + return EndNode(anonymousTypeCreateExpression, expr); + } + + public AstNode VisitParenthesizedExpression(CSharp.ParenthesizedExpression parenthesizedExpression, object data) + { + var result = new ParenthesizedExpression(); + + result.Expression = (Expression)parenthesizedExpression.Expression.AcceptVisitor(this, data); + + return EndNode(parenthesizedExpression, result); + } + + public AstNode VisitPointerReferenceExpression(CSharp.PointerReferenceExpression pointerReferenceExpression, object data) + { + return EndNode(pointerReferenceExpression,((Expression)pointerReferenceExpression.Target.AcceptVisitor(this, data)).Invoke("Dereference").Member(pointerReferenceExpression.MemberName)); + } + + public AstNode VisitPrimitiveExpression(CSharp.PrimitiveExpression primitiveExpression, object data) + { + Expression expr; + + if (!string.IsNullOrEmpty(primitiveExpression.Value as string) || primitiveExpression.Value is char) + expr = ConvertToConcat(primitiveExpression.Value.ToString()); + else + expr = new PrimitiveExpression(primitiveExpression.Value); + + return EndNode(primitiveExpression, expr); + } + + Expression ConvertToConcat(string literal) + { + Stack parts = new Stack(); + int start = 0; + + for (int i = 0; i < literal.Length; i++) { + string part; + switch (literal[i]) { + case '\0': + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + parts.Push(new IdentifierExpression("vbNullChar")); + start = i + 1; + break; + case '\b': + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + parts.Push(new IdentifierExpression("vbBack")); + start = i + 1; + break; + case '\f': + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + parts.Push(new IdentifierExpression("vbFormFeed")); + start = i + 1; + break; + case '\r': + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + if (i + 1 < literal.Length && literal[i + 1] == '\n') { + i++; + parts.Push(new IdentifierExpression("vbCrLf")); + } else + parts.Push(new IdentifierExpression("vbCr")); + start = i + 1; + break; + case '\n': + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + parts.Push(new IdentifierExpression("vbLf")); + start = i + 1; + break; + case '\t': + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + parts.Push(new IdentifierExpression("vbTab")); + start = i + 1; + break; + case '\v': + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + parts.Push(new IdentifierExpression("vbVerticalTab")); + start = i + 1; + break; + default: + if ((int)literal[i] > 255) { + part = literal.Substring(start, i - start); + if (!string.IsNullOrEmpty(part)) + parts.Push(new PrimitiveExpression(part)); + parts.Push(new InvocationExpression(new IdentifierExpression("ChrW"), new PrimitiveExpression((int)literal[i]))); + } else + continue; + start = i + 1; + break; + } + + } + + if (start < literal.Length) { + string part = literal.Substring(start); + parts.Push(new PrimitiveExpression(part)); + } + + Expression current = parts.Pop(); + + while (parts.Any()) + current = new BinaryOperatorExpression(parts.Pop(), BinaryOperatorType.Concat, current); + + return current; + } + + public AstNode VisitSizeOfExpression(CSharp.SizeOfExpression sizeOfExpression, object data) + { + return EndNode( + sizeOfExpression, + new InvocationExpression( + new IdentifierExpression() { Identifier = "__SizeOf" }, + new TypeReferenceExpression((AstType)sizeOfExpression.Type.AcceptVisitor(this, data)) + ) + ); + } + + public AstNode VisitStackAllocExpression(CSharp.StackAllocExpression stackAllocExpression, object data) + { + return EndNode( + stackAllocExpression, + new InvocationExpression( + new IdentifierExpression() { Identifier = "__StackĄlloc" }, + new TypeReferenceExpression((AstType)stackAllocExpression.Type.AcceptVisitor(this, data)), + (Expression)stackAllocExpression.CountExpression.AcceptVisitor(this, data) + ) + ); + } + + public AstNode VisitThisReferenceExpression(CSharp.ThisReferenceExpression thisReferenceExpression, object data) + { + InstanceExpression result = new InstanceExpression(InstanceExpressionType.Me, ConvertLocation(thisReferenceExpression.StartLocation)); + return EndNode(thisReferenceExpression, result); + } + + public AstNode VisitTypeOfExpression(CSharp.TypeOfExpression typeOfExpression, object data) + { + var expr = new GetTypeExpression(); + expr.Type = (AstType)typeOfExpression.Type.AcceptVisitor(this, data); + return EndNode(typeOfExpression, expr); + } + + public AstNode VisitTypeReferenceExpression(CSharp.TypeReferenceExpression typeReferenceExpression, object data) + { + var expr = new TypeReferenceExpression((AstType)typeReferenceExpression.Type.AcceptVisitor(this, data)); + return EndNode(typeReferenceExpression, expr); + } + + public AstNode VisitUnaryOperatorExpression(CSharp.UnaryOperatorExpression unaryOperatorExpression, object data) + { + Expression expr; + + switch (unaryOperatorExpression.Operator) { + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Not: + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.BitNot: + expr = new UnaryOperatorExpression() { + Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data), + Operator = UnaryOperatorType.Not + }; + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Minus: + expr = new UnaryOperatorExpression() { + Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data), + Operator = UnaryOperatorType.Minus + }; + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Plus: + expr = new UnaryOperatorExpression() { + Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data), + Operator = UnaryOperatorType.Plus + }; + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Increment: + expr = new InvocationExpression(); + ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__Increment" }; + ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data)); + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.PostIncrement: + expr = new InvocationExpression(); + ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__PostIncrement" }; + ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data)); + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Decrement: + expr = new InvocationExpression(); + ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__Decrement" }; + ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data)); + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.PostDecrement: + expr = new InvocationExpression(); + ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__PostDecrement" }; + ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data)); + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.AddressOf: + expr = new UnaryOperatorExpression() { + Expression = (Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data), + Operator = UnaryOperatorType.AddressOf + }; + break; + case ICSharpCode.NRefactory.CSharp.UnaryOperatorType.Dereference: + expr = new InvocationExpression(); + ((InvocationExpression)expr).Target = new IdentifierExpression() { Identifier = "__Dereference" }; + ((InvocationExpression)expr).Arguments.Add((Expression)unaryOperatorExpression.Expression.AcceptVisitor(this, data)); + break; + default: + throw new Exception("Invalid value for UnaryOperatorType"); + } + + return EndNode(unaryOperatorExpression, expr); + } + + public AstNode VisitUncheckedExpression(CSharp.UncheckedExpression uncheckedExpression, object data) + { + blocks.Peek().AddChild(new Comment(" The following expression was wrapped in a unchecked-expression", false), AstNode.Roles.Comment); + return EndNode(uncheckedExpression, uncheckedExpression.Expression.AcceptVisitor(this, data)); + } + + public AstNode VisitEmptyExpression(CSharp.EmptyExpression emptyExpression, object data) + { + return EndNode(emptyExpression, new EmptyExpression()); + } + + public AstNode VisitQueryExpression(CSharp.QueryExpression queryExpression, object data) + { + var expr = new QueryExpression(); + ConvertNodes(queryExpression.Clauses, expr.QueryOperators); + return EndNode(queryExpression, expr); + } + + public AstNode VisitQueryContinuationClause(CSharp.QueryContinuationClause queryContinuationClause, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitQueryFromClause(CSharp.QueryFromClause queryFromClause, object data) + { + var op = new FromQueryOperator(); + op.Variables.Add( + new CollectionRangeVariableDeclaration { + Identifier = new VariableIdentifier { Name = queryFromClause.Identifier }, + Type = (AstType)queryFromClause.Type.AcceptVisitor(this, data), + Expression = (Expression)queryFromClause.Expression.AcceptVisitor(this, data) + } + ); + + return EndNode(queryFromClause, op); + } + + public AstNode VisitQueryLetClause(CSharp.QueryLetClause queryLetClause, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitQueryWhereClause(CSharp.QueryWhereClause queryWhereClause, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitQueryJoinClause(CSharp.QueryJoinClause queryJoinClause, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitQueryOrderClause(CSharp.QueryOrderClause queryOrderClause, object data) + { + var op = new OrderByQueryOperator(); + + ConvertNodes(queryOrderClause.Orderings, op.Expressions); + + return EndNode(queryOrderClause, op); + } + + public AstNode VisitQueryOrdering(CSharp.QueryOrdering queryOrdering, object data) + { + var expr = new OrderExpression(); + + expr.Direction = (QueryOrderingDirection)queryOrdering.Direction; + expr.Expression = (Expression)queryOrdering.Expression.AcceptVisitor(this, data); + + return EndNode(queryOrdering, expr); + } + + int selectVarCount = 0; + + public AstNode VisitQuerySelectClause(CSharp.QuerySelectClause querySelectClause, object data) + { + var op = new SelectQueryOperator(); + + op.Variables.Add( + new VariableInitializer { + Identifier = new VariableIdentifier { Name = "SelectVar" + selectVarCount }, + Expression = (Expression)querySelectClause.Expression.AcceptVisitor(this, data) + }); + + return EndNode(querySelectClause, op); + } + + public AstNode VisitQueryGroupClause(CSharp.QueryGroupClause queryGroupClause, object data) + { + var op = new GroupByQueryOperator(); + + throw new NotImplementedException(); + + return EndNode(queryGroupClause, op); + } + + public AstNode VisitAttribute(CSharp.Attribute attribute, object data) + { + var attr = new VB.Ast.Attribute(); + AttributeTarget target; + Enum.TryParse(((CSharp.AttributeSection)attribute.Parent).AttributeTarget, true, out target); + attr.Target = target; + attr.Type = (AstType)attribute.Type.AcceptVisitor(this, data); + ConvertNodes(attribute.Arguments, attr.Arguments); + + return EndNode(attribute, attr); + } + + public AstNode VisitAttributeSection(CSharp.AttributeSection attributeSection, object data) + { + AttributeBlock block = new AttributeBlock(); + ConvertNodes(attributeSection.Attributes, block.Attributes); + return EndNode(attributeSection, block); + } + + public AstNode VisitDelegateDeclaration(CSharp.DelegateDeclaration delegateDeclaration, object data) + { + var result = new DelegateDeclaration(); + + ConvertNodes(delegateDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes); + ConvertNodes(delegateDeclaration.ModifierTokens, result.ModifierTokens); + result.Name = new Identifier(delegateDeclaration.Name, AstLocation.Empty); + result.IsSub = IsSub(delegateDeclaration.ReturnType); + ConvertNodes(delegateDeclaration.Parameters, result.Parameters); + ConvertNodes(delegateDeclaration.TypeParameters, result.TypeParameters); + ConvertNodes(delegateDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes); + if (!result.IsSub) + result.ReturnType = (AstType)delegateDeclaration.ReturnType.AcceptVisitor(this, data); + return EndNode(delegateDeclaration, result); + } + + public AstNode VisitNamespaceDeclaration(CSharp.NamespaceDeclaration namespaceDeclaration, object data) + { + var newNamespace = new NamespaceDeclaration(); + + ConvertNodes(namespaceDeclaration.Identifiers, newNamespace.Identifiers); + ConvertNodes(namespaceDeclaration.Members, newNamespace.Members); + + return EndNode(namespaceDeclaration, newNamespace); + } + + public AstNode VisitTypeDeclaration(CSharp.TypeDeclaration typeDeclaration, object data) + { + // TODO add missing features! + + if (typeDeclaration.ClassType == ClassType.Enum) { + var type = new EnumDeclaration(); + CopyAnnotations(typeDeclaration, type); + + ConvertNodes(typeDeclaration.Attributes, type.Attributes); + ConvertNodes(typeDeclaration.ModifierTokens, type.ModifierTokens); + + if (typeDeclaration.BaseTypes.Any()) { + var first = typeDeclaration.BaseTypes.First(); + + type.UnderlyingType = (AstType)first.AcceptVisitor(this, data); + } + + type.Name = new Identifier(typeDeclaration.Name, AstLocation.Empty); + + ConvertNodes(typeDeclaration.Members, type.Members); + + return EndNode(typeDeclaration, type); + } else { + var type = new TypeDeclaration(); + CopyAnnotations(typeDeclaration, type); + + CSharp.Attribute stdModAttr; + + if (typeDeclaration.ClassType == ClassType.Class && HasAttribute(typeDeclaration.Attributes, "Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute", out stdModAttr)) { + type.ClassType = ClassType.Module; + // remove AttributeSection if only one attribute is present + var attrSec = (CSharp.AttributeSection)stdModAttr.Parent; + if (attrSec.Attributes.Count == 1) + attrSec.Remove(); + else + stdModAttr.Remove(); + } else + type.ClassType = typeDeclaration.ClassType; + + if ((typeDeclaration.Modifiers & CSharp.Modifiers.Static) == CSharp.Modifiers.Static) { + type.ClassType = ClassType.Module; + typeDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + } + + ConvertNodes(typeDeclaration.Attributes, type.Attributes); + ConvertNodes(typeDeclaration.ModifierTokens, type.ModifierTokens); + + if (typeDeclaration.BaseTypes.Any()) { + var first = typeDeclaration.BaseTypes.First(); + + if (provider.GetClassTypeForAstType(first) != ClassType.Interface) { + ConvertNodes(typeDeclaration.BaseTypes.Skip(1), type.ImplementsTypes); + type.InheritsType = (AstType)first.AcceptVisitor(this, data); + } else + ConvertNodes(typeDeclaration.BaseTypes, type.ImplementsTypes); + } + + type.Name = typeDeclaration.Name; + + types.Push(type); + ConvertNodes(typeDeclaration.Members, type.Members); + types.Pop(); + + return EndNode(typeDeclaration, type); + } + } + + public AstNode VisitUsingAliasDeclaration(CSharp.UsingAliasDeclaration usingAliasDeclaration, object data) + { + var imports = new ImportsStatement(); + + var clause = new AliasImportsClause() { + Name = new Identifier(usingAliasDeclaration.Alias, AstLocation.Empty), + Alias = (AstType)usingAliasDeclaration.Import.AcceptVisitor(this, data) + }; + + imports.AddChild(clause, ImportsStatement.ImportsClauseRole); + + return EndNode(usingAliasDeclaration, imports); + } + + public AstNode VisitUsingDeclaration(CSharp.UsingDeclaration usingDeclaration, object data) + { + var imports = new ImportsStatement(); + + var clause = new MemberImportsClause() { + Member = (AstType)usingDeclaration.Import.AcceptVisitor(this, data) + }; + + imports.AddChild(clause, ImportsStatement.ImportsClauseRole); + + return EndNode(usingDeclaration, imports); + } + + public AstNode VisitExternAliasDeclaration(CSharp.ExternAliasDeclaration externAliasDeclaration, object data) + { + throw new NotImplementedException(); + } + + 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) + { + 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) + { + blocks.Peek().AddChild(new Comment(" The following expression was wrapped in a checked-statement", false), AstNode.Roles.Comment); + var body = (BlockStatement)checkedStatement.Body.AcceptVisitor(this, data); + + foreach (var stmt in body) { + stmt.Remove(); + blocks.Peek().Add(stmt); + } + + return EndNode(checkedStatement, null); + } + + public AstNode VisitContinueStatement(CSharp.ContinueStatement continueStatement, object data) + { + var @continue = new ContinueStatement(ContinueKind.None); + + foreach (var stmt in continueStatement.Ancestors) { + if (stmt is CSharp.DoWhileStatement) { + @continue.ContinueKind = ContinueKind.Do; + break; + } + if (stmt is CSharp.ForStatement || stmt is CSharp.ForeachStatement) { + @continue.ContinueKind = ContinueKind.For; + break; + } + if (stmt is CSharp.WhileStatement) { + @continue.ContinueKind = ContinueKind.While; + break; + } + } + + return EndNode(continueStatement, @continue); + } + + public AstNode VisitDoWhileStatement(CSharp.DoWhileStatement doWhileStatement, object data) + { + var stmt = new DoLoopStatement(); + + stmt.ConditionType = ConditionType.LoopWhile; + stmt.Expression = (Expression)doWhileStatement.Condition.AcceptVisitor(this, data); + stmt.Body = (BlockStatement)doWhileStatement.EmbeddedStatement.AcceptVisitor(this, data); + + return EndNode(doWhileStatement, stmt); + } + + public AstNode VisitEmptyStatement(CSharp.EmptyStatement emptyStatement, object data) + { + return EndNode(emptyStatement, null); + } + + public AstNode VisitExpressionStatement(CSharp.ExpressionStatement expressionStatement, object data) + { + var expr = new ExpressionStatement((Expression)expressionStatement.Expression.AcceptVisitor(this, data)); + return EndNode(expressionStatement, expr); + } + + public AstNode VisitFixedStatement(CSharp.FixedStatement fixedStatement, object data) + { + var block = blocks.Peek(); + block.AddChild(new Comment(" Emulating fixed-Statement, might not be entirely correct!", false), AstNode.Roles.Comment); + + var variables = new LocalDeclarationStatement(); + variables.Modifiers = Modifiers.Dim; + var stmt = new TryStatement(); + stmt.FinallyBlock = new BlockStatement(); + foreach (var decl in fixedStatement.Variables) { + var v = new VariableDeclaratorWithTypeAndInitializer { + Identifiers = { new VariableIdentifier { Name = decl.Name } }, + Type = new SimpleType("GCHandle"), + Initializer = new InvocationExpression( + new MemberAccessExpression { Target = new IdentifierExpression { Identifier = "GCHandle" }, MemberName = "Alloc" }, + (Expression)decl.Initializer.AcceptVisitor(this, data), + new MemberAccessExpression { Target = new IdentifierExpression { Identifier = "GCHandleType" }, MemberName = "Pinned" } + ) + }; + variables.Variables.Add(v); + stmt.FinallyBlock.Add(new IdentifierExpression { Identifier = decl.Name }.Invoke("Free")); + } + + block.Add(variables); + + stmt.Body = (BlockStatement)fixedStatement.EmbeddedStatement.AcceptVisitor(this, data); + + foreach (var ident in stmt.Body.Descendants.OfType()) { + ident.ReplaceWith(expr => ((Expression)expr).Invoke("AddrOfPinnedObject")); + } + + return EndNode(fixedStatement, stmt); + } + + public AstNode VisitForeachStatement(CSharp.ForeachStatement foreachStatement, object data) + { + var stmt = new ForEachStatement() { + Body = (BlockStatement)foreachStatement.EmbeddedStatement.AcceptVisitor(this, data), + InExpression = (Expression)foreachStatement.InExpression.AcceptVisitor(this, data), + Variable = new VariableInitializer() { + Identifier = new VariableIdentifier() { Name = foreachStatement.VariableName }, + Type = (AstType)foreachStatement.VariableType.AcceptVisitor(this, data) + } + }; + + return EndNode(foreachStatement, stmt); + } + + public AstNode VisitForStatement(CSharp.ForStatement forStatement, object data) + { + // 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) }); + + CSharp.AstNode counterLoop = new CSharp.ForStatement() { + Initializers = { + new NamedNode( + "iteratorVar", + new Choice { + new CSharp.VariableDeclarationStatement { + Type = new Choice { + new CSharp.PrimitiveType("long"), + new CSharp.PrimitiveType("ulong"), + new CSharp.PrimitiveType("int"), + new CSharp.PrimitiveType("uint"), + new CSharp.PrimitiveType("short"), + new CSharp.PrimitiveType("ushort"), + new CSharp.PrimitiveType("sbyte"), + new CSharp.PrimitiveType("byte") + }, + Variables = { + new AnyNode() + } + }, + new CSharp.ExpressionStatement( + new CSharp.AssignmentExpression() + ) + }) + }, + Condition = new NamedNode( + "condition", + new CSharp.BinaryOperatorExpression { + Left = new NamedNode("ident", new CSharp.IdentifierExpression()), + Operator = CSharp.BinaryOperatorType.Any, + Right = new AnyNode("endExpr") + }), + Iterators = { + new CSharp.ExpressionStatement( + new NamedNode( + "increment", + new CSharp.AssignmentExpression { + Left = new Backreference("ident"), + Operator = CSharp.AssignmentOperatorType.Any, + Right = new NamedNode("factor", new AnyNode()) + } + ) + ) + }, + EmbeddedStatement = new NamedNode("body", new AnyNode()) + }; + + var match = counterLoop.Match(forStatement); + + if (match.Success) { + var init = match.Get("iteratorVar").SingleOrDefault(); + + AstNode iteratorVariable; + + if (init is CSharp.VariableDeclarationStatement) { + var var = ((CSharp.VariableDeclarationStatement)init).Variables.First(); + iteratorVariable = new VariableInitializer() { + Identifier = new VariableIdentifier { Name = var.Name }, + Type = (AstType)((CSharp.VariableDeclarationStatement)init).Type.AcceptVisitor(this, data), + Expression = (Expression)var.Initializer.AcceptVisitor(this, data) + }; + } else if (init is CSharp.ExpressionStatement) { + iteratorVariable = init.AcceptVisitor(this, data); + } else goto end; + + Expression toExpr = Expression.Null; + + var cond = match.Get("condition").SingleOrDefault(); + var endExpr = (Expression)match.Get("endExpr").SingleOrDefault().AcceptVisitor(this, data); + + if (cond.Operator == CSharp.BinaryOperatorType.LessThanOrEqual || + cond.Operator == CSharp.BinaryOperatorType.GreaterThanOrEqual) { + toExpr = endExpr; + } + + if (cond.Operator == CSharp.BinaryOperatorType.LessThan) + toExpr = new BinaryOperatorExpression(endExpr, BinaryOperatorType.Subtract, new PrimitiveExpression(1)); + if (cond.Operator == CSharp.BinaryOperatorType.GreaterThan) + toExpr = new BinaryOperatorExpression(endExpr, BinaryOperatorType.Add, new PrimitiveExpression(1)); + + Expression stepExpr = Expression.Null; + + var increment = match.Get("increment").SingleOrDefault(); + var factorExpr = (Expression)match.Get("factor").SingleOrDefault().AcceptVisitor(this, data); + + if (increment.Operator == CSharp.AssignmentOperatorType.Add && (factorExpr is PrimitiveExpression && !IsEqual(((PrimitiveExpression)factorExpr).Value, 1))) + stepExpr = factorExpr; + if (increment.Operator == CSharp.AssignmentOperatorType.Subtract) + stepExpr = new UnaryOperatorExpression(UnaryOperatorType.Minus, factorExpr); + + return new ForStatement() { + Variable = iteratorVariable, + ToExpression = toExpr, + StepExpression = stepExpr, + Body = (BlockStatement)match.Get("body").Single().AcceptVisitor(this, data) + }; + } + + end: + 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); + } + + bool IsEqual(object value, int num) + { + if (value is byte) + return (byte)value == num; + if (value is sbyte) + return (sbyte)value == num; + if (value is short) + return (short)value == num; + if (value is ushort) + return (ushort)value == num; + if (value is int) + return (int)value == num; + if (value is uint) + return (uint)value == num; + if (value is long) + return (long)value == num; + if (value is ulong) + return (ulong)value == (ulong)num; + + throw new InvalidCastException(); + } + + public AstNode VisitGotoCaseStatement(CSharp.GotoCaseStatement gotoCaseStatement, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitGotoDefaultStatement(CSharp.GotoDefaultStatement gotoDefaultStatement, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitGotoStatement(CSharp.GotoStatement gotoStatement, object data) + { + return EndNode(gotoStatement, new GoToStatement() { Label = new IdentifierExpression() { Identifier = gotoStatement.Label } }); + } + + public AstNode VisitIfElseStatement(CSharp.IfElseStatement ifElseStatement, object data) + { + var stmt = new IfElseStatement(); + + stmt.Condition = (Expression)ifElseStatement.Condition.AcceptVisitor(this, data); + stmt.Body = (Statement)ifElseStatement.TrueStatement.AcceptVisitor(this, data); + stmt.ElseBlock = (Statement)ifElseStatement.FalseStatement.AcceptVisitor(this, data); + + return EndNode(ifElseStatement, stmt); + } + + public AstNode VisitLabelStatement(CSharp.LabelStatement labelStatement, object data) + { + return EndNode(labelStatement, new LabelDeclarationStatement() { Label = new IdentifierExpression() { Identifier = labelStatement.Label } }); + } + + public AstNode VisitLockStatement(CSharp.LockStatement lockStatement, object data) + { + 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) + { + var stmt = new ReturnStatement((Expression)returnStatement.Expression.AcceptVisitor(this, data)); + + return EndNode(returnStatement, stmt); + } + + public AstNode VisitSwitchStatement(CSharp.SwitchStatement switchStatement, object data) + { + var stmt = new SelectStatement() { Expression = (Expression)switchStatement.Expression.AcceptVisitor(this, data) }; + ConvertNodes(switchStatement.SwitchSections, stmt.Cases); + + return EndNode(switchStatement, stmt); + } + + public AstNode VisitSwitchSection(CSharp.SwitchSection switchSection, object data) + { + var caseStmt = new CaseStatement(); + ConvertNodes(switchSection.CaseLabels, caseStmt.Clauses); + if (switchSection.Statements.Count == 1 && switchSection.Statements.FirstOrDefault() is CSharp.BlockStatement) + caseStmt.Body = (BlockStatement)switchSection.Statements.FirstOrDefault().AcceptVisitor(this, data); + else { + caseStmt.Body = new BlockStatement(); + ConvertNodes(switchSection.Statements, caseStmt.Body.Statements); + } + if (caseStmt.Body.LastOrDefault() is ExitStatement && ((ExitStatement)caseStmt.Body.LastOrDefault()).ExitKind == ExitKind.Select) + caseStmt.Body.LastOrDefault().Remove(); + return EndNode(switchSection, caseStmt); + } + + public AstNode VisitCaseLabel(CSharp.CaseLabel caseLabel, object data) + { + return EndNode(caseLabel, new SimpleCaseClause() { Expression = (Expression)caseLabel.Expression.AcceptVisitor(this, data) }); + } + + public AstNode VisitThrowStatement(CSharp.ThrowStatement throwStatement, object data) + { + return EndNode(throwStatement, new ThrowStatement((Expression)throwStatement.Expression.AcceptVisitor(this, data))); + } + + public AstNode VisitTryCatchStatement(CSharp.TryCatchStatement tryCatchStatement, object data) + { + var stmt = new TryStatement(); + + stmt.Body = (BlockStatement)tryCatchStatement.TryBlock.AcceptVisitor(this, data); + stmt.FinallyBlock = (BlockStatement)tryCatchStatement.FinallyBlock.AcceptVisitor(this, data); + ConvertNodes(tryCatchStatement.CatchClauses, stmt.CatchBlocks); + + return EndNode(tryCatchStatement, stmt); + } + + public AstNode VisitCatchClause(CSharp.CatchClause catchClause, object data) + { + var clause = new CatchBlock(); + + clause.ExceptionType = (AstType)catchClause.Type.AcceptVisitor(this, data); + clause.ExceptionVariable = catchClause.VariableName; + ConvertNodes(catchClause.Body.Statements, clause.Statements); + + return EndNode(catchClause, clause); + } + + public AstNode VisitUncheckedStatement(CSharp.UncheckedStatement uncheckedStatement, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitUnsafeStatement(CSharp.UnsafeStatement unsafeStatement, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitUsingStatement(CSharp.UsingStatement usingStatement, object data) + { + var stmt = new UsingStatement(); + + stmt.Resources.Add(usingStatement.ResourceAcquisition.AcceptVisitor(this, data)); + stmt.Body = (BlockStatement)usingStatement.EmbeddedStatement.AcceptVisitor(this, data); + + return EndNode(usingStatement, stmt); + } + + public AstNode VisitVariableDeclarationStatement(CSharp.VariableDeclarationStatement variableDeclarationStatement, object data) + { + var decl = new LocalDeclarationStatement(); + decl.Modifiers = Modifiers.Dim; + ConvertNodes(variableDeclarationStatement.Variables, decl.Variables); + + return EndNode(variableDeclarationStatement, decl); + } + + public AstNode VisitWhileStatement(CSharp.WhileStatement whileStatement, object data) + { + var stmt = new WhileStatement() { + Condition = (Expression)whileStatement.Condition.AcceptVisitor(this, data), + Body = (BlockStatement)whileStatement.EmbeddedStatement.AcceptVisitor(this, data) + }; + + return EndNode(whileStatement, stmt); + } + + public AstNode VisitYieldBreakStatement(CSharp.YieldBreakStatement yieldBreakStatement, object data) + { + var frame = members.Peek(); + frame.inIterator = true; + return EndNode(yieldBreakStatement, new ReturnStatement()); + } + + public AstNode VisitYieldStatement(CSharp.YieldStatement yieldStatement, object data) + { + var frame = members.Peek(); + frame.inIterator = true; + return EndNode(yieldStatement, new YieldStatement((Expression)yieldStatement.Expression.AcceptVisitor(this, data))); + } + + public AstNode VisitAccessor(CSharp.Accessor accessor, object data) + { + var result = new Accessor(); + + ConvertNodes(accessor.Attributes, result.Attributes); + ConvertNodes(accessor.ModifierTokens, result.ModifierTokens); + result.Body = (BlockStatement)accessor.Body.AcceptVisitor(this, data); + + return EndNode(accessor, result); + } + + public AstNode VisitConstructorDeclaration(CSharp.ConstructorDeclaration constructorDeclaration, object data) + { + var result = new ConstructorDeclaration(); + + ConvertNodes(constructorDeclaration.Attributes, result.Attributes); + ConvertNodes(constructorDeclaration.ModifierTokens, result.ModifierTokens); + ConvertNodes(constructorDeclaration.Parameters, result.Parameters); + result.Body = (BlockStatement)constructorDeclaration.Body.AcceptVisitor(this, data); + if (!constructorDeclaration.Initializer.IsNull) + result.Body.Statements.InsertBefore(result.Body.FirstOrDefault(), (Statement)constructorDeclaration.Initializer.AcceptVisitor(this, data)); + + return EndNode(constructorDeclaration, result); + } + + public AstNode VisitConstructorInitializer(CSharp.ConstructorInitializer constructorInitializer, object data) + { + var result = new InvocationExpression( + new MemberAccessExpression() { + Target = new InstanceExpression(constructorInitializer.ConstructorInitializerType == CSharp.ConstructorInitializerType.This ? InstanceExpressionType.Me : InstanceExpressionType.MyBase, AstLocation.Empty), + MemberName = new Identifier("New", AstLocation.Empty) + } + ); + ConvertNodes(constructorInitializer.Arguments, result.Arguments); + + return EndNode(constructorInitializer, new ExpressionStatement(result)); + } + + public AstNode VisitDestructorDeclaration(CSharp.DestructorDeclaration destructorDeclaration, object data) + { + var finalizer = new MethodDeclaration() { Name = "Finalize", IsSub = true }; + + ConvertNodes(destructorDeclaration.Attributes, finalizer.Attributes); + ConvertNodes(destructorDeclaration.ModifierTokens, finalizer.ModifierTokens); + finalizer.Body = (BlockStatement)destructorDeclaration.Body.AcceptVisitor(this, data); + + return EndNode(destructorDeclaration, finalizer); + } + + public AstNode VisitEnumMemberDeclaration(CSharp.EnumMemberDeclaration enumMemberDeclaration, object data) + { + var result = new EnumMemberDeclaration(); + + ConvertNodes(enumMemberDeclaration.Attributes, result.Attributes); + result.Name = new Identifier(enumMemberDeclaration.Name, AstLocation.Empty); + result.Value = (Expression)enumMemberDeclaration.Initializer.AcceptVisitor(this, data); + + return EndNode(enumMemberDeclaration, result); + } + + public AstNode VisitEventDeclaration(CSharp.EventDeclaration eventDeclaration, object data) + { + members.Push(new MemberInfo()); + + foreach (var evt in eventDeclaration.Variables) { + var result = new EventDeclaration(); + + ConvertNodes(eventDeclaration.Attributes, result.Attributes); + if (types.Any() && types.Peek().ClassType == ClassType.Module) + eventDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + result.Modifiers = ConvertModifiers(eventDeclaration.Modifiers, eventDeclaration); + result.Name = evt.Name; + result.ReturnType = (AstType)eventDeclaration.ReturnType.AcceptVisitor(this, data); + +// CreateImplementsClausesForEvent(result); + + types.Peek().Members.Add(result); + } + + members.Pop(); + + return EndNode(eventDeclaration, null); + } + + public AstNode VisitCustomEventDeclaration(CSharp.CustomEventDeclaration customEventDeclaration, object data) + { + var result = new EventDeclaration(); + + members.Push(new MemberInfo()); + + ConvertNodes(customEventDeclaration.Attributes, result.Attributes); + if (types.Any() && types.Peek().ClassType == ClassType.Module) + customEventDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + result.Modifiers = ConvertModifiers(customEventDeclaration.Modifiers, customEventDeclaration); + result.IsCustom = true; + result.Name = new Identifier(customEventDeclaration.Name, AstLocation.Empty); + result.ReturnType = (AstType)customEventDeclaration.ReturnType.AcceptVisitor(this, data); + if (!customEventDeclaration.PrivateImplementationType.IsNull) + result.ImplementsClause.Add( + new InterfaceMemberSpecifier((AstType)customEventDeclaration.PrivateImplementationType.AcceptVisitor(this, data), customEventDeclaration.Name)); +// else +// CreateImplementsClausesForEvent(result); + result.AddHandlerBlock = (Accessor)customEventDeclaration.AddAccessor.AcceptVisitor(this, data); + result.RemoveHandlerBlock = (Accessor)customEventDeclaration.RemoveAccessor.AcceptVisitor(this, data); + + members.Pop(); + + return EndNode(customEventDeclaration, result); + } + + public AstNode VisitFieldDeclaration(CSharp.FieldDeclaration fieldDeclaration, object data) + { + var decl = new FieldDeclaration(); + + members.Push(new MemberInfo()); + + ConvertNodes(fieldDeclaration.Attributes, decl.Attributes); + if (types.Any() && types.Peek().ClassType == ClassType.Module) + fieldDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + decl.Modifiers = ConvertModifiers(fieldDeclaration.Modifiers, fieldDeclaration); + ConvertNodes(fieldDeclaration.Variables, decl.Variables); + + members.Pop(); + + return EndNode(fieldDeclaration, decl); + } + + public AstNode VisitIndexerDeclaration(CSharp.IndexerDeclaration indexerDeclaration, object data) + { + var decl = new PropertyDeclaration(); + + members.Push(new MemberInfo()); + + ConvertNodes(indexerDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), decl.Attributes); + decl.Getter = (Accessor)indexerDeclaration.Getter.AcceptVisitor(this, data); + if (types.Any() && types.Peek().ClassType == ClassType.Module) + indexerDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + decl.Modifiers = ConvertModifiers(indexerDeclaration.Modifiers, indexerDeclaration); + decl.Name = new Identifier(indexerDeclaration.Name, AstLocation.Empty); + ConvertNodes(indexerDeclaration.Parameters, decl.Parameters); + ConvertNodes(indexerDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), decl.ReturnTypeAttributes); + if (!indexerDeclaration.PrivateImplementationType.IsNull) + decl.ImplementsClause.Add( + new InterfaceMemberSpecifier((AstType)indexerDeclaration.PrivateImplementationType.AcceptVisitor(this, data), + indexerDeclaration.Name)); + decl.ReturnType = (AstType)indexerDeclaration.ReturnType.AcceptVisitor(this, data); + decl.Setter = (Accessor)indexerDeclaration.Setter.AcceptVisitor(this, data); + + if (!decl.Setter.IsNull) { + decl.Setter.Parameters.Add(new ParameterDeclaration() { + Name = new Identifier("value", AstLocation.Empty), + Type = (AstType)indexerDeclaration.ReturnType.AcceptVisitor(this, data), + }); + } + + members.Pop(); + + return EndNode(indexerDeclaration, decl); + } + + public AstNode VisitMethodDeclaration(CSharp.MethodDeclaration methodDeclaration, object data) + { + CSharp.Attribute attr; + + if (types.Any() && types.Peek().ClassType == ClassType.Module) + methodDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + + if ((methodDeclaration.Modifiers & CSharp.Modifiers.Extern) == CSharp.Modifiers.Extern && HasAttribute(methodDeclaration.Attributes, "System.Runtime.InteropServices.DllImportAttribute", out attr)) { + var result = new ExternalMethodDeclaration(); + + members.Push(new MemberInfo()); + + // remove AttributeSection if only one attribute is present + var attrSec = (CSharp.AttributeSection)attr.Parent; + if (attrSec.Attributes.Count == 1) + attrSec.Remove(); + else + attr.Remove(); + + result.Library = (attr.Arguments.First().AcceptVisitor(this, data) as PrimitiveExpression).Value.ToString(); + result.CharsetModifier = ConvertCharset(attr.Arguments); + result.Alias = ConvertAlias(attr.Arguments); + + ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes); + ConvertNodes(methodDeclaration.ModifierTokens, result.ModifierTokens); + result.Name = new Identifier(methodDeclaration.Name, AstLocation.Empty); + result.IsSub = IsSub(methodDeclaration.ReturnType); + ConvertNodes(methodDeclaration.Parameters, result.Parameters); + ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes); + if (!result.IsSub) + result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data); + + if (members.Pop().inIterator) { + result.Modifiers |= Modifiers.Iterator; + } + + return EndNode(methodDeclaration, result); + } else { + var result = new MethodDeclaration(); + + members.Push(new MemberInfo()); + + ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes); + ConvertNodes(methodDeclaration.ModifierTokens, result.ModifierTokens); + result.Name = new Identifier(methodDeclaration.Name, AstLocation.Empty); + result.IsSub = IsSub(methodDeclaration.ReturnType); + ConvertNodes(methodDeclaration.Parameters, result.Parameters); + ConvertNodes(methodDeclaration.TypeParameters, result.TypeParameters); + ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes); + if (!methodDeclaration.PrivateImplementationType.IsNull) + result.ImplementsClause.Add( + new InterfaceMemberSpecifier((AstType)methodDeclaration.PrivateImplementationType.AcceptVisitor(this, data), + methodDeclaration.Name)); +// else +// CreateImplementsClausesForMethod(result); + if (!result.IsSub) + result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data); + + if (methodDeclaration.IsExtensionMethod) { + result.Attributes.Add( + new AttributeBlock { + Attributes = { + new Ast.Attribute { + Type = AstType.FromName("System.Runtime.CompilerServices.ExtensionAttribute") + } + } + }); + } + + result.Body = (BlockStatement)methodDeclaration.Body.AcceptVisitor(this, data); + + if (members.Pop().inIterator) { + result.Modifiers |= Modifiers.Iterator; + } + + return EndNode(methodDeclaration, result); + } + } + + void CreateImplementsClausesForMethod(MethodDeclaration result) + { + if (!types.Any()) return; + var current = types.Peek(); + if (current.ClassType == ClassType.Interface) + return; + + foreach (var type in current.ImplementsTypes) { + var resolved = provider.ResolveType(type, current); + var found = resolved.GetMembers(provider.ResolveContext, m => m.EntityType == EntityType.Method && m.Name == result.Name.Name); + if (found.FirstOrDefault() != null) { + result.ImplementsClause.Add(new InterfaceMemberSpecifier((AstType)type.Clone(), found.FirstOrDefault().Name)); + } + } + } + + void CreateImplementsClausesForEvent(EventDeclaration result) + { + if (!types.Any()) return; + var current = types.Peek(); + if (current.ClassType == ClassType.Interface) + return; + + foreach (var type in current.ImplementsTypes) { + var resolved = provider.ResolveType(type, current); + var found = resolved.GetMembers(provider.ResolveContext, m => m.EntityType == EntityType.Event && m.Name == result.Name.Name); + if (found.FirstOrDefault() != null) { + result.ImplementsClause.Add(new InterfaceMemberSpecifier((AstType)type.Clone(), found.FirstOrDefault().Name)); + } + } + } + + string ConvertAlias(CSharp.AstNodeCollection arguments) + { + var pattern = new CSharp.AssignmentExpression() { + Left = new CSharp.IdentifierExpression("EntryPoint"), + Operator = CSharp.AssignmentOperatorType.Assign, + Right = new AnyNode("alias") + }; + + var result = arguments + .Select(expr => pattern.Match(expr)) + .FirstOrDefault(r => r.Success); + + if (result.Success && result.Has("alias")) { + return result.Get("alias") + .First().Value.ToString(); + } + + return null; + } + + CharsetModifier ConvertCharset(CSharp.AstNodeCollection arguments) + { + var pattern = new CSharp.AssignmentExpression() { + Left = new CSharp.IdentifierExpression("CharSet"), + Operator = CSharp.AssignmentOperatorType.Assign, + Right = new NamedNode( + "modifier", + new CSharp.MemberReferenceExpression() { + Target = new CSharp.IdentifierExpression("CharSet") + }) + }; + + var result = arguments + .Select(expr => pattern.Match(expr)) + .FirstOrDefault(r => r.Success); + + if (result.Success && result.Has("modifier")) { + switch (result.Get("modifier").First().MemberName) { + case "Auto": + return CharsetModifier.Auto; + case "Ansi": + return CharsetModifier.Ansi; + case "Unicode": + return CharsetModifier.Unicode; + } + } + + return CharsetModifier.None; + } + + bool IsSub(CSharp.AstType returnType) + { + var t = returnType as CSharp.PrimitiveType; + return t != null && t.Keyword == "void"; + } + + public AstNode VisitOperatorDeclaration(CSharp.OperatorDeclaration operatorDeclaration, object data) + { + MemberDeclaration result; + members.Push(new MemberInfo()); + + if (types.Any() && types.Peek().ClassType == ClassType.Module) + operatorDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + + if (operatorDeclaration.OperatorType == CSharp.OperatorType.Increment || operatorDeclaration.OperatorType == CSharp.OperatorType.Decrement) { + var m = new MethodDeclaration(); + result = m; + + ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), m.Attributes); + ConvertNodes(operatorDeclaration.ModifierTokens, m.ModifierTokens); + m.Name = operatorDeclaration.OperatorType == CSharp.OperatorType.Increment ? "op_Increment" : "op_Decrement"; + ConvertNodes(operatorDeclaration.Parameters, m.Parameters); + ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), m.ReturnTypeAttributes); + m.ReturnType = (AstType)operatorDeclaration.ReturnType.AcceptVisitor(this, data); + m.Body = (BlockStatement)operatorDeclaration.Body.AcceptVisitor(this, data); + } else { + var op = new OperatorDeclaration(); + result = op; + + ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), op.Attributes); + ConvertNodes(operatorDeclaration.ModifierTokens, op.ModifierTokens); + switch (operatorDeclaration.OperatorType) { + case ICSharpCode.NRefactory.CSharp.OperatorType.LogicalNot: + case ICSharpCode.NRefactory.CSharp.OperatorType.OnesComplement: + op.Operator = OverloadableOperatorType.Not; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.True: + op.Operator = OverloadableOperatorType.IsTrue; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.False: + op.Operator = OverloadableOperatorType.IsFalse; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Implicit: + op.Modifiers |= Modifiers.Widening; + op.Operator = OverloadableOperatorType.CType; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Explicit: + op.Modifiers |= Modifiers.Narrowing; + op.Operator = OverloadableOperatorType.CType; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Addition: + op.Operator = OverloadableOperatorType.Add; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Subtraction: + op.Operator = OverloadableOperatorType.Subtract; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.UnaryPlus: + op.Operator = OverloadableOperatorType.UnaryPlus; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.UnaryNegation: + op.Operator = OverloadableOperatorType.UnaryMinus; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Multiply: + op.Operator = OverloadableOperatorType.Multiply; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Division: + op.Operator = OverloadableOperatorType.Divide; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Modulus: + op.Operator = OverloadableOperatorType.Modulus; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.BitwiseAnd: + op.Operator = OverloadableOperatorType.BitwiseAnd; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.BitwiseOr: + op.Operator = OverloadableOperatorType.BitwiseOr; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.ExclusiveOr: + op.Operator = OverloadableOperatorType.ExclusiveOr; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.LeftShift: + op.Operator = OverloadableOperatorType.ShiftLeft; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.RightShift: + op.Operator = OverloadableOperatorType.ShiftRight; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Equality: + op.Operator = OverloadableOperatorType.Equality; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.Inequality: + op.Operator = OverloadableOperatorType.InEquality; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.GreaterThan: + op.Operator = OverloadableOperatorType.GreaterThan; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.LessThan: + op.Operator = OverloadableOperatorType.LessThan; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.GreaterThanOrEqual: + op.Operator = OverloadableOperatorType.GreaterThanOrEqual; + break; + case ICSharpCode.NRefactory.CSharp.OperatorType.LessThanOrEqual: + op.Operator = OverloadableOperatorType.LessThanOrEqual; + break; + default: + throw new Exception("Invalid value for OperatorType"); + } + ConvertNodes(operatorDeclaration.Parameters, op.Parameters); + ConvertNodes(operatorDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), op.ReturnTypeAttributes); + op.ReturnType = (AstType)operatorDeclaration.ReturnType.AcceptVisitor(this, data); + op.Body = (BlockStatement)operatorDeclaration.Body.AcceptVisitor(this, data); + } + + members.Pop(); + + return EndNode(operatorDeclaration, result); + + } + + public AstNode VisitParameterDeclaration(CSharp.ParameterDeclaration parameterDeclaration, object data) + { + var param = new ParameterDeclaration(); + + ConvertNodes(parameterDeclaration.Attributes, param.Attributes); + param.Modifiers = ConvertParamModifiers(parameterDeclaration.ParameterModifier); + if ((param.Modifiers & Modifiers.None) == Modifiers.None) + param.Modifiers = Modifiers.ByVal; + if ((parameterDeclaration.ParameterModifier & ICSharpCode.NRefactory.CSharp.ParameterModifier.Out) == ICSharpCode.NRefactory.CSharp.ParameterModifier.Out) { + AttributeBlock block = new AttributeBlock(); + block.Attributes.Add(new Ast.Attribute() { Type = new SimpleType("System.Runtime.InteropServices.OutAttribute") }); + param.Attributes.Add(block); + } + param.Name = new Identifier(parameterDeclaration.Name, AstLocation.Empty); + param.Type = (AstType)parameterDeclaration.Type.AcceptVisitor(this, data); + param.OptionalValue = (Expression)parameterDeclaration.DefaultExpression.AcceptVisitor(this, data); + if (!param.OptionalValue.IsNull) + param.Modifiers |= Modifiers.Optional; + + return EndNode(parameterDeclaration, param); + } + + Modifiers ConvertParamModifiers(CSharp.ParameterModifier mods) + { + switch (mods) { + case ICSharpCode.NRefactory.CSharp.ParameterModifier.None: + case ICSharpCode.NRefactory.CSharp.ParameterModifier.This: + return Modifiers.None; + case ICSharpCode.NRefactory.CSharp.ParameterModifier.Ref: + return Modifiers.ByRef; + case ICSharpCode.NRefactory.CSharp.ParameterModifier.Out: + return Modifiers.ByRef; + case ICSharpCode.NRefactory.CSharp.ParameterModifier.Params: + return Modifiers.ParamArray; + default: + throw new Exception("Invalid value for ParameterModifier"); + } + } + + public AstNode VisitPropertyDeclaration(CSharp.PropertyDeclaration propertyDeclaration, object data) + { + var decl = new PropertyDeclaration(); + + members.Push(new MemberInfo()); + + if (types.Any() && types.Peek().ClassType == ClassType.Module) + propertyDeclaration.Modifiers &= ~CSharp.Modifiers.Static; + + ConvertNodes(propertyDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), decl.Attributes); + decl.Getter = (Accessor)propertyDeclaration.Getter.AcceptVisitor(this, data); + decl.Modifiers = ConvertModifiers(propertyDeclaration.Modifiers, propertyDeclaration); + decl.Name = new Identifier(propertyDeclaration.Name, AstLocation.Empty); + ConvertNodes(propertyDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), decl.ReturnTypeAttributes); + if (!propertyDeclaration.PrivateImplementationType.IsNull) + decl.ImplementsClause.Add( + new InterfaceMemberSpecifier((AstType)propertyDeclaration.PrivateImplementationType.AcceptVisitor(this, data), + propertyDeclaration.Name)); + decl.ReturnType = (AstType)propertyDeclaration.ReturnType.AcceptVisitor(this, data); + decl.Setter = (Accessor)propertyDeclaration.Setter.AcceptVisitor(this, data); + + if (!decl.Setter.IsNull) { + decl.Setter.Parameters.Add(new ParameterDeclaration() { + Name = new Identifier("value", AstLocation.Empty), + Type = (AstType)propertyDeclaration.ReturnType.AcceptVisitor(this, data), + }); + } + + if (members.Pop().inIterator) { + decl.Modifiers |= Modifiers.Iterator; + } + + return EndNode(propertyDeclaration, decl); + } + + public AstNode VisitVariableInitializer(CSharp.VariableInitializer variableInitializer, object data) + { + var decl = new VariableDeclaratorWithTypeAndInitializer(); + + // look for type in parent + decl.Type = (AstType)variableInitializer.Parent + .GetChildByRole(CSharp.VariableInitializer.Roles.Type) + .AcceptVisitor(this, data); + decl.Identifiers.Add(new VariableIdentifier() { Name = variableInitializer.Name }); + decl.Initializer = (Expression)variableInitializer.Initializer.AcceptVisitor(this, data); + + return EndNode(variableInitializer, decl); + } + + public AstNode VisitFixedFieldDeclaration(CSharp.FixedFieldDeclaration fixedFieldDeclaration, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitFixedVariableInitializer(CSharp.FixedVariableInitializer fixedVariableInitializer, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitCompilationUnit(CSharp.CompilationUnit compilationUnit, object data) + { + var unit = new CompilationUnit(); + + foreach (var node in compilationUnit.Children) + unit.AddChild(node.AcceptVisitor(this, null), CompilationUnit.MemberRole); + + return EndNode(compilationUnit, unit); + } + + public AstNode VisitSimpleType(CSharp.SimpleType simpleType, object data) + { + var type = new SimpleType(simpleType.Identifier); + ConvertNodes(simpleType.TypeArguments, type.TypeArguments); + + return EndNode(simpleType, type); + } + + public AstNode VisitMemberType(CSharp.MemberType memberType, object data) + { + AstType target = null; + + if (memberType.Target is CSharp.SimpleType && ((CSharp.SimpleType)(memberType.Target)).Identifier.Equals("global", StringComparison.Ordinal)) + target = new PrimitiveType("Global"); + else + target = (AstType)memberType.Target.AcceptVisitor(this, data); + + var type = new QualifiedType(target, new Identifier(memberType.MemberName, AstLocation.Empty)); + ConvertNodes(memberType.TypeArguments, type.TypeArguments); + + return EndNode(memberType, type); + } + + public AstNode VisitComposedType(CSharp.ComposedType composedType, object data) + { + AstType type = new ComposedType(); + + ConvertNodes(composedType.ArraySpecifiers, ((ComposedType)type).ArraySpecifiers); + ((ComposedType)type).BaseType = (AstType)composedType.BaseType.AcceptVisitor(this, data); + ((ComposedType)type).HasNullableSpecifier = composedType.HasNullableSpecifier; + + for (int i = 0; i < composedType.PointerRank; i++) { + var tmp = new SimpleType() { Identifier = "__Pointer" }; + tmp.TypeArguments.Add(type); + type = tmp; + } + + return EndNode(composedType, type); + } + + public AstNode VisitArraySpecifier(CSharp.ArraySpecifier arraySpecifier, object data) + { + return EndNode(arraySpecifier, new ArraySpecifier(arraySpecifier.Dimensions)); + } + + public AstNode VisitPrimitiveType(CSharp.PrimitiveType primitiveType, object data) + { + string typeName; + + switch (primitiveType.Keyword) { + case "object": + typeName = "Object"; + break; + case "bool": + typeName = "Boolean"; + break; + case "char": + typeName = "Char"; + break; + case "sbyte": + typeName = "SByte"; + break; + case "byte": + typeName = "Byte"; + break; + case "short": + typeName = "Short"; + break; + case "ushort": + typeName = "UShort"; + break; + case "int": + typeName = "Integer"; + break; + case "uint": + typeName = "UInteger"; + break; + case "long": + typeName = "Long"; + break; + case "ulong": + typeName = "ULong"; + break; + case "float": + typeName = "Single"; + break; + case "double": + typeName = "Double"; + break; + case "decimal": + typeName = "Decimal"; + break; + case "string": + typeName = "String"; + break; + // generic constraints + case "new": + typeName = "New"; + break; + case "struct": + typeName = "Structure"; + break; + case "class": + typeName = "Class"; + break; + case "void": + typeName = "Void"; + break; + default: + typeName = "unknown"; + break; + } + + return EndNode(primitiveType, new PrimitiveType(typeName)); + } + + public AstNode VisitComment(CSharp.Comment comment, object data) + { + var c = new Comment(comment.Content, comment.CommentType == CSharp.CommentType.Documentation); + + if (comment.CommentType == CSharp.CommentType.MultiLine) + throw new NotImplementedException(); + + return EndNode(comment, c); + } + + public AstNode VisitTypeParameterDeclaration(CSharp.TypeParameterDeclaration typeParameterDeclaration, object data) + { + var param = new TypeParameterDeclaration() { + Variance = typeParameterDeclaration.Variance, + Name = typeParameterDeclaration.Name + }; + + var constraint = typeParameterDeclaration.Parent + .GetChildrenByRole(CSharp.AstNode.Roles.Constraint) + .SingleOrDefault(c => c.TypeParameter == typeParameterDeclaration.Name); + + ConvertNodes(constraint == null ? Enumerable.Empty() : constraint.BaseTypes, param.Constraints); + + // TODO : typeParameterDeclaration.Attributes get lost? + //ConvertNodes(typeParameterDeclaration.Attributes + + return EndNode(typeParameterDeclaration, param); + } + + public AstNode VisitConstraint(CSharp.Constraint constraint, object data) + { + throw new NotImplementedException(); + } + + public AstNode VisitCSharpTokenNode(CSharp.CSharpTokenNode cSharpTokenNode, object data) + { + var mod = cSharpTokenNode as CSharp.CSharpModifierToken; + if (mod != null) { + var convertedModifiers = ConvertModifiers(mod.Modifier, mod.Parent); + VBModifierToken token = null; + if (convertedModifiers != Modifiers.None) { + token = new VBModifierToken(AstLocation.Empty, convertedModifiers); + return EndNode(cSharpTokenNode, token); + } + return EndNode(cSharpTokenNode, token); + } else { + throw new NotSupportedException("Should never visit individual tokens"); + } + } + + Modifiers ConvertModifiers(CSharp.Modifiers modifier, CSharp.AstNode container) + { + if ((modifier & CSharp.Modifiers.Any) == CSharp.Modifiers.Any) + return Modifiers.Any; + + var mod = Modifiers.None; + + if ((modifier & CSharp.Modifiers.Const) == CSharp.Modifiers.Const) + mod |= Modifiers.Const; + if ((modifier & CSharp.Modifiers.Abstract) == CSharp.Modifiers.Abstract) { + if (container is CSharp.TypeDeclaration) + mod |= Modifiers.MustInherit; + else + mod |= Modifiers.MustOverride; + } + if ((modifier & CSharp.Modifiers.Static) == CSharp.Modifiers.Static) + mod |= Modifiers.Shared; + + if ((modifier & CSharp.Modifiers.Public) == CSharp.Modifiers.Public) + mod |= Modifiers.Public; + if ((modifier & CSharp.Modifiers.Protected) == CSharp.Modifiers.Protected) + mod |= Modifiers.Protected; + if ((modifier & CSharp.Modifiers.Internal) == CSharp.Modifiers.Internal) + mod |= Modifiers.Friend; + if ((modifier & CSharp.Modifiers.Private) == CSharp.Modifiers.Private) + mod |= Modifiers.Private; + if (container is CSharp.IndexerDeclaration) + mod |= Modifiers.Default; + bool writeable = IsWriteableProperty(container); + bool readable = IsReadableProperty(container); + if (writeable && !readable) + mod |= Modifiers.WriteOnly; + if (readable && !writeable) + mod |= Modifiers.ReadOnly; + + if ((modifier & CSharp.Modifiers.Override) == CSharp.Modifiers.Override) + mod |= Modifiers.Overrides; + if ((modifier & CSharp.Modifiers.Virtual) == CSharp.Modifiers.Virtual) + mod |= Modifiers.Overridable; + + return mod; + } + + bool IsReadableProperty(ICSharpCode.NRefactory.CSharp.AstNode container) + { + if (container is CSharp.IndexerDeclaration) { + var i = container as CSharp.IndexerDeclaration; + return !i.Getter.IsNull; + } + + if (container is CSharp.PropertyDeclaration) { + var p = container as CSharp.PropertyDeclaration; + return !p.Getter.IsNull; + } + + return false; + } + + bool IsWriteableProperty(ICSharpCode.NRefactory.CSharp.AstNode container) + { + if (container is CSharp.IndexerDeclaration) { + var i = container as CSharp.IndexerDeclaration; + return !i.Setter.IsNull; + } + + if (container is CSharp.PropertyDeclaration) { + var p = container as CSharp.PropertyDeclaration; + return !p.Setter.IsNull; + } + + return false; + } + + public AstNode VisitIdentifier(CSharp.Identifier identifier, object data) + { + var ident = new Identifier(identifier.Name, ConvertLocation(identifier.StartLocation)); + + return EndNode(identifier, ident); + } + + public AstNode VisitPatternPlaceholder(CSharp.AstNode placeholder, ICSharpCode.NRefactory.PatternMatching.Pattern pattern, object data) + { + throw new NotImplementedException(); + } + + void ConvertNodes(IEnumerable nodes, VB.AstNodeCollection result) where T : VB.AstNode + { + foreach (var node in nodes) { + T n = (T)node.AcceptVisitor(this, null); + if (n != null) + result.Add(n); + } + } + + AstLocation ConvertLocation(CSharp.AstLocation location) + { + return new AstLocation(location.Line, location.Column); + } + + T EndNode(CSharp.AstNode node, T result) where T : VB.AstNode + { + if (result != null) { + CopyAnnotations(node, result); + } + + return result; + } + + void CopyAnnotations(CSharp.AstNode node, T result) where T : VB.AstNode + { + foreach (var ann in node.Annotations) + result.AddAnnotation(ann); + } + + bool HasAttribute(CSharp.AstNodeCollection attributes, string name, out CSharp.Attribute foundAttribute) + { + foreach (var attr in attributes.SelectMany(a => a.Attributes)) { + if (provider.GetTypeNameForAttribute(attr) == name) { + foundAttribute = attr; + return true; + } + } + foundAttribute = null; + return false; + } + } +} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs index 31d1232323..85ff7a7bd2 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/OperatorDeclaration.cs @@ -28,7 +28,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.