dotnet-websharper / core

WebSharper - Full-stack, functional, reactive web apps and microservices in F# and C#
https://websharper.com
Apache License 2.0
594 stars 52 forks source link

Interface merging #808

Open Jand42 opened 6 years ago

Jand42 commented 6 years ago

While converting to TypeScript (#789) It is becoming annoying that some System interfaces have generic and non-generic versions, and the members are needed to be redirected from one to other.

For example the hack at https://github.com/intellifactory/websharper/blob/master/src/stdlib/WebSharper.Main.Proxies/Enumerable.fs#L29 translates badly to TS as it is not defining a GetEnumerator0 member that would be used on calls through System.Collections.IEnumerable.

A way to simplify TS output and interoperability would be to merge the translated form of some interfaces with special logic. Fox example only one real implementation of GetEnumerable could be given, and both generic and non-generic versions would just translate to a TS class member named GetEnumerable.

Other similarly merged interfaces: IEnumerator, IComparable, IComparer, IEquatable, IEqualityComparer, and later collection interfaces (#576) when those are added to the proxies.

Jand42 commented 6 years ago

Previously Inline attribute was not allowed on interface implementation methods. This led to some duplicated instance members, one implementation redirecting to the other, for example in the case of the proxy for System.Collections.Generic.List.Enumerator<T> which defines MoveNext as a non-implementation member, and also twice as implementations for System.Collections.IEnumerator and System.Collections.Generic.IEnumerator<T>.

Now allowing Inline so that these instance members can be merged in the output, but this can also lead to incorrect behavior when the inline is not correct (redirecting to another instance member with the same name). Later a check can be added so that this is forced.

Jand42 commented 6 years ago

If an interface extends both IEnumerable and IEnumerable<T>, the non-generic version must be dropped because now they conflict in TS. Probably the same is needed with other merged interfaces, will test.