-
-
Notifications
You must be signed in to change notification settings - Fork 895
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
Parsing and encoding JSON booleans doesn't roundtrip correctly for code actions #4184
Parsing and encoding JSON booleans doesn't roundtrip correctly for code actions #4184
Comments
So the problem here is that It parses this JSON: "{\"id\":74,\"jsonrpc\":\"2.0\",\"result\":[{\"command\":{\"arguments\":[{\"methodGroup\":[[\"show\",\"show :: Foo -> String\"]],\"range\":{\"end\":{\"character\":17,\"line\":7},\"start\":{\"character\":9,\"line\":7}},\"verTxtDocId\":{\"uri\":\"file:///home/robbert/Documents/forks/lsp-mode/Foo.hs\",\"version\":2},\"withSig\":false}],\"command\":\"1065989:class:classplugin.codeaction\",\"title\":\"Add placeholders for 'show'\"},\"diagnostics\":[],\"kind\":\"quickfix\",\"title\":\"Add placeholders for 'show'\"},{\"command\":{\"arguments\":[{\"methodGroup\":[[\"show\",\"show :: Foo -> String\"]],\"range\":{\"end\":{\"character\":17,\"line\":7},\"start\":{\"character\":9,\"line\":7}},\"verTxtDocId\":{\"uri\":\"file:///home/robbert/Documents/forks/lsp-mode/Foo.hs\",\"version\":2},\"withSig\":true}],\"command\":\"1065989:class:classplugin.codeaction\",\"title\":\"Add placeholders for 'show' with signature(s)\"},\"diagnostics\":[],\"kind\":\"quickfix\",\"title\":\"Add placeholders for 'show' with signature(s)\"},{\"command\":{\"arguments\":[{\"methodGroup\":[[\"show\",\"show :: Foo -> String\"],[\"showList\",\"showList :: [Foo] -> ShowS\"]],\"range\":{\"end\":{\"character\":17,\"line\":7},\"start\":{\"character\":9,\"line\":7}},\"verTxtDocId\":{\"uri\":\"file:///home/robbert/Documents/forks/lsp-mode/Foo.hs\",\"version\":2},\"withSig\":false}],\"command\":\"1065989:class:classplugin.codeaction\",\"title\":\"Add placeholders for all missing methods\"},\"diagnostics\":[],\"kind\":\"quickfix\",\"title\":\"Add placeholders for all missing methods\"},{\"command\":{\"arguments\":[{\"methodGroup\":[[\"show\",\"show :: Foo -> String\"],[\"showList\",\"showList :: [Foo] -> ShowS\"]],\"range\":{\"end\":{\"character\":17,\"line\":7},\"start\":{\"character\":9,\"line\":7}},\"verTxtDocId\":{\"uri\":\"file:///home/robbert/Documents/forks/lsp-mode/Foo.hs\",\"version\":2},\"withSig\":true}],\"command\":\"1065989:class:classplugin.codeaction\",\"title\":\"Add placeholders for all missing methods with signature(s)\"},\"diagnostics\":[],\"kind\":\"quickfix\",\"title\":\"Add placeholders for all missing methods with signature(s)\"},{\"diagnostics\":[],\"edit\":{\"changes\":{\"file:///home/robbert/Documents/forks/lsp-mode/Foo.hs\":[{\"newText\":\"{-# OPTIONS_GHC -Wno-missing-methods #-}\\n\",\"range\":{\"end\":{\"character\":0,\"line\":0},\"start\":{\"character\":0,\"line\":0}}}]}},\"kind\":\"quickfix\",\"title\":\"Disable \\\"missing-methods\\\" warnings\"}]}" To this: #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("id" 74 "jsonrpc" "2.0" "result" [#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("arguments" [#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("methodGroup" [["show" "show :: Foo -> String"]] "range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 17 "line" 7)) "start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 9 "line" 7)))) "verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2)) "withSig" nil))] "command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for 'show'")) "diagnostics" [] "kind" "quickfix" "title" "Add placeholders for 'show'")) #s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("arguments" [#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("methodGroup" [["show" "show :: Foo -> String"]] "range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 17 "line" 7)) "start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 9 "line" 7)))) "verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2)) "withSig" t))] "command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for 'show' with signature(s)")) "diagnostics" [] "kind" "quickfix" "title" "Add placeholders for 'show' with signature(s)")) #s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("arguments" [#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("methodGroup" [["show" "show :: Foo -> String"] ["showList" "showList :: [Foo] -> ShowS"]] "range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 17 "line" 7)) "start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 9 "line" 7)))) "verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2)) "withSig" nil))] "command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for all missing methods")) "diagnostics" [] "kind" "quickfix" "title" "Add placeholders for all missing methods")) #s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("arguments" [#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("methodGroup" [["show" "show :: Foo -> String"] ["showList" "showList :: [Foo] -> ShowS"]] "range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 17 "line" 7)) "start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 9 "line" 7)))) "verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2)) "withSig" t))] "command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for all missing methods with signature(s)")) "diagnostics" [] "kind" "quickfix" "title" "Add placeholders for all missing methods with signature(s)")) #s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("diagnostics" [] "edit" #s(hash-table size 1 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("changes" #s(hash-table size 1 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" [#s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("newText" "{-# OPTIONS_GHC -Wno-missing-methods #-}
" "range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 0 "line" 0)) "start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("character" 0 "line" 0))))))])))) "kind" "quickfix" "title" "Disable \"missing-methods\" warnings"))])) However, throwing this same input into #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("id" 74 "jsonrpc" "2.0" "result"
[#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("arguments"
[#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("methodGroup"
[["show" "show :: Foo -> String"]]
"range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 17 "line" 7))
"start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 9 "line" 7))))
"verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2))
"withSig" :false))]
"command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for 'show'"))
"diagnostics"
[]
"kind" "quickfix" "title" "Add placeholders for 'show'"))
#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("arguments"
[#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("methodGroup"
[["show" "show :: Foo -> String"]]
"range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 17 "line" 7))
"start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 9 "line" 7))))
"verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2))
"withSig" t))]
"command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for 'show' with signature(s)"))
"diagnostics"
[]
"kind" "quickfix" "title" "Add placeholders for 'show' with signature(s)"))
#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("arguments"
[#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("methodGroup"
[["show" "show :: Foo -> String"]
["showList" "showList :: [Foo] -> ShowS"]]
"range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 17 "line" 7))
"start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 9 "line" 7))))
"verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2))
"withSig" :false))]
"command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for all missing methods"))
"diagnostics"
[]
"kind" "quickfix" "title" "Add placeholders for all missing methods"))
#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("command" #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("arguments"
[#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("methodGroup"
[["show" "show :: Foo -> String"]
["showList" "showList :: [Foo] -> ShowS"]]
"range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 17 "line" 7))
"start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 9 "line" 7))))
"verTxtDocId" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("uri" "file:///home/robbert/Documents/forks/lsp-mode/Foo.hs" "version" 2))
"withSig" t))]
"command" "1065989:class:classplugin.codeaction" "title" "Add placeholders for all missing methods with signature(s)"))
"diagnostics"
[]
"kind" "quickfix" "title" "Add placeholders for all missing methods with signature(s)"))
#s(hash-table size 4 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("diagnostics"
[]
"edit" #s(hash-table size 1 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("changes" #s(hash-table size 1 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("file:///home/robbert/Documents/forks/lsp-mode/Foo.hs"
[#s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("newText" "{-# OPTIONS_GHC -Wno-missing-methods #-}
" "range" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("end" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 0 "line" 0))
"start" #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 data
("character" 0 "line" 0))))))]))))
"kind" "quickfix" "title" "Disable \"missing-methods\" warnings"))])) |
Oh, yes, of course it does this. This is how (json-parse-buffer :object-type (if lsp-use-plists
'plist
'hash-table)
:null-object nil
:false-object nil) It doesn't distinguish between |
This would break code actions where the server sends us an action containing a `false` boolean parameter. `lsp-mode` would translate this into `nil`, and then send a `null` back to the language server. An example of this causing problems was emacs-lsp#4184. There may be parts of `lsp-mode` that expect `false` values to be parsed as `nil`, so any logic involving parsed booleans may need to be updated.
This lets us fix emacs-lsp#4184 by selectively changing `nil` code action argument values to `:json-false`. Once this is merged, HLS needs to set the field to `'(:withSig)` (and possibly some other values).
This lets us fix emacs-lsp#4184 by selectively changing `nil` code action argument values to `:json-false`. Once this is merged, HLS needs to set the field to `'(:withSig)` (and possibly some other values).
This lets us fix emacs-lsp#4184 by selectively changing `nil` code action argument values to `:json-false`. Once this is merged, HLS needs to set the field to `'(:withSig)` (and possibly some other values).
This lets us fix #4184 by selectively changing `nil` code action argument values to `:json-false`. Once this is merged, HLS needs to set the field to `'(:withSig)` (and possibly some other values).
Hmm. We already try and be a bit permissive on the HLS side as various clients don't follow the spec. Particularly in terms of using |
I think in most cases it wouldn't hurt to treat\ |
Original title: Argument parsing errors when using the 'Add placeholders for ...' code actions in haskell-language-server
Thank you for the bug report
lsp-mode
related packages.M-x lsp-start-plain
Bug description
This has been happening for at least a year now. I was silently hoping this would magically get fixed in the meantime (on either the language server's or lsp-mode's side), but I guess that didn't happen. 😄
Also wasn't quite whether to file this under
lsp-mode
's orlsp-haskell
's issue tracker, but since this involves a parsing issue I posted it here.Using any of the
Add placeholders for
code actions from Haskell Language Server's class actions plugin results in the following error:The issue has previously been reported on hls' issue tracker here: haskell/haskell-language-server#2993
Steps to reproduce
This happens any time you try to execute one of these code actions. The simplest way to reproduce this would be to create a
.hs
file with the following contents:Then hover over the 'No implicit implementation for' warning at
Show Foo
and try to execute any of the placeholder code actions.Expected behavior
I'd expect the placeholders to be inserted.
Which Language Server did you use?
This happens with any HLS version. I recently used 1.8.0.0 up to 2.3.0.0 that all had this issue.
OS
Linux
Error callstack
Backtrace
*lsp-log*
*lsp-log: lsp-haskell:128453*
*lsp-haskell::stderr*
Anything else?
No response
The text was updated successfully, but these errors were encountered: