-
-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LSP server development #14
LSP server development #14
Conversation
NOTE: This PR depends on #13 so that should be merged first. Or could potentially be merged as part of this if that makes it easier. |
In the Hylo LSP I have separated NotificationHandler and RequestHandler, but since the protocols compose it is also possible to implementing them in the same actor, which is more similar to the current I to however think it would be best if the client side had similar setup as the server side. |
Ok #13 is now merged! I'm going to start looking at this more closely. |
import Logging | ||
|
||
public protocol ProtocolHandler { | ||
var connection: JSONRPCClientConnection { get } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This protocol gives me pause. A synchronous getter can be very problematic for an actor. I haven't yet looked closely enough to be sure, but it seems like it may be possible to make this { get async }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been refactored and the protocol is not there anymore, so not sure if it is still something that needs fixing in the updated changeset. This is a bit beyond my swift knowledge atm!
import Foundation | ||
import JSONRPC | ||
import LanguageServerProtocol | ||
import Logging |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Logging
still being used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logging usage has been removed
I explicitly do not squash to try to avoid conflict here, but it still happened... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is pretty stylistic, but it is uncommon (though not unheard of) to have module names with "-" in them. But, I think it's ok to just go with "LSPClient" and "LSPServer". I usually like to avoid acronyms, but in this case its already getting long and I don't think anyone will be confused.
Sounds good with rename. And I have removed Logger and ProtocolHandler. Also, regarding client side, not sure it needs to follow the same pattern as the server protocols, client development will typically use But also, the splitting of this repo into server/client parts makes the separation between |
At first, when I read your comment I thought "yes! why is there a LanguageClient package at all?" But, exploring that idea quickly led to a very good reason: the LanguageClient package has 6 dependencies. I agree that this is an awkward arrangement. I'm just not sure how to best balance these trade-offs. But I agree that whatever change, if any, we decide to do, can be done separately from this work. I'm going to give this another closer look this week. |
Ah, yes, additional dependencies makes sense as reason to keep it separate 👍 |
…oliyo/LanguageServerProtocol into feature/lsp-server-development
All requests need to respond, otherwise it is a notification, not a request
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some very minor stuff.
I was worried, at first, about the introduction of the handler protocols. But, I think that was largely overblown from having such a hard time doing similar (but not identical) work when adopting swift concurrency.
But after looking more closely, I think this is going to be just fine. Thanks so much for all your hard work here. I really appreciate it.
public init(ranges: [LSPRange], wordPattern: String? = nil) { | ||
self.ranges = ranges | ||
self.wordPattern = wordPattern | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed on purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge issue, restored now
@@ -2,7 +2,7 @@ import Foundation | |||
|
|||
public typealias MonikerClientCapabilities = DynamicRegistrationClientCapabilities | |||
|
|||
public struct MonikerParams: Codable, Hashable, Sendable { | |||
public struct MonkierParams: Codable, Hashable, Sendable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, fixed
|
||
public enum ClientNotification: Sendable, Hashable { | ||
public enum Method: String, Hashable, Sendable { | ||
case initialized | ||
case exit | ||
case windowWorkDoneProgressCancel = "window/workDoneProgress/cancel" | ||
case workspaceDidChangeWatchedFiles = "workspace/didChangeWatchedFiles" | ||
case workspaceDidChangeWatchedFiles = "workspace/workspaceDidChangeWatchedFiles" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy-paste error I bet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, yes!
enum ServerError: Error { | ||
case unrecognizedMethod(String) | ||
case missingParams | ||
case unhandledRegisterationMethod(String) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo "unhandledRegisterationMethod" -> unhandleRegistrationMethod"
I've addressed the comments, let me know if I missed anything, or if you have additional comments! |
I suspect we may still end up making some changes here and there. But, I think we're ready enough to make progress. Let's do it! Thank you so much for all of your hard work and patience. |
Support for serverside LSP development:
Split library in three parts
Renaming of
Server
concept/protocolCalling the clientside connection to the server makes sense in the client context, but makes things a bit confusing when working from the other side.
I have attempted to find a terminology that works well from both sides:
What was previously called
Server
, is nowServerConnection
. Where aServerConnection
contains:And with matching
ClientConnection
protocol on the server side.Serverside LSP developent
In addition to the
ClientConnection
protocol, the serverside library has additional support that can be reused for specific LSP implementations.The same pattern should probably be implemented in the client side, but first lets make sure we can agree on a design that seems reasonable and support both sides of the LSP protocol.
ClientConnection
JSONRPCClientConnection
ClientConnection
protocolRequestHandler
protocolCancelRequest
NotificationHandler
ErrorHandler
EventHandler
RequestHandler
,NotificationHandler
,ErrorHandler
EventDispatcher