vala-lang / vala-language-server

Code Intelligence for Vala & Genie
GNU Lesser General Public License v2.1
286 stars 41 forks source link

Create `vala-language-client` to debug the language server #227

Open albfan opened 2 years ago

albfan commented 2 years ago

I'm trying to setup a complete workflow for vala.

Adding https://github.com/mesonbuild/meson/pull/9582 to meson, one can do:

mkdir -p home/alberto/tutorial/vala-lsp
cd home/alberto/tutorial/vala-lsp
git init
meson init --language vala
vim
:e sample.vala

With a correct setup, vim-lsp or similar work (if setup as mentioned in this project README.md)

so far so good, but after that, debug is little complex

I enable vim-lsp debug and extract basic operations:

So after run this server: (it is listening on stdin)

$ vala-language-server 

Initialize:

Content-Length: 1995

{"id":1,"jsonrpc":"2.0","method":"initialize","params":{"rootUri":"file:///home/alberto/tutorial/vala-lsp","capabilities":{"workspace":{"configuration":true,"applyEdit":true},"window":{"workDoneProgress":false},"textDocument":{"semanticHighlightingCapabilities":{"semanticHighlighting":false},"codeAction":{"isPreferredSupport":true,"disabledSupport":true,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"dynamicRegistration":false},"completion":{"completionItem":{"snippetSupport":false,"resolveSupport":{"properties":["additionalTextEdits"]},"documentationFormat":["markdown","plaintext"]},"dynamicRegistration":false,"completionItemKind":{"valueSet":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,1,2,3,4,5,6,7,8,9]}},"formatting":{"dynamicRegistration":false},"codeLens":{"dynamicRegistration":false},"hover":{"dynamicRegistration":false,"contentFormat":["markdown","plaintext"]},"rangeFormatting":{"dynamicRegistration":false},"declaration":{"dynamicRegistration":false,"linkSupport":true},"references":{"dynamicRegistration":false},"typeHierarchy":false,"foldingRange":{"rangeLimit":5000,"dynamicRegistration":false,"lineFoldingOnly":true},"documentSymbol":{"symbolKind":{"valueSet":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,1,2,3,4,5,6,7,8,9]},"dynamicRegistration":false,"labelSupport":false,"hierarchicalDocumentSymbolSupport":false},"publishDiagnostics":{"relatedInformation":true},"synchronization":{"dynamicRegistration":false,"willSaveWaitUntil":false,"willSave":false,"didSave":true},"documentHighlight":{"dynamicRegistration":false},"implementation":{"dynamicRegistration":false,"linkSupport":true},"typeDefinition":{"dynamicRegistration":false,"linkSupport":true},"definition":{"dynamicRegistration":false,"linkSupport":true}}},"rootPath":"/home/alberto/tutorial/vala-lsp","clientInfo":{"name":"vim-lsp"},"processId":42803,"trace":"off"}}

Response:

Content-Length: 534

