Check that an event subscription has the corresponding unsubscription code (+= / -=) Follow
Hi there !
I'd like to build a simple R# plugin that warns me whenever I subscribe to an event without unsubscription code. I'm not familiar with the R# API, but I started my plugin and I now have a process that looks like the following:
public class DaemonStageProcess : CSharpDaemonStageProcessBase
{
public DaemonStageProcess(IDaemonProcess process) : base(process)
{
}
public override void Execute(Action<DaemonStageResult> commiter)
{
HighlightInFile(file => file.ProcessDescendants(this), commiter);
}
public override void ProcessBeforeInterior(IElement element)
{
if(element is IAssignmentExpression)
{
var expression = (IAssignmentExpression) element;
if(expression.AssignmentType == AssignmentType.PLUSEQ)
{
// TODO...
}
}
}
}
My question are:
- am I on the right track ?
- how should I check, when I encounter a EventName += this.MethodName we have a EventName -= this.MethodName somewhere in the class ?
Thank you in advance for your help,
Jeremy
Please sign in to leave a comment.
Yes, you're on the right way.
1) Along with DaemonStageProcess, you have to create DaemonStage and mark it with [DaemonStage] attribute. Refer to the PowerToys for example
2) You have to collect all += and -= expressions where left operand is IReferenceExpression which resolves to event. Then match that expressions where these expressions are equal. You can compare expressions via MiscUtil.CompareExpressions
Thank you for the quick answer !
One more question
How can I do to ensure that the IReferenceExpression resolves to an event ?
referenceExpression.Reference.Resolve().DeclaredElement is IEvent
Ok...
And I hope the last question, how would you make the difference between a event owned by the class and an event that comes from a member of the class ?
For exemple:
public class PersonObserver
{
private Person person;
public event EventHandler LocalEvent;
}
I want to detect person.Renamed += ... but not LocalEvent += ...
Thank you very much for your help
You should cast left operand of += expression to IReferenceExpression
(You've definitely done this already to check if it refers to event)
Then check referenceExpression.QualifiedExpression
if it is 'null' or 'IThisExpression' - then the event is local
Otherwise, it belongs to other class
Hi there! I'm facing same issue as you did, Jeremy Alles! I wonder if you finished this plugin. If so, can you share it? I'd love to have it!