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

Expose receiver for static event assignemt

上级 0e0e4efd
......@@ -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.Event.IsStatic ? null : boundEventAssignmentOperator.ReceiverOpt));
Lazy<IOperation> instance = new Lazy<IOperation>(() => Create(boundEventAssignmentOperator.ReceiverOpt));
SyntaxNode eventAccessSyntax = ((AssignmentExpressionSyntax)syntax).Left;
return new LazyEventReferenceExpression(@event, instance, @event, eventAccessSyntax, @event.Type, ConvertToOptional(null));
......
......@@ -203,5 +203,48 @@ void M()
VerifyOperationTreeAndDiagnosticsForTest<AssignmentExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[Fact]
public void AddEventHandler_AssignToStaticEventOnInstance()
{
string source = @"
using System;
class Test
{
public static event EventHandler MyEvent;
}
class C
{
void Handler(object sender, EventArgs e)
{
}
void M()
{
var t = new Test();
/*<bind>*/t.MyEvent += Handler/*<bind>*/;
}
}
";
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')
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(18,19): error CS0176: Member 'Test.MyEvent' cannot be accessed with an instance reference; qualify it with a type name instead
// /*<bind>*/t.MyEvent += Handler/*<bind>*/;
Diagnostic(ErrorCode.ERR_ObjectProhibited, "t.MyEvent").WithArguments("Test.MyEvent").WithLocation(18, 19),
// file.cs(6,38): warning CS0067: The event 'Test.MyEvent' is never used
// public static event EventHandler MyEvent;
Diagnostic(ErrorCode.WRN_UnreferencedEvent, "MyEvent").WithArguments("Test.MyEvent").WithLocation(6, 38)
};
VerifyOperationTreeAndDiagnosticsForTest<AssignmentExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
......@@ -574,11 +574,7 @@ Namespace Microsoft.CodeAnalysis.Semantics
Private Function CreateBoundEventAccessOperation(boundEventAccess As BoundEventAccess) As IEventReferenceExpression
Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(
Function()
If boundEventAccess.EventSymbol.IsShared Then
Return Nothing
Else
Return Create(boundEventAccess.ReceiverOpt)
End If
Return Create(boundEventAccess.ReceiverOpt)
End Function)
Dim [event] As IEventSymbol = boundEventAccess.EventSymbol
......
......@@ -169,5 +169,39 @@ BC31143: Method 'Public Sub M(x As Integer)' does not have a signature compatibl
VerifyOperationTreeAndDiagnosticsForTest(Of AddRemoveHandlerStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<Fact>
Public Sub AddEventHandler_AssignToSharedEventOnInstance()
Dim source = <![CDATA[
Imports System
Class TestClass
Shared Event TestEvent As Action
Sub Remove()
AddHandler Me.TestEvent, AddressOf M 'BIND:"AddHandler Me.TestEvent, AddressOf M"
End Sub
Sub M()
End Sub
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')
Handler: IOperation: (OperationKind.None) (Syntax: 'AddressOf M')
Children(1):
IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: TestClass) (Syntax: 'M')
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC42025: Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated.
AddHandler Me.TestEvent, AddressOf M 'BIND:"AddHandler Me.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.
先完成此消息的编辑!
想要评论请 注册