zeroc-ice / ice

All-in-one solution for creating networked applications with RPC, pub/sub, server deployment, and more.
https://zeroc.com
GNU General Public License v2.0
2.04k stars 592 forks source link

Generate dispatch with SwiftSyntax in Swift #2273

Open bernardnormier opened 3 months ago

bernardnormier commented 3 months ago

In Swift, the base protocol for all dispatchers is Ice.Dispatcher:

/// A dispatcher accepts incoming requests and returns outgoing responses.
public protocol Dispatcher {
    /// Dispatches an incoming request and returns the corresponding outgoing response.
    /// - Parameter request: The incoming request.
    /// - Returns: The outgoing response, wrapped in a Promise.
    func dispatch(_ request: IncomingRequest) -> Promise<OutgoingResponse>
}

And a given Slice interface MyInterface, the slice2swift compiler generates:

This structure is the result of Swift's method dispatching rules. In particular, a default implementation of the Dispatcher.dispatch method provided by an extension MyInterface would not be virtual. So it works fine as long as there is no inheritance... but we want inheritance to work.

Splitting the server-side generated code in protocol + struct is naturally not ideal.

A possible alternative would be to do like in IceRPC C# and use a source generator - SwiftSyntax (https://github.com/apple/swift-syntax) to add conformance to the Dispatcher protocol. The generated method needs to be inside the user class (not in an extension) because we want this method to be "virtual" and overridden in derived classes.