{"result":{"capabilities":{"textDocumentSync":2,"definitionProvider":true,"documentSymbolProvider":true,"completionProvider":{"triggerCharacters":[".",">"]},"signatureHelpProvider":{"triggerCharacters":["(","[",","]},"hoverProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"implementationProvider":true,"workspaceSymbolProvider":true,"renameProvider":{"prepareProvider":true},"codeLensProvider":{"resolveProvider":false}},"serverInfo":{"name":"Vala Language Server","version":"0.48.3"}},"jsonrpc":"2.0","id":1}
Content-Length: 153

{"method":"textDocument/publishDiagnostics","jsonrpc":"2.0","params":{"uri":"file:///home/alberto/tutorial/vala-lsp/src/vala_lsp.vala","diagnostics":[]}}Content-Length: 143

{"method":"textDocument/publishDiagnostics","jsonrpc":"2.0","params":{"uri":"file:///usr/share/vala-0.54/vapi/glib-2.0.vapi","diagnostics":[]}}Content-Length: 146

{"method":"textDocument/publishDiagnostics","jsonrpc":"2.0","params":{"uri":"file:///usr/share/vala-0.54/vapi/gobject-2.0.vapi","diagnostics":[]}}Content-Length: 135

{"method":"textDocument/publishDiagnostics","jsonrpc":"2.0","params":{"uri":"file:///home/alberto/tutorial/vala-lsp","diagnostics":[]}}

Ask for hover for stdout.printf

Content-Length: 185

{"id":5,"jsonrpc":"2.0","method":"textDocument/hover","params":{"textDocument":{"uri":"file:///home/alberto/tutorial/vala-lsp/src/vala_lsp.vala"},"position":{"character":12,"line":1}}}

Response: void GLib.FileStream.printf (string format, ...)

Content-Length: 203

{"result":{"contents":[{"language":"vala","value":"void GLib.FileStream.printf (string format, ...)"}],"range":{"start":{"line":1,"character":11},"end":{"line":1,"character":17}}},"jsonrpc":"2.0","id":5}

Hope this helps others to start with lsp and extend, improve features.

Good to have: Miss a vala-language-client (connected by socket? or localhost) to launch queries. Even a GUI would be awesome (as a side project)

Prince781 commented 2 years ago

Also, with respect to improving debugging, see #26 and #203

albfan commented 2 years ago

I will try to add test if I manage to understand all this stuff and lsp specs

esodan commented 2 years ago

I have started to add VLS unit tests in GVLS, in order to test GVls' LSP client against VLS server.

First simple test, just initialize the server and got (just to show how is going on):

$ meson test vls-initialization --gdb
ninja: Entering directory `/home/esodan/Projects/gvls/build'
[1/35] Generating version.vala with a custom command
fatal: No se encontraron nombres, no se puede describir nada.
Reading symbols from /home/esodan/Projects/gvls/build/tests/vls/vls-initialization...
(gdb) r
Starting program: /home/esodan/Projects/gvls/build/tests/vls/vls-initialization 
[Depuración de hilo usando libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
# random seed: R02S1d462f52acf3946d9186c998b81937b1
1..1
# Start of gvls tests
# Start of lsp tests
# Start of stdio tests
[Detaching after fork from child process 37562]
[Nuevo Thread 0x7ffff37d0640 (LWP 37563)]
# MESSAGE: test-vls-initialization.vala:65: Initialize Server
** Message: 07:56:42.988: test-vls-initialization.vala:65: Initialize Server
[Nuevo Thread 0x7ffff2f30640 (LWP 37565)]
# GLib-GIO-DEBUG: _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’
# jsonrpc-output-stream-MESSAGE: >>> {'method': <'initialize'>, 'jsonrpc': <'2.0'>, 'id': <int64 1>, 'params': <{'processId': <int64 1>, 'rootUri': <'file:///home/esodan/Projects/gvls/tests'>, 'initializationOptions': <{'autoConfigure': <false>, 'defaultNamespaces': <true>, 'defaultVapiDirs': <false>, 'scanWorkspace': <true>, 'addUsingNamespaces': <false>, 'mesonBuildSystem': <true>, 'files': <@av []>, 'packages': <@av []>, 'options': <@av []>, 'valaArgs': <@av []>, 'initialized': <true>, 'targets': <@av []>}>, 'capabilities': <{'workspace': <{'applyEdit': <false>, 'workspaceEdit': <{'documentChanges': <false>, 'resourceOperations': <[<<'create'>>, <<'rename'>>, <<'delete'>>]>}>, 'didChangeConfiguration': <{'dynamicRegistration': <false>}>, 'didChangeWhatchedFile': <{'dynamicRegistration': <false>}>, 'symbol': <{'dynamicRegistration': <false>, 'symbolKind': <{'valueSet': <[<int64 0>, <int64 3>, <int64 5>, <int64 6>, <int64 7>, <int64 8>, <int64 10>, <int64 13>, <int64 14>, <int64 15>, <int64 16>, <int64 17>, <int64 22>, <int64 23>]>}>}>, 'executeCommand': <{'dynamicRegistration': <false>}>, 'workspaceFolders': <false>, 'configuration': <true>}>, 'textDocument': <{'synchronization': <{'dynamicRegistration': <false>, 'willSave': <false>, 'willSaveWaitUntil': <false>, 'didSave': <true>}>, 'completion': <{'dynamicRegistration': <false>, 'completionItem': <{'snippetSupport': <false>, 'commitCharactersSupport': <true>, 'documentationFormat': <[<<'plaintext'>>, <<'markdown'>>]>, 'deprecatedSupport': <false>, 'preselectSupport': <false>}>, 'completionItemKind': <{'valueSet': <[<int64 1>, <int64 2>, <int64 5>, <int64 6>, <int64 7>, <int64 8>, <int64 10>, <int64 13>, <int64 14>, <int64 22>]>}>, 'contextSupport': <false>}>, 'hover': <{'dynamicRegistration': <false>, 'contentFormat': <[<<'markdown'>>]>}>, 'signatureHelp': <{'dynamicRegistration': <false>}>, 'references': <{'dynamicRegistration': <false>}>, 'documentHighlight': <{'dynamicRegistration': <false>}>, 'documentSymbol': <{'dynamicRegistration': <false>, 'symbolKind': <{'valueSet': <[<int64 3>, <int64 5>, <int64 6>, <int64 8>, <int64 10>, <int64 11>, <int64 13>, <int64 15>, <int64 23>, <int64 22>]>}>, 'hierarchicalDocumentSymbolSupport': <true>}>, 'formatting': <{'dynamicRegistration': <false>}>, 'rangeFormatting': <{'dynamicRegistration': <false>}>, 'onTypeFormatting': <{'dynamicRegistration': <false>}>, 'definition': <{'dynamicRegistration': <false>}>, 'typeDefinition': <{'dynamicRegistration': <false>}>, 'implementation': <{'dynamicRegistration': <false>}>, 'codeAction': <{'dynamicRegistration': <false>}>, 'codeLens': <{'dynamicRegistration': <false>}>, 'documentLink': <{'dynamicRegistration': <false>}>, 'colorProvider': <{'dynamicRegistration': <false>}>, 'rename': <{'dynamicRegistration': <false>, 'prepareSupport': <false>}>, 'publishDiagnostics': <{'relatedInformation': <false>}>, 'foldingRange': <{'dynamicRegistration': <false>, 'rangeLimit': <int64 0>, 'lineFoldingOnly': <false>}>}>}>, 'workspaceFolders': <@av []>}>}
jsonrpc-output-stream-Message: 07:56:43.009: >>> {'method': <'initialize'>, 'jsonrpc': <'2.0'>, 'id': <int64 1>, 'params': <{'processId': <int64 1>, 'rootUri': <'file:///home/esodan/Projects/gvls/tests'>, 'initializationOptions': <{'autoConfigure': <false>, 'defaultNamespaces': <true>, 'defaultVapiDirs': <false>, 'scanWorkspace': <true>, 'addUsingNamespaces': <false>, 'mesonBuildSystem': <true>, 'files': <@av []>, 'packages': <@av []>, 'options': <@av []>, 'valaArgs': <@av []>, 'initialized': <true>, 'targets': <@av []>}>, 'capabilities': <{'workspace': <{'applyEdit': <false>, 'workspaceEdit': <{'documentChanges': <false>, 'resourceOperations': <[<<'create'>>, <<'rename'>>, <<'delete'>>]>}>, 'didChangeConfiguration': <{'dynamicRegistration': <false>}>, 'didChangeWhatchedFile': <{'dynamicRegistration': <false>}>, 'symbol': <{'dynamicRegistration': <false>, 'symbolKind': <{'valueSet': <[<int64 0>, <int64 3>, <int64 5>, <int64 6>, <int64 7>, <int64 8>, <int64 10>, <int64 13>, <int64 14>, <int64 15>, <int64 16>, <int64 17>, <int64 22>, <int64 23>]>}>}>, 'executeCommand': <{'dynamicRegistration': <false>}>, 'workspaceFolders': <false>, 'configuration': <true>}>, 'textDocument': <{'synchronization': <{'dynamicRegistration': <false>, 'willSave': <false>, 'willSaveWaitUntil': <false>, 'didSave': <true>}>, 'completion': <{'dynamicRegistration': <false>, 'completionItem': <{'snippetSupport': <false>, 'commitCharactersSupport': <true>, 'documentationFormat': <[<<'plaintext'>>, <<'markdown'>>]>, 'deprecatedSupport': <false>, 'preselectSupport': <false>}>, 'completionItemKind': <{'valueSet': <[<int64 1>, <int64 2>, <int64 5>, <int64 6>, <int64 7>, <int64 8>, <int64 10>, <int64 13>, <int64 14>, <int64 22>]>}>, 'contextSupport': <false>}>, 'hover': <{'dynamicRegistration': <false>, 'contentFormat': <[<<'markdown'>>]>}>, 'signatureHelp': <{'dynamicRegistration': <false>}>, 'references': <{'dynamicRegistration': <false>}>, 'documentHighlight': <{'dynamicRegistration': <false>}>, 'documentSymbol': <{'dynamicRegistration': <false>, 'symbolKind': <{'valueSet': <[<int64 3>, <int64 5>, <int64 6>, <int64 8>, <int64 10>, <int64 11>, <int64 13>, <int64 15>, <int64 23>, <int64 22>]>}>, 'hierarchicalDocumentSymbolSupport': <true>}>, 'formatting': <{'dynamicRegistration': <false>}>, 'rangeFormatting': <{'dynamicRegistration': <false>}>, 'onTypeFormatting': <{'dynamicRegistration': <false>}>, 'definition': <{'dynamicRegistration': <false>}>, 'typeDefinition': <{'dynamicRegistration': <false>}>, 'implementation': <{'dynamicRegistration': <false>}>, 'codeAction': <{'dynamicRegistration': <false>}>, 'codeLens': <{'dynamicRegistration': <false>}>, 'documentLink': <{'dynamicRegistration': <false>}>, 'colorProvider': <{'dynamicRegistration': <false>}>, 'rename': <{'dynamicRegistration': <false>, 'prepareSupport': <false>}>, 'publishDiagnostics': <{'relatedInformation': <false>}>, 'foldingRange': <{'dynamicRegistration': <false>, 'rangeLimit': <int64 0>, 'lineFoldingOnly': <false>}>}>}>, 'workspaceFolders': <@av []>}>}
[Nuevo Thread 0x7ffff272f640 (LWP 37566)]
jsonrpc-input-stream-Message: 07:56:43.010: <<< {"method":"initialize","jsonrpc":"2.0","id":1,"params":{"processId":1,"rootUri":"file:///home/esodan/Projects/gvls/tests","initializationOptions":{"autoConfigure":false,"defaultNamespaces":true,"defaultVapiDirs":false,"scanWorkspace":true,"addUsingNamespaces":false,"mesonBuildSystem":true,"files":[],"packages":[],"options":[],"valaArgs":[],"initialized":true,"targets":[]},"capabilities":{"workspace":{"applyEdit":false,"workspaceEdit":{"documentChanges":false,"resourceOperations":["create","rename","delete"]},"didChangeConfiguration":{"dynamicRegistration":false},"didChangeWhatchedFile":{"dynamicRegistration":false},"symbol":{"dynamicRegistration":false,"symbolKind":{"valueSet":[0,3,5,6,7,8,10,13,14,15,16,17,22,23]}},"executeCommand":{"dynamicRegistration":false},"workspaceFolders":false,"configuration":true},"textDocument":{"synchronization":{"dynamicRegistration":false,"willSave":false,"willSaveWaitUntil":false,"didSave":true},"completion":{"dynamicRegistration":false,"completionItem":{"snippetSupport":false,"commitCharactersSupport":true,"documentationFormat":["plaintext","markdown"],"deprecatedSupport":false,"preselectSupport":false},"completionItemKind":{"valueSet":[1,2,5,6,7,8,10,13,14,22]},"contextSupport":false},"hover":{"dynamicRegistration":false,"contentFormat":["markdown"]},"signatureHelp":{"dynamicRegistration":false},"references":{"dynamicRegistration":false},"documentHighlight":{"dynamicRegistration":false},"documentSymbol":{"dynamicRegistration":false,"symbolKind":{"valueSet":[3,5,6,8,10,11,13,15,23,22]},"hierarchicalDocumentSymbolSupport":true},"formatting":{"dynamicRegistration":false},"rangeFormatting":{"dynamicRegistration":false},"onTypeFormatting":{"dynamicRegistration":false},"definition":{"dynamicRegistration":false},"typeDefinition":{"dynamicRegistration":false},"implementation":{"dynamicRegistration":false},"codeAction":{"dynamicRegistration":false},"codeLens":{"dynamicRegistration":false},"documentLink":{"dynamicRegistration":false},"colorProvider":{"dynamicRegistration":false},"rename":{"dynamicRegistration":false,"prepareSupport":false},"publishDiagnostics":{"relatedInformation":false},"foldingRange":{"dynamicRegistration":false,"rangeLimit":0,"lineFoldingOnly":false}}},"workspaceFolders":[]}}
jsonrpc-output-stream-Message: 07:56:43.017: >>> {'result': <{'capabilities': <{'textDocumentSync': <int16 2>, 'definitionProvider': <true>, 'documentSymbolProvider': <true>, 'completionProvider': <{'triggerCharacters': <['.', '>']>}>, 'signatureHelpProvider': <{'triggerCharacters': <['(', '[', ',']>}>, 'hoverProvider': <true>, 'referencesProvider': <true>, 'documentHighlightProvider': <true>, 'implementationProvider': <true>, 'workspaceSymbolProvider': <true>, 'renameProvider': <{'prepareProvider': <true>}>, 'codeLensProvider': <{'resolveProvider': <false>}>}>, 'serverInfo': <{'name': <'Vala Language Server'>, 'version': <'0.48.4'>}>}>, 'jsonrpc': <'2.0'>, 'id': <int64 1>}
# jsonrpc-input-stream-MESSAGE: <<< {"result":{"capabilities":{"textDocumentSync":2,"definitionProvider":true,"documentSymbolProvider":true,"completionProvider":{"triggerCharacters":[".",">"]},"signatureHelpProvider":{"triggerCharacters":["(","[",","]},"hoverProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"implementationProvider":true,"workspaceSymbolProvider":true,"renameProvider":{"prepareProvider":true},"codeLensProvider":{"resolveProvider":false}},"serverInfo":{"name":"Vala Language Server","version":"0.48.4"}},"jsonrpc":"2.0","id":1}
jsonrpc-input-stream-Message: 07:56:43.017: <<< {"result":{"capabilities":{"textDocumentSync":2,"definitionProvider":true,"documentSymbolProvider":true,"completionProvider":{"triggerCharacters":[".",">"]},"signatureHelpProvider":{"triggerCharacters":["(","[",","]},"hoverProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"implementationProvider":true,"workspaceSymbolProvider":true,"renameProvider":{"prepareProvider":true},"codeLensProvider":{"resolveProvider":false}},"serverInfo":{"name":"Vala Language Server","version":"0.48.4"}},"jsonrpc":"2.0","id":1}
# MESSAGE: test-vls-initialization.vala:42: End initialization...
** Message: 07:56:43.018: test-vls-initialization.vala:42: End initialization...
# MESSAGE: test-vls-initialization.vala:43: Send shutdown request
** Message: 07:56:43.018: test-vls-initialization.vala:43: Send shutdown request
# jsonrpc-output-stream-MESSAGE: >>> {'method': <'shutdown'>, 'jsonrpc': <'2.0'>, 'id': <int64 2>, 'params': <'shutdown'>}
jsonrpc-output-stream-Message: 07:56:43.018: >>> {'method': <'shutdown'>, 'jsonrpc': <'2.0'>, 'id': <int64 2>, 'params': <'shutdown'>}
# jsonrpc-output-stream-MESSAGE: >>> {'method': <'initialized'>, 'jsonrpc': <'2.0'>, 'params': <@a{sv} {}>}
jsonrpc-output-stream-Message: 07:56:43.018: >>> {'method': <'initialized'>, 'jsonrpc': <'2.0'>, 'params': <@a{sv} {}>}

(vala-language-server:37562): vls-WARNING **: 07:56:43.506: mesonproject.vala:287: configuration failed with exit code 256
----stdout:
The Meson build system
Version: 0.56.2
Source dir: /home/esodan/Projects/gvls/tests
Build dir: /tmp/vls-meson-4217662860-H23PF1
Build type: native build

ERROR: First statement must be a call to project

A full log can be found at /tmp/vls-meson-4217662860-H23PF1/meson-logs/meson-log.txt

----stderr:

(vala-language-server:37562): vls-WARNING **: 07:56:43.527: server.vala:205: Failed to initialize Meson project - meson configuration failed with exit code 256
jsonrpc-output-stream-Message: 07:56:43.527: >>> {'method': <'window/showMessage'>, 'jsonrpc': <'2.0'>, 'params': <{'type': <int16 1>, 'message': <'Failed to initialize Meson project - meson configuration failed with exit code 256'>}>}
# jsonrpc-input-stream-MESSAGE: <<< {"method":"window/showMessage","jsonrpc":"2.0","params":{"type":1,"message":"Failed to initialize Meson project - meson configuration failed with exit code 256"}}
jsonrpc-input-stream-Message: 07:56:43.528: <<< {"method":"window/showMessage","jsonrpc":"2.0","params":{"type":1,"message":"Failed to initialize Meson project - meson configuration failed with exit code 256"}}

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.754: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.755: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.756: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.756: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.760: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.763: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.766: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.769: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.770: vala_symbol_get_name: assertion 'self != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.780: vala_object_type_construct: assertion 'type_symbol != NULL' failed

(vala-language-server:37562): vala-CRITICAL **: 07:56:43.780: vala_interface_add_prerequisite: assertion 'type != NULL' failed
jsonrpc-input-stream-Message: 07:56:43.827: <<< {"method":"shutdown","jsonrpc":"2.0","id":2,"params":"shutdown"}
jsonrpc-output-stream-Message: 07:56:43.836: >>> {'result': <@mv nothing>, 'jsonrpc': <'2.0'>, 'id': <int64 2>}
# jsonrpc-input-stream-MESSAGE: <<< {"result":null,"jsonrpc":"2.0","id":2}
jsonrpc-input-stream-Message: 07:56:43.838: <<< {"result":null,"jsonrpc":"2.0","id":2}
# MESSAGE: test-vls-initialization.vala:47: Shutdown response: nothing
** Message: 07:56:43.838: test-vls-initialization.vala:47: Shutdown response: nothing
**
ERROR:../tests/vls/test-vls-initialization.vala:48:__lambda6_: assertion failed: ("ok" in msg)
Bail out! ERROR:../tests/vls/test-vls-initialization.vala:48:__lambda6_: assertion failed: ("ok" in msg)

Thread 1 "vls-initializat" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737293155264) at pthread_kill.c:44
44  pthread_kill.c: No existe el archivo o el directorio.