Check that an event subscription has the corresponding unsubscription code (+= / -=)

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

7 comments

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

0

Thank you for the quick answer !

0

One more question

How can I do to ensure that the IReferenceExpression resolves to an event ?

0

referenceExpression.Reference.Resolve().DeclaredElement is IEvent

0

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

0

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

0

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!

0

Please sign in to leave a comment.