提交 f8bf0253 编写于 作者: G Gen Lu

Reverted the change for receiver in static event assignment and add more tests

上级 d500d521
......@@ -365,7 +365,7 @@ private IEventAssignmentExpression CreateBoundEventAssignmentOperatorOperation(B
// 2. the constant value of BoundEventAccess is always null.
// 3. the syntax of the boundEventAssignmentOperator is always AssignmentExpressionSyntax, so the syntax for the event reference would be the LHS of the assignment.
IEventSymbol @event = boundEventAssignmentOperator.Event;
Lazy<IOperation> instance = new Lazy<IOperation>(() => Create(boundEventAssignmentOperator.ReceiverOpt));
Lazy<IOperation> instance = new Lazy<IOperation>(() => Create(boundEventAssignmentOperator.Event.IsStatic ? null : boundEventAssignmentOperator.ReceiverOpt));
SyntaxNode eventAccessSyntax = ((AssignmentExpressionSyntax)syntax).Left;
return new LazyEventReferenceExpression(@event, instance, @event, eventAccessSyntax, @event.Type, ConvertToOptional(null));
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
......@@ -230,8 +231,8 @@ void M()
";
string expectedOperationTree = @"
IEventAssignmentExpression (EventAdd)) (OperationKind.EventAssignmentExpression, Type: System.Void, IsInvalid) (Syntax: 't.MyEvent += Handler')
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (OperationKind.EventReferenceExpression, Type: System.EventHandler, IsInvalid) (Syntax: 't.MyEvent')
Instance Receiver: ILocalReferenceExpression: t (OperationKind.LocalReferenceExpression, Type: Test, IsInvalid) (Syntax: 't')
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (Static) (OperationKind.EventReferenceExpression, Type: System.EventHandler, IsInvalid) (Syntax: 't.MyEvent')
Instance Receiver: null
Handler: IMethodBindingExpression: void C.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
";
......@@ -246,5 +247,82 @@ void M()
VerifyOperationTreeAndDiagnosticsForTest<AssignmentExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[Fact]
[WorkItem(8909, "https://github.com/dotnet/roslyn/issues/8909")]
public void AddEventHandler_AssignToNonStaticEventOnType()
{
string source = @"
using System;
class Test
{
public event EventHandler MyEvent;
}
class C
{
void Handler(object sender, EventArgs e)
{
}
void M()
{
/*<bind>*/Test.MyEvent += Handler/*<bind>*/;
}
}
";
string expectedOperationTree = @"
IEventAssignmentExpression (EventAdd)) (OperationKind.EventAssignmentExpression, Type: System.Void, IsInvalid) (Syntax: 'Test.MyEvent += Handler')
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (OperationKind.EventReferenceExpression, Type: System.EventHandler, IsInvalid) (Syntax: 'Test.MyEvent')
Instance Receiver: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'Test')
Handler: IMethodBindingExpression: void C.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')";
var expectedDiagnostics = new[] {
// file.cs(17,19): error CS0120: An object reference is required for the non-static field, method, or property 'Test.MyEvent'
// /*<bind>*/Test.MyEvent += Handler/*<bind>*/;
Diagnostic(ErrorCode.ERR_ObjectRequired, "Test.MyEvent").WithArguments("Test.MyEvent").WithLocation(17, 19),
// file.cs(6,31): warning CS0067: The event 'Test.MyEvent' is never used
// public event EventHandler MyEvent;
Diagnostic(ErrorCode.WRN_UnreferencedEvent, "MyEvent").WithArguments("Test.MyEvent").WithLocation(6, 31)
};
VerifyOperationTreeAndDiagnosticsForTest<AssignmentExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[Fact]
public void AddEventHandler_AssignToEventWithoutExplicitReceiver()
{
string source = @"
using System;
class Test
{
public event EventHandler MyEvent;
void Handler(object sender, EventArgs e)
{
}
void M()
{
/*<bind>*/MyEvent += Handler/*<bind>*/;
}
}
";
string expectedOperationTree = @"
IEventAssignmentExpression (EventAdd)) (OperationKind.EventAssignmentExpression, Type: System.Void) (Syntax: 'MyEvent += Handler')
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (OperationKind.EventReferenceExpression, Type: System.EventHandler) (Syntax: 'MyEvent')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Test) (Syntax: 'MyEvent')
Handler: IMethodBindingExpression: void Test.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Test) (Syntax: 'Handler')";
var expectedDiagnostics = new[] {
// file.cs(6,31): warning CS0067: The event 'Test.MyEvent' is never used
// public event EventHandler MyEvent;
Diagnostic(ErrorCode.WRN_UnreferencedEvent, "MyEvent").WithArguments("Test.MyEvent").WithLocation(6, 31)
};
VerifyOperationTreeAndDiagnosticsForTest<AssignmentExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
......@@ -574,7 +574,11 @@ Namespace Microsoft.CodeAnalysis.Semantics
Private Function CreateBoundEventAccessOperation(boundEventAccess As BoundEventAccess) As IEventReferenceExpression
Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(
Function()
Return Create(boundEventAccess.ReceiverOpt)
If boundEventAccess.EventSymbol.IsShared Then
Return Nothing
Else
Return Create(boundEventAccess.ReceiverOpt)
End If
End Function)
Dim [event] As IEventSymbol = boundEventAccess.EventSymbol
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics
......@@ -188,8 +189,8 @@ End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'AddHandler ... AddressOf M')
Expression: IEventAssignmentExpression (EventAdd)) (OperationKind.EventAssignmentExpression, Type: null) (Syntax: 'AddHandler ... AddressOf M')
Event Reference: IEventReferenceExpression: Event TestClass.TestEvent As System.Action (OperationKind.EventReferenceExpression, Type: System.Action) (Syntax: 'Me.TestEvent')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Explicit) (OperationKind.InstanceReferenceExpression, Type: TestClass) (Syntax: 'Me')
Event Reference: IEventReferenceExpression: Event TestClass.TestEvent As System.Action (Static) (OperationKind.EventReferenceExpression, Type: System.Action) (Syntax: 'Me.TestEvent')
Instance Receiver: null
Handler: IOperation: (OperationKind.None) (Syntax: 'AddressOf M')
Children(1):
IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: TestClass) (Syntax: 'M')
......@@ -203,5 +204,39 @@ BC42025: Access of shared member, constant member, enum member or nested type th
VerifyOperationTreeAndDiagnosticsForTest(Of AddRemoveHandlerStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<Fact>
<WorkItem(8909, "https://github.com/dotnet/roslyn/issues/8909")>
Public Sub AddEventHandler_AssignToNonSharedEventOnType()
Dim source = <![CDATA[
Imports System
Class TestClass
Event TestEvent As Action
Sub Remove()
AddHandler TestClass.TestEvent, AddressOf M 'BIND:"AddHandler TestClass.TestEvent, AddressOf M"
End Sub
Sub M()
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'AddHandler ... AddressOf M')
Expression: IEventAssignmentExpression (EventAdd)) (OperationKind.EventAssignmentExpression, Type: null, IsInvalid) (Syntax: 'AddHandler ... AddressOf M')
Event Reference: IEventReferenceExpression: Event TestClass.TestEvent As System.Action (OperationKind.EventReferenceExpression, Type: System.Action, IsInvalid) (Syntax: 'TestClass.TestEvent')
Instance Receiver: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'TestClass')
Handler: IOperation: (OperationKind.None) (Syntax: 'AddressOf M')
Children(1):
IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: TestClass) (Syntax: 'M')
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC30469: Reference to a non-shared member requires an object reference.
AddHandler TestClass.TestEvent, AddressOf M 'BIND:"AddHandler TestClass.TestEvent, AddressOf M"
~~~~~~~~~~~~~~~~~~~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of AddRemoveHandlerStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册