ObservableEvents icon indicating copy to clipboard operation
ObservableEvents copied to clipboard

Wrong observable event signature generated for events hidden in the inheriting class

Open Metadorius opened this issue 1 year ago • 4 comments

Description

When using the source generator on newest DevExpress WinForms controls (using .NET Framework 4.8) the result can't be compiled because of some wrongly generated code. It seems that PaintEx signature differs from what the source generator assumes, so the result can't be compiled.

How to repro

  1. Install DevExpress WinForms components (23.2.4 as of time of writing) trial from here
  2. Clone https://github.com/kpCat/ObservableEventsDevexpressRepro
  3. Attempt to build the solution

Result

The following error pops up on compilation:

4>SourceClassDevExpress.XtraEditors.TextEdit-InstanceEvents.SourceGenerated.cs(440,13): Error CS0123 : No overloaded method for "Handler" that corresponds to the delegate "TextEditPaintExEventHandler".

Metadorius avatar Feb 06 '24 17:02 Metadorius

Thanks,

Third party libraries are a bit hard for us to test against even with trials.

Is PaintEx a generic type?

glennawatson avatar Feb 07 '24 00:02 glennawatson

Third party libraries are a bit hard for us to test against even with trials.

Let me help you then.

This is what gets generated:

        public global::System.IObservable<global::DevExpress.Utils.XtraPaintEventArgs> PaintEx=>global::System.Reactive.Linq.Observable.Create<global::DevExpress.Utils.XtraPaintEventArgs>(obs=>
        {
            void Handler( object sender, global::DevExpress.Utils.XtraPaintEventArgs e) =>obs.OnNext(e);
            _data.PaintEx+=Handler;
            return global::System.Reactive.Disposables.Disposable.Create(() => _data.PaintEx-=Handler);
        });

The analysis-reported error: image

I digged into decompile and figured out that the base XtraControl that is used by all DevExpress controls has PaintEx method which gets picked up by the source generator:

    public event XtraPaintEventHandler PaintEx
    {
      add => this.Events.AddHandler(XtraControl.paintEx, (Delegate) value);
      remove => this.Events.RemoveHandler(XtraControl.paintEx, (Delegate) value);
    }

The TextEdit and other controls define another event that hides the parent's event with another signature:

    public event TextEditPaintExEventHandler PaintEx
    {
      add => this.Events.AddHandler(TextEdit.paintEx, (Delegate) value);
      remove => this.Events.RemoveHandler(TextEdit.paintEx, (Delegate) value);
    }

So it seems to me that the source generator just incorrectly uses the hidden event instead of the new one.

Metadorius avatar Feb 07 '24 10:02 Metadorius

Any news? Or perhaps there is some existing workaround for the time being to somehow disable some part of the codegen just to make it compile, apart from manually doing ye olde FromEventPattern?

Metadorius avatar Feb 15 '24 13:02 Metadorius