diff --git a/ILSpy/VB/ILSpyEnvironmentProvider.cs b/ILSpy/VB/ILSpyEnvironmentProvider.cs index 05c7c1bc7..12592a540 100644 --- a/ILSpy/VB/ILSpyEnvironmentProvider.cs +++ b/ILSpy/VB/ILSpyEnvironmentProvider.cs @@ -139,5 +139,19 @@ namespace ICSharpCode.ILSpy.VB } } + public bool HasEvent(NRefactory.VB.Ast.Expression expression) + { + return expression.Annotation<EventDefinition>() != null; + } + + public bool IsMethodGroup(ICSharpCode.NRefactory.CSharp.Expression expression) + { + var annotation = expression.Annotation<MethodDefinition>(); + if (annotation != null) { + return true; + } + + return false; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/AddRemoveHandlerStatement.cs b/NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/AddRemoveHandlerStatement.cs new file mode 100644 index 000000000..7a46c8c66 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/AddRemoveHandlerStatement.cs @@ -0,0 +1,38 @@ +// 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 +{ + /// <summary> + /// ( AddHandler | RemoveHandler ) Expression, Expression + /// </summary> + public class AddRemoveHandlerStatement : Statement + { + public static readonly Role<Expression> EventExpressionRole = new Role<Expression>("EventExpression", Expression.Null); + public static readonly Role<Expression> DelegateExpressionRole = new Role<Expression>("DelegateExpression", Expression.Null); + + public bool IsAddHandler { get; set; } + + public Expression EventExpression { + get { return GetChildByRole(EventExpressionRole); } + set { SetChildByRole(EventExpressionRole, value); } + } + + public Expression DelegateExpression { + get { return GetChildByRole(DelegateExpressionRole); } + set { SetChildByRole(DelegateExpressionRole, value); } + } + + public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data) + { + return visitor.VisitAddRemoveHandlerStatement(this, data); + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs b/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs index c24e2b617..2726c6106 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs @@ -75,6 +75,7 @@ namespace ICSharpCode.NRefactory.VB { S VisitLabelDeclarationStatement(LabelDeclarationStatement labelDeclarationStatement, T data); S VisitLocalDeclarationStatement(LocalDeclarationStatement localDeclarationStatement, T data); S VisitExpressionStatement(ExpressionStatement expressionStatement, T data); + S VisitAddRemoveHandlerStatement(AddRemoveHandlerStatement addRemoveHandlerStatement, T data); S VisitWithStatement(WithStatement withStatement, T data); S VisitSyncLockStatement(SyncLockStatement syncLockStatement, T data); S VisitIfElseStatement(IfElseStatement ifElseStatement, T data); diff --git a/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj b/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj index cc8a37d55..6e5e4cc38 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj +++ b/NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj @@ -103,6 +103,7 @@ <Compile Include="Ast\GlobalScope\OptionStatement.cs" /> <Compile Include="Ast\Identifier.cs" /> <Compile Include="Ast\INullable.cs" /> + <Compile Include="Ast\Statements\AddRemoveHandlerStatement.cs" /> <Compile Include="Ast\Statements\BlockStatement.cs" /> <Compile Include="Ast\Statements\ContinueStatement.cs" /> <Compile Include="Ast\Statements\DoLoopStatement.cs" /> diff --git a/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs b/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs index 7edd3a525..e3c2b977e 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs @@ -256,7 +256,7 @@ namespace ICSharpCode.NRefactory.VB } if (!typeDeclaration.InheritsType.IsNull || typeDeclaration.ImplementsTypes.Any()) - NewLine(); + NewLine(); WriteMembers(typeDeclaration.Members); @@ -397,6 +397,8 @@ namespace ICSharpCode.NRefactory.VB { StartNode(primitiveExpression); + if (lastWritten == LastWritten.KeywordOrIdentifier) + Space(); WritePrimitiveValue(primitiveExpression.Value); return EndNode(primitiveExpression); @@ -895,6 +897,10 @@ namespace ICSharpCode.NRefactory.VB // formatter.Space(); // } formatter.WriteToken(token); + if (token == ",") { + lastWritten = LastWritten.Whitespace; + Space(); + } // if (token == "+") // lastWritten = LastWritten.Plus; // else if (token == "-") @@ -2655,5 +2661,21 @@ namespace ICSharpCode.NRefactory.VB return EndNode(groupJoinQueryOperator); } + + public object VisitAddRemoveHandlerStatement(AddRemoveHandlerStatement addRemoveHandlerStatement, object data) + { + StartNode(addRemoveHandlerStatement); + + if (addRemoveHandlerStatement.IsAddHandler) + WriteKeyword("AddHandler"); + else + WriteKeyword("RemoveHandler"); + + addRemoveHandlerStatement.EventExpression.AcceptVisitor(this, data); + WriteToken(",", VBTokenNode.Roles.Comma); + addRemoveHandlerStatement.DelegateExpression.AcceptVisitor(this, data); + + return EndNode(addRemoveHandlerStatement); + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs b/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs index 88caf76b5..1c562e187 100644 --- a/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs @@ -20,6 +20,8 @@ namespace ICSharpCode.NRefactory.VB.Visitors bool? IsReferenceType(CSharp.Expression expression); //ITypeResolveContext ResolveContext { get; } IType ResolveType(AstType type, TypeDeclaration entity = null); + bool IsMethodGroup(CSharp.Expression expression); + bool HasEvent(Expression expression); } /// <summary> @@ -126,9 +128,21 @@ namespace ICSharpCode.NRefactory.VB.Visitors op = AssignmentOperatorType.Assign; break; case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Add: + if (provider.HasEvent(left)) { + var addHandler = new AddRemoveHandlerStatement { IsAddHandler = true }; + addHandler.EventExpression = left; + addHandler.DelegateExpression = right; + return EndNode(assignmentExpression, addHandler); + } op = AssignmentOperatorType.Add; break; case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Subtract: + if (provider.HasEvent(left)) { + var addHandler = new AddRemoveHandlerStatement { IsAddHandler = false }; + addHandler.EventExpression = left; + addHandler.DelegateExpression = right; + return EndNode(assignmentExpression, addHandler); + } op = AssignmentOperatorType.Subtract; break; case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Multiply: @@ -359,6 +373,9 @@ namespace ICSharpCode.NRefactory.VB.Visitors var expr = new IdentifierExpression(); expr.Identifier = new Identifier(identifierExpression.Identifier, TextLocation.Empty); ConvertNodes(identifierExpression.TypeArguments, expr.TypeArguments); + if (provider.IsMethodGroup(identifierExpression)) { + return EndNode(identifierExpression, new UnaryOperatorExpression(UnaryOperatorType.AddressOf, expr)); + } return EndNode(identifierExpression, expr); } @@ -372,10 +389,8 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitInvocationExpression(CSharp.InvocationExpression invocationExpression, object data) { - var expr = new InvocationExpression( - (Expression)invocationExpression.Target.AcceptVisitor(this, data)); + var expr = new InvocationExpression((Expression)invocationExpression.Target.AcceptVisitor(this, data)); ConvertNodes(invocationExpression.Arguments, expr.Arguments); - return EndNode(invocationExpression, expr); } @@ -412,6 +427,9 @@ namespace ICSharpCode.NRefactory.VB.Visitors memberAccessExpression.Target = (Expression)memberReferenceExpression.Target.AcceptVisitor(this, data); memberAccessExpression.MemberName = new Identifier(memberReferenceExpression.MemberName, TextLocation.Empty); ConvertNodes(memberReferenceExpression.TypeArguments, memberAccessExpression.TypeArguments); + if (provider.IsMethodGroup(memberReferenceExpression)) { + return EndNode(memberReferenceExpression, new UnaryOperatorExpression(UnaryOperatorType.AddressOf, memberAccessExpression)); + } return EndNode(memberReferenceExpression, memberAccessExpression); } @@ -445,6 +463,11 @@ namespace ICSharpCode.NRefactory.VB.Visitors { var expr = new ObjectCreationExpression((AstType)objectCreateExpression.Type.AcceptVisitor(this, data)); ConvertNodes(objectCreateExpression.Arguments, expr.Arguments); + var arg1 = expr.Arguments.FirstOrDefault() as UnaryOperatorExpression; + if (arg1 != null && arg1.Operator == UnaryOperatorType.AddressOf) { + arg1.Remove(); + return EndNode(objectCreateExpression, arg1); + } if (!objectCreateExpression.Initializer.IsNull) expr.Initializer = (ArrayInitializerExpression)objectCreateExpression.Initializer.AcceptVisitor(this, data); @@ -1036,8 +1059,10 @@ namespace ICSharpCode.NRefactory.VB.Visitors public AstNode VisitExpressionStatement(CSharp.ExpressionStatement expressionStatement, object data) { - var expr = new ExpressionStatement((Expression)expressionStatement.Expression.AcceptVisitor(this, data)); - return EndNode(expressionStatement, expr); + var node = expressionStatement.Expression.AcceptVisitor(this, data); + if (node is Expression) + node = new ExpressionStatement((Expression)node); + return EndNode(expressionStatement, node); } public AstNode VisitFixedStatement(CSharp.FixedStatement fixedStatement, object data)