From 74c376bb98e4b5eb11147b357b34b34c523d76c7 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 15 May 2011 13:48:51 +0200 Subject: [PATCH] implement PropertyDeclaration; add Inherits/Implements to TypeDeclaration; implement output for DelegateDeclaration --- ILSpy/VB/VBLanguage.cs | 48 +++++- .../Ast/GlobalScope/TypeDeclaration.cs | 1 + .../Ast/TypeMembers/Accessor.cs | 49 ++++++ .../Ast/TypeMembers/FieldDeclaration.cs | 89 +++++++++++ .../Ast/TypeMembers/MethodDeclaration.cs | 82 +--------- .../Ast/TypeMembers/PropertyDeclaration.cs | 57 +++++++ .../Ast/VBModifierToken.cs | 16 +- .../ICSharpCode.NRefactory.VB/IAstVisitor.cs | 2 + .../ICSharpCode.NRefactory.VB.csproj | 3 + .../OutputVisitor/OutputVisitor.cs | 140 +++++++++++++++++- .../Visitors/CSharpToVBConverterVisitor.cs | 106 +++++++++++-- 11 files changed, 497 insertions(+), 96 deletions(-) create mode 100644 NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/Accessor.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/PropertyDeclaration.cs diff --git a/ILSpy/VB/VBLanguage.cs b/ILSpy/VB/VBLanguage.cs index c1b139d34..64b645c1d 100644 --- a/ILSpy/VB/VBLanguage.cs +++ b/ILSpy/VB/VBLanguage.cs @@ -18,12 +18,14 @@ using System; using System.ComponentModel.Composition; +using System.IO; using System.Linq; - +using System.Text; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Ast; using ICSharpCode.Decompiler.Ast.Transforms; using ICSharpCode.ILSpy.XmlDoc; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.VB; using ICSharpCode.NRefactory.VB.Visitors; using Mono.Cecil; @@ -125,6 +127,32 @@ namespace ICSharpCode.ILSpy.VB Settings = settings }); } + + public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null) + { + ConvertTypeOptions options = ConvertTypeOptions.IncludeTypeParameterDefinitions; + if (includeNamespace) + options |= ConvertTypeOptions.IncludeNamespace; + var astType = AstBuilder + .ConvertType(type, typeAttributes, options) + .AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null); + + StringWriter w = new StringWriter(); + // TODO +// if (type.IsByReference) { +// ParameterDefinition pd = typeAttributes as ParameterDefinition; +// if (pd != null && (!pd.IsIn && pd.IsOut)) +// w.Write("out "); +// else +// w.Write("ref "); +// +// if (astType is ComposedType && ((ComposedType)astType).PointerRank > 0) +// ((ComposedType)astType).PointerRank--; +// } + + astType.AcceptVisitor(new OutputVisitor(w, new VBFormattingOptions()), null); + return w.ToString(); + } } public class ILSpyEnvironmentProvider : IEnvironmentProvider @@ -142,5 +170,23 @@ namespace ICSharpCode.ILSpy.VB .First() .FullName; } + + public ClassType GetClassTypeForAstType(ICSharpCode.NRefactory.CSharp.AstType type) + { + var definition = type.Annotations.OfType().First(); + + if (definition.IsClass) + return ClassType.Class; + if (definition.IsInterface) + return ClassType.Interface; + if (definition.IsEnum) + return ClassType.Enum; + if (definition.IsFunctionPointer) + return ClassType.Delegate; + if (definition.IsValueType) + return ClassType.Struct; + + return ClassType.Module; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs index 28b669d9c..1c7af2966 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs @@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.VB.Ast public AstType InheritsType { get { return GetChildByRole(InheritsTypeRole); } + set { SetChildByRole(InheritsTypeRole, value); } } public AstNodeCollection ImplementsTypes { diff --git a/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/Accessor.cs b/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/Accessor.cs new file mode 100644 index 000000000..87a2f53e2 --- /dev/null +++ b/NRefactory/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 the GNU LGPL (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/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs new file mode 100644 index 000000000..fa093e045 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs @@ -0,0 +1,89 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory.VB.Ast +{ + /// + /// 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); + } + } + + /// + /// VariableIdentifiers As ObjectCreationExpression
+ /// VariableIdentifiers ( As TypeName )? ( Equals Expression )? + ///
+ public class VariableDeclarator : AstNode + { + public static readonly Role VariableDeclaratorRole = new Role("VariableDeclarator"); + + public AstNodeCollection Identifiers { + get { return GetChildrenByRole(VariableIdentifier.VariableIdentifierRole); } + } + + 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.VisitVariableDeclarator(this, data); + } + } + + /// + /// Identifier IdentifierModifiers + /// + public class VariableIdentifier : AstNode + { + public static readonly Role VariableIdentifierRole = new Role("VariableIdentifier"); + + 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/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/MethodDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/MethodDeclaration.cs index e3614e2f5..dd699c601 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/MethodDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/MethodDeclaration.cs @@ -70,85 +70,7 @@ 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); - } - } - - /// - /// VariableIdentifiers As ObjectCreationExpression
- /// VariableIdentifiers ( As TypeName )? ( Equals Expression )? - ///
- public class VariableDeclarator : AstNode - { - public static readonly Role VariableDeclaratorRole = new Role("VariableDeclarator"); - - public AstNodeCollection Identifiers { - get { return GetChildrenByRole(VariableIdentifier.VariableIdentifierRole); } - } - - 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.VisitVariableDeclarator(this, data); - } - } + - /// - /// Identifier IdentifierModifiers - /// - public class VariableIdentifier : AstNode - { - public static readonly Role VariableIdentifierRole = new Role("VariableIdentifier"); - - 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/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/PropertyDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/PropertyDeclaration.cs new file mode 100644 index 000000000..1b0a7d7d2 --- /dev/null +++ b/NRefactory/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 the GNU LGPL (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/NRefactory/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs b/NRefactory/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs index 05a22acc4..427d3e53d 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/Ast/VBModifierToken.cs @@ -57,7 +57,11 @@ 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), // 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) @@ -117,8 +121,16 @@ 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"; default: - throw new NotSupportedException("Invalid value for Modifiers"); + throw new NotSupportedException("Invalid value for Modifiers: " + modifier); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs b/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs index 4f2342273..394b3ae2a 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs @@ -37,6 +37,8 @@ namespace ICSharpCode.NRefactory.VB { S VisitFieldDeclaration(FieldDeclaration fieldDeclaration, T data); S VisitVariableDeclarator(VariableDeclarator variableDeclarator, T data); S VisitVariableIdentifier(VariableIdentifier variableIdentifier, T data); + S VisitAccessor(Accessor accessor, T data); + S VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, T data); // Expression scope S VisitIdentifier(Identifier identifier, T data); diff --git a/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj b/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj index 4b176c48a..5034fbfd7 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj +++ b/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj @@ -82,8 +82,11 @@ + + + diff --git a/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs b/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs index c6f67ebd0..94efbb685 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs @@ -77,7 +77,32 @@ 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) @@ -191,6 +216,12 @@ namespace ICSharpCode.NRefactory.VB WriteModifiers(typeDeclaration.ModifierTokens); WriteClassTypeKeyword(typeDeclaration); WriteIdentifier(typeDeclaration.Name.Name); + if (!typeDeclaration.InheritsType.IsNull) { + Space(); + WriteKeyword("Inherits"); + typeDeclaration.InheritsType.AcceptVisitor(this, data); + } + WriteImplementsClause(typeDeclaration.ImplementsTypes); NewLine(); WriteMembers(typeDeclaration.Members); @@ -241,7 +272,27 @@ namespace ICSharpCode.NRefactory.VB 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) @@ -416,7 +467,8 @@ namespace ICSharpCode.NRefactory.VB methodDeclaration.Name.AcceptVisitor(this, data); WriteTypeParameters(methodDeclaration.TypeParameters); WriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, false); - if (!methodDeclaration.IsSub) { + if (!methodDeclaration.IsSub && !methodDeclaration.ReturnType.IsNull) { + Space(); WriteKeyword("As"); WriteAttributes(methodDeclaration.ReturnTypeAttributes); methodDeclaration.ReturnType.AcceptVisitor(this, data); @@ -462,7 +514,14 @@ namespace ICSharpCode.NRefactory.VB 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) @@ -991,6 +1050,16 @@ namespace ICSharpCode.NRefactory.VB void WriteImplementsClause(AstNodeCollection implementsClause) { if (implementsClause.Any()) { + Space(); + WriteKeyword("Implements"); + WriteCommaSeparatedList(implementsClause); + } + } + + void WriteImplementsClause(AstNodeCollection implementsClause) + { + if (implementsClause.Any()) { + Space(); WriteKeyword("Implements"); WriteCommaSeparatedList(implementsClause); } @@ -999,6 +1068,7 @@ namespace ICSharpCode.NRefactory.VB void WriteHandlesClause(AstNodeCollection handlesClause) { if (handlesClause.Any()) { + Space(); WriteKeyword("Handles"); WriteCommaSeparatedList(handlesClause); } @@ -1150,5 +1220,67 @@ namespace ICSharpCode.NRefactory.VB 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"); + } + if (accessor.Parameters.Any()) + WriteCommaSeparatedListInParenthesis(accessor.Parameters, false); + NewLine(); + + WriteBlock(accessor.Body); + + WriteKeyword("End"); + + if (accessor.Role == PropertyDeclaration.GetterRole) { + WriteKeyword("Get"); + } else if (accessor.Role == PropertyDeclaration.SetterRole) { + WriteKeyword("Set"); + } + NewLine(); + + return EndNode(accessor); + } + + 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); + } + NewLine(); + Indent(); + + if (!propertyDeclaration.Getter.IsNull) { + propertyDeclaration.Getter.AcceptVisitor(this, data); + } + + if (!propertyDeclaration.Setter.IsNull) { + propertyDeclaration.Setter.AcceptVisitor(this, data); + } + Unindent(); + + WriteKeyword("End"); + WriteKeyword("Property"); + NewLine(); + + return EndNode(propertyDeclaration); + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs b/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs index 89f22afbf..43eb59c1a 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs @@ -14,6 +14,7 @@ namespace ICSharpCode.NRefactory.VB.Visitors { string RootNamespace { get; } string GetTypeNameForAttribute(CSharp.Attribute attribute); + ClassType GetClassTypeForAstType(CSharp.AstType type); } /// @@ -286,7 +287,18 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitDelegateDeclaration(CSharp.DelegateDeclaration delegateDeclaration, object data) { - throw new NotImplementedException(); + 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) @@ -320,6 +332,16 @@ namespace ICSharpCode.NRefactory.VB.Visitors 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 = new Identifier(typeDeclaration.Name, AstLocation.Empty); ConvertNodes(typeDeclaration.Members, type.Members); @@ -361,7 +383,7 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitBlockStatement(CSharp.BlockStatement blockStatement, object data) { - throw new NotImplementedException(); + return null; } public AstNode VisitBreakStatement(CSharp.BreakStatement breakStatement, object data) @@ -511,7 +533,13 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitAccessor(CSharp.Accessor accessor, object data) { - throw new NotImplementedException(); + 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) @@ -563,7 +591,29 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitIndexerDeclaration(CSharp.IndexerDeclaration indexerDeclaration, object data) { - throw new NotImplementedException(); + var decl = new PropertyDeclaration(); + + ConvertNodes(indexerDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), decl.Attributes); + decl.Getter = (Accessor)indexerDeclaration.Getter.AcceptVisitor(this, data); + 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), +// }); + } + + return EndNode(indexerDeclaration, decl); } public AstNode VisitMethodDeclaration(CSharp.MethodDeclaration methodDeclaration, object data) @@ -577,9 +627,10 @@ namespace ICSharpCode.NRefactory.VB.Visitors ConvertNodes(methodDeclaration.Parameters, result.Parameters); ConvertNodes(methodDeclaration.TypeParameters, result.TypeParameters); ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes); - result.ImplementsClause.Add( - new InterfaceMemberSpecifier((AstType)methodDeclaration.PrivateImplementationType.AcceptVisitor(this, data), - methodDeclaration.Name)); + if (!methodDeclaration.PrivateImplementationType.IsNull) + result.ImplementsClause.Add( + new InterfaceMemberSpecifier((AstType)methodDeclaration.PrivateImplementationType.AcceptVisitor(this, data), + methodDeclaration.Name)); if (!result.IsSub) result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data); @@ -603,6 +654,8 @@ namespace ICSharpCode.NRefactory.VB.Visitors ConvertNodes(parameterDeclaration.Attributes, param.Attributes); param.Modifiers = ConvertParamModifiers(parameterDeclaration.ParameterModifier); + if ((param.Modifiers & Modifiers.None) == Modifiers.None) + param.Modifiers = Modifiers.ByVal; param.Name = new Identifier(parameterDeclaration.Name, AstLocation.Empty); param.Type = (AstType)parameterDeclaration.Type.AcceptVisitor(this, data); param.OptionalValue = (Expression)parameterDeclaration.DefaultExpression.AcceptVisitor(this, data); @@ -631,7 +684,28 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitPropertyDeclaration(CSharp.PropertyDeclaration propertyDeclaration, object data) { - return null; + var decl = new PropertyDeclaration(); + + 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), + }); + } + + return EndNode(propertyDeclaration, decl); } public AstNode VisitVariableInitializer(CSharp.VariableInitializer variableInitializer, object data) @@ -757,6 +831,16 @@ namespace ICSharpCode.NRefactory.VB.Visitors case "string": typeName = "String"; break; + // generic constraints + case "new": + typeName = "New"; + break; + case "struct": + typeName = "Structure"; + break; + case "class": + typeName = "Class"; + break; default: typeName = "unknown"; break; @@ -777,7 +861,11 @@ namespace ICSharpCode.NRefactory.VB.Visitors Name = typeParameterDeclaration.Name }; - // TODO : fetch constraints from parent node + 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