Fable
Fable copied to clipboard
CLIEvent and Object expressions
Description
The CLIEvent property seems to be missing from object expressions.
Repro code
open System
type InterfaceWithCLIEvent<'t> =
[<CLIEvent>]
abstract Event : IEvent<System.Action<obj,'t>,'t>
let event = Event<Action<obj, bool>,bool>()
let ifaceWIthEvent =
{ new InterfaceWithCLIEvent<_> with
[<CLIEvent>]
member __.Event = event.Publish }
Expected and actual results
In JavaScript this compiles to:
import Event$ from "fable-library/Event.js";
export const event = new Event$();
export const ifaceWIthEvent = {
add_Event(handler) {
event.Publish.AddHandler(handler);
},
remove_Event(handler_1) {
event.Publish.RemoveHandler(handler_1);
},
};
So the Event property is gone. I came across this issue since Python uses interfaces and I get the error: Can't instantiate abstract class ObjectExpr0 with abstract method Event
Interface looks like this:
class InterfaceWithCLIEvent_1(Protocol, Generic[_T]):
@abstractmethod
def add_event(self, __arg0: Any) -> None:
...
@property
@abstractmethod
def Event(self) -> IEvent_2[Any, _T]:
...
@abstractmethod
def remove_event(self, __arg0: Any) -> None:
...
So the Event is part of the interface, but not part of the implementation. If you implement a class using the interface, then the property will be available.
Related information
- Fable version: repl4
- Operating system
Thanks for reporting @dbrattli! I need to have a look. Actually I never wanted to add Events to Fable, because I like Observables much better (current support has been mostly done by Krzystof and ncave) so I don't remember all the fitting parts 😅
Yes, the only reference I can find is: https://github.com/fable-compiler/Fable/blob/main/src/fcs-fable/src/Compiler/Checking/CheckExpressions.fs#L2745 Is that where this things happen?
Hmm, that's the "trimmed down FCS" created by @ncave that we use to self-compile Fable.Standalone. But Fable.Cli doesn't use fable-fcs but a custom build also from ncave's FCS fork (service_slim branch). If we need to generate some code for object expressions implementing Events I assume we have to do it either here (for Fable AST) or here (for Babel/JS AST).
The problem is that the main property seem to have been removed, so it's not that easy to know that you have to re-add it just by looking for the _remove and _add methods. Anyways, consider this low-priority. I'm not using it for anything, just porting more tests to Python.
@dbrattli I'm no expert, but it looks like this is how F# compiler (FCS) works for [<CLIEvent>] properties. In any case, it is not something that Fable is doing or changing.
Can you perhaps just not output (in the interface) any property with [<CLIEvent>] attribute, instead of trying to re-add the property in the object expression? (Technically that should be done for all languages that emit interfaces, so in Rust too).
@dbrattli @alfonsogarciacaro Looks like Dart also generates interfaces, so it has to be fixed there too (to not output [<CLIEvent>] properties in the interface).