From 4fe57f12189ed8f64fe93f3e202acb3304039e37 Mon Sep 17 00:00:00 2001 From: tris203 Date: Fri, 28 Jun 2024 22:00:24 +0100 Subject: [PATCH 1/4] feat(protocol): Add custom request handling This commit introduces the ability to handle custom requests in the protocol package. A new struct, CustomRequestHandler, has been added which contains a Method and a Func. The Func is a function that takes a context and params and returns an error. The Handler struct now includes a slice of CustomRequestHandlers, and the Handle method has been updated to handle custom requests by unmarshalling the params into the handler's params and then calling the handler's Func. A new method, FindCustomRequestHandler, has been added to the Handler struct. This method takes a method string and returns the corresponding CustomRequestHandler and a boolean indicating whether the handler was found. The server's handle method has also been updated to handle errors from the Handler's Handle method. --- protocol_3_16/custom.go | 15 +++++++++++++++ protocol_3_16/handler.go | 24 ++++++++++++++++++++++++ protocol_3_17/custom.go | 15 +++++++++++++++ protocol_3_17/handler.go | 20 ++++++++++++++++++++ server/handler.go | 7 +++++-- 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 protocol_3_16/custom.go create mode 100644 protocol_3_17/custom.go diff --git a/protocol_3_16/custom.go b/protocol_3_16/custom.go new file mode 100644 index 0000000..cad7860 --- /dev/null +++ b/protocol_3_16/custom.go @@ -0,0 +1,15 @@ +package protocol + +import ( + "encoding/json" + + "github.com/tliron/glsp" +) + +type CustomRequestHandler struct { + Method string + Func CustomRequestFunc + params json.RawMessage +} + +type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) error diff --git a/protocol_3_16/handler.go b/protocol_3_16/handler.go index 1fa0c2b..680192e 100644 --- a/protocol_3_16/handler.go +++ b/protocol_3_16/handler.go @@ -82,6 +82,9 @@ type Handler struct { TextDocumentLinkedEditingRange TextDocumentLinkedEditingRangeFunc TextDocumentMoniker TextDocumentMonikerFunc + // Custom Request/Notification + CustomRequest []CustomRequestHandler + initialized bool lock sync.Mutex } @@ -709,11 +712,32 @@ func (self *Handler) Handle(context *glsp.Context) (r any, validMethod bool, val r, err = self.TextDocumentMoniker(context, ¶ms) } } + + default: + if self.CustomRequest != nil { + if handler, ok := self.FindCustomRequestHandler(context.Method); ok { + validMethod = true + if err = json.Unmarshal(context.Params, &handler.params); err == nil { + validParams = true + err = handler.Func(context, handler.params) + } + } + } + } return } +func (self *Handler) FindCustomRequestHandler(method string) (*CustomRequestHandler, bool) { + for _, handler := range self.CustomRequest { + if handler.Method == method { + return &handler, true + } + } + return nil, false +} + func (self *Handler) IsInitialized() bool { self.lock.Lock() defer self.lock.Unlock() diff --git a/protocol_3_17/custom.go b/protocol_3_17/custom.go new file mode 100644 index 0000000..cad7860 --- /dev/null +++ b/protocol_3_17/custom.go @@ -0,0 +1,15 @@ +package protocol + +import ( + "encoding/json" + + "github.com/tliron/glsp" +) + +type CustomRequestHandler struct { + Method string + Func CustomRequestFunc + params json.RawMessage +} + +type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) error diff --git a/protocol_3_17/handler.go b/protocol_3_17/handler.go index 5026a09..8874d8b 100644 --- a/protocol_3_17/handler.go +++ b/protocol_3_17/handler.go @@ -648,10 +648,30 @@ func (self *Handler) Handle(context *glsp.Context) (r any, validMethod bool, val r, err = self.TextDocumentDiagnostic(context, ¶ms) } } + + default: + if self.CustomRequest != nil { + if handler, ok := self.FindCustomRequestHandler(context.Method); ok { + validMethod = true + if err = json.Unmarshal(context.Params, &handler.params); err == nil { + validParams = true + err = handler.Func(context, handler.params) + } + } + } + } return +} +func (self *Handler) FindCustomRequestHandler(method string) (*CustomRequestHandler, bool) { + for _, handler := range self.CustomRequest { + if handler.Method == method { + return &handler, true + } + } + return nil, false } func (self *Handler) IsInitialized() bool { diff --git a/server/handler.go b/server/handler.go index 8ae24b5..209a579 100644 --- a/server/handler.go +++ b/server/handler.go @@ -37,8 +37,11 @@ func (self *Server) handle(context contextpkg.Context, connection *jsonrpc2.Conn switch request.Method { case "exit": // We're giving the attached handler a chance to handle it first, but we'll ignore any result - self.Handler.Handle(&glspContext) - err := connection.Close() + _, _, _, err := self.Handler.Handle(&glspContext) + if err != nil { + return nil, err + } + err = connection.Close() return nil, err default: From f933cc6b33d97de4a6a071f99c11f75e66869734 Mon Sep 17 00:00:00 2001 From: tris203 Date: Fri, 28 Jun 2024 22:29:40 +0100 Subject: [PATCH 2/4] feat(protocol): change CustomRequestFunc return type The return type of CustomRequestFunc in both protocol_3_16 and protocol_3_17 has been changed from error to (any, error). This allows the function to return a result alongside an error. The Handler's Handle method has been updated to accommodate this change. --- protocol_3_16/custom.go | 2 +- protocol_3_16/handler.go | 2 +- protocol_3_17/custom.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol_3_16/custom.go b/protocol_3_16/custom.go index cad7860..c56c058 100644 --- a/protocol_3_16/custom.go +++ b/protocol_3_16/custom.go @@ -12,4 +12,4 @@ type CustomRequestHandler struct { params json.RawMessage } -type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) error +type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) (any, error) diff --git a/protocol_3_16/handler.go b/protocol_3_16/handler.go index 680192e..29e9f8a 100644 --- a/protocol_3_16/handler.go +++ b/protocol_3_16/handler.go @@ -719,7 +719,7 @@ func (self *Handler) Handle(context *glsp.Context) (r any, validMethod bool, val validMethod = true if err = json.Unmarshal(context.Params, &handler.params); err == nil { validParams = true - err = handler.Func(context, handler.params) + r, err = handler.Func(context, handler.params) } } } diff --git a/protocol_3_17/custom.go b/protocol_3_17/custom.go index cad7860..c56c058 100644 --- a/protocol_3_17/custom.go +++ b/protocol_3_17/custom.go @@ -12,4 +12,4 @@ type CustomRequestHandler struct { params json.RawMessage } -type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) error +type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) (any, error) From e9c481687ce30b4e88ac8cb4daeace76b7063ff3 Mon Sep 17 00:00:00 2001 From: tris203 Date: Wed, 3 Jul 2024 22:37:01 +0100 Subject: [PATCH 3/4] revert(handler): remove error check --- server/handler.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/server/handler.go b/server/handler.go index 209a579..8ae24b5 100644 --- a/server/handler.go +++ b/server/handler.go @@ -37,11 +37,8 @@ func (self *Server) handle(context contextpkg.Context, connection *jsonrpc2.Conn switch request.Method { case "exit": // We're giving the attached handler a chance to handle it first, but we'll ignore any result - _, _, _, err := self.Handler.Handle(&glspContext) - if err != nil { - return nil, err - } - err = connection.Close() + self.Handler.Handle(&glspContext) + err := connection.Close() return nil, err default: From f562f779268737ec40cf6159adb3f29b49083bab Mon Sep 17 00:00:00 2001 From: tris203 Date: Wed, 3 Jul 2024 22:45:42 +0100 Subject: [PATCH 4/4] refactor(protocol): Make 'Params' field public in CustomRequestHandler The 'params' field in the CustomRequestHandler struct has been renamed to 'Params' and made public. This change is reflected in the associated methods where 'params' was used. The 'protocol_3_17/custom.go' file has been deleted. The 'FindCustomRequestHandler' method now returns a 'protocol316.CustomRequestHandler' instead of a 'CustomRequestHandler'. --- protocol_3_16/custom.go | 3 ++- protocol_3_16/handler.go | 4 ++-- protocol_3_17/custom.go | 15 --------------- protocol_3_17/handler.go | 6 +++--- 4 files changed, 7 insertions(+), 21 deletions(-) delete mode 100644 protocol_3_17/custom.go diff --git a/protocol_3_16/custom.go b/protocol_3_16/custom.go index c56c058..e08f9b0 100644 --- a/protocol_3_16/custom.go +++ b/protocol_3_16/custom.go @@ -9,7 +9,8 @@ import ( type CustomRequestHandler struct { Method string Func CustomRequestFunc - params json.RawMessage + // This field should be private however it is used in both versions of the protocol + Params json.RawMessage } type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) (any, error) diff --git a/protocol_3_16/handler.go b/protocol_3_16/handler.go index 29e9f8a..aae5386 100644 --- a/protocol_3_16/handler.go +++ b/protocol_3_16/handler.go @@ -717,9 +717,9 @@ func (self *Handler) Handle(context *glsp.Context) (r any, validMethod bool, val if self.CustomRequest != nil { if handler, ok := self.FindCustomRequestHandler(context.Method); ok { validMethod = true - if err = json.Unmarshal(context.Params, &handler.params); err == nil { + if err = json.Unmarshal(context.Params, &handler.Params); err == nil { validParams = true - r, err = handler.Func(context, handler.params) + r, err = handler.Func(context, handler.Params) } } } diff --git a/protocol_3_17/custom.go b/protocol_3_17/custom.go deleted file mode 100644 index c56c058..0000000 --- a/protocol_3_17/custom.go +++ /dev/null @@ -1,15 +0,0 @@ -package protocol - -import ( - "encoding/json" - - "github.com/tliron/glsp" -) - -type CustomRequestHandler struct { - Method string - Func CustomRequestFunc - params json.RawMessage -} - -type CustomRequestFunc func(context *glsp.Context, params json.RawMessage) (any, error) diff --git a/protocol_3_17/handler.go b/protocol_3_17/handler.go index 8874d8b..08864c7 100644 --- a/protocol_3_17/handler.go +++ b/protocol_3_17/handler.go @@ -653,9 +653,9 @@ func (self *Handler) Handle(context *glsp.Context) (r any, validMethod bool, val if self.CustomRequest != nil { if handler, ok := self.FindCustomRequestHandler(context.Method); ok { validMethod = true - if err = json.Unmarshal(context.Params, &handler.params); err == nil { + if err = json.Unmarshal(context.Params, &handler.Params); err == nil { validParams = true - err = handler.Func(context, handler.params) + r, err = handler.Func(context, handler.Params) } } } @@ -665,7 +665,7 @@ func (self *Handler) Handle(context *glsp.Context) (r any, validMethod bool, val return } -func (self *Handler) FindCustomRequestHandler(method string) (*CustomRequestHandler, bool) { +func (self *Handler) FindCustomRequestHandler(method string) (*protocol316.CustomRequestHandler, bool) { for _, handler := range self.CustomRequest { if handler.Method == method { return &handler, true