haringsrob / laravel-dev-tools

Developer tools for easier Laravel development (Blade lsp)
Apache License 2.0
84 stars 5 forks source link

Help with LSP JSON-RPC Response.. #10

Open EmranMR opened 11 months ago

EmranMR commented 11 months ago

Hello @haringsrob. I am very keen to try your LSP however I hit some roadblocks. I was wondering if you could help. I should also mention I am not an expert in LSP by any means. I am just trying to port this LSP into Nova by following the documentations 😊

I am writing an extension for the Nova editor. Please checkout the branch named LSP if you need to.

You can check out the documentation by Nova about their language-client. Here is a summary of installation:

  1. As per your guide, I added your repo as a submodule
  2. Generated the executable using the ./laravel-dev-tools app:build and copied into the extension root.
    • I also tired to copy the executable that is already in the builds/ folder of your repo inside my extension.
  3. Then I hooked up the Nova LanguageClient to your executable via stdio

Based on the docs on Nova and your repo that should be it. In fact it seemed to have worked fine in sublime, neovim and vsCode looking at the other issues. But I get errors in return for some reason.

Once I initiate the LSP I get the following error in debug mode:

To summerise Nova is moaning about the hoverProvider not having Expected Bool or HoverOptions as the value because the value is Phpactor\\LanguageServerProtocol\\HoverClientCapabilities , see below 👇

1. Error Messages

Example Language Server[22:26:46.707000] The data couldn’t be read because it isn’t in the correct format.
Example Language Server[22:26:46.707000] Example Language Server connection closed unexpectedly: dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "result", intValue: nil), CodingKeys(stringValue: "capabilities", intValue: nil), CodingKeys(stringValue: "hoverProvider", intValue: nil)], debugDescription: "Expected Bool or HoverOptions", underlyingError: nil))

2. Nova's Request to the LSP

Example Language Server[22:26:46.112000] Sending JSON-RPC request: number(0) initialize
{
  "jsonrpc" : "2.0",
  "id" : 0,
  "method" : "initialize",
  "params" : {
    "locale" : "en_GB",
    "capabilities" : {
      "window" : {
        "showMessage" : {
          "messageActionItem" : {
            "additionalPropertiesSupport" : true
          }
        },
        "showDocument" : {
          "support" : true
        }
      },
      "workspace" : {
        "configuration" : true,
        "applyEdit" : true,
        "didChangeConfiguration" : {
          "dynamicRegistration" : true
        },
        "executeCommand" : {

        },
        "workspaceFolders" : true,
        "workspaceEdit" : {
          "failureHandling" : "undo",
          "documentChanges" : true,
          "resourceOperations" : [
            "create",
            "rename",
            "delete"
          ]
        }
      },
      "textDocument" : {
        "codeAction" : {
          "resolveSupport" : {
            "properties" : [
              "edit"
            ]
          },
          "codeActionLiteralSupport" : {
            "codeActionKind" : {
              "valueSet" : [
                "quickfix",
                "refactor",
                "refactor.extract",
                "refactor.inline",
                "refactor.rewrite",
                "source",
                "source.organizeImports",
                "source.fixAll"
              ]
            }
          },
          "isPreferredSupport" : true
        },
        "hover" : {
          "contentFormat" : [
            "markdown",
            "plaintext"
          ]
        },
        "completion" : {
          "completionItem" : {
            "resolveSupport" : {
              "properties" : [
                "documentation",
                "insertText",
                "insertTextFormat",
                "insertTextMode",
                "textEdit",
                "textEditText",
                "additionalTextEdits",
                "commitCharacters",
                "command"
              ]
            },
            "snippetSupport" : true,
            "documentationFormat" : [
              "markdown",
              "plaintext"
            ],
            "tagSupport" : {
              "valueSet" : [
                1
              ]
            },
            "insertReplaceSupport" : true,
            "deprecatedSupport" : true,
            "commitCharactersSupport" : true
          },
          "completionItemKind" : {
            "valueSet" : [
              1,
              2,
              3,
              4,
              5,
              6,
              7,
              8,
              9,
              10,
              11,
              12,
              13,
              14,
              15,
              16,
              17,
              18,
              19,
              20,
              21,
              22,
              23,
              24,
              25
            ]
          },
          "contextSupport" : true
        },
        "documentHighlight" : {

        },
        "codeLens" : {

        },
        "synchronization" : {
          "didSave" : true,
          "willSave" : true,
          "willSaveWaitUntil" : true
        },
        "publishDiagnostics" : {
          "tagSupport" : {
            "valueSet" : [
              1,
              2
            ]
          },
          "versionSupport" : true,
          "relatedInformation" : true
        },
        "declaration" : {
          "linkSupport" : true
        },
        "typeDefinition" : {
          "linkSupport" : true
        },
        "definition" : {
          "linkSupport" : true
        },
        "implementation" : {
          "linkSupport" : true
        },
        "signatureHelp" : {
          "signatureInformation" : {
            "documentationFormat" : [
              "markdown",
              "plaintext"
            ]
          }
        }
      }
    },
    "processId" : 2416,
    "rootPath" : "\/Users\/Emran\/Developer\/nova-extension\/Laravel-Suit",
    "workspaceFolders" : [
      {
        "uri" : "file:\/\/\/Users\/Emran\/Developer\/nova-extension\/Laravel-Suit\/",
        "name" : "Laravel Suite"
      }
    ],
    "rootUri" : "file:\/\/\/Users\/Emran\/Developer\/nova-extension\/Laravel-Suit\/",
    "clientInfo" : {
      "name" : "Nova",
      "version" : "534827"
    }
  }
}

3. Laravel-dev-tools Response

Example Language Server[22:26:46.707000] Received JSON-RPC response: number(0) initialize
{
  "jsonrpc" : "2.0",
  "result" : {
    "serverInfo" : {
      "version" : 1
    },
    "capabilities" : {
      "executeCommandProvider" : {
        "commands" : [
          "create_component",
          "create_livewire_component"
        ]
      },
      "completionProvider" : {
        "triggerCharacters" : [
          "<",
          ":",
          "@"
        ]
      },
      "hoverProvider" : "Phpactor\\LanguageServerProtocol\\HoverClientCapabilities",
      "definitionProvider" : "Phpactor\\LanguageServerProtocol\\DefinitionClientCapabilities",
      "documentSymbolProvider" : "Phpactor\\LanguageServerProtocol\\DocumentSymbolClientCapabilities",
      "codeActionProvider" : {
        "codeActionKinds" : [
          "quickfix"
        ]
      },
      "textDocumentSync" : 1
    }
  },
  "id" : 0
}
EmranMR commented 11 months ago

Got me wondering if this LSP requires phpactor to be an active LSP for php files as a prerequisite? 🤔

haringsrob commented 11 months ago

Hey EmranMR,

It does should not require phpactor to be active.

Not too sure about the error you are getting, what if you disable hover capabilities?

EmranMR commented 11 months ago

Hey @haringsrob! Sorry for the late reply. So I decided to try the bare phpactor LSP itself for comparison to see if that would also give the similar error, returning the wrong types JSON-RPC response.

The phpactor implementation worked really fine, In fact far more superior than the intelephense I had before so will be looking into porting that as well in the future as an extension!

I checked the logs Phpactor and all the capabilities were returned correctly such as bool object etc.

Now I did a quick search in your source code, not sure but might be related to registerCapabilties??

To give you an example phpactor returns bool for hoverProvider: true

but the laravel-dev-tools return the following:

"hoverProvider" : "Phpactor\\LanguageServerProtocol\\HoverClientCapabilities",
"definitionProvider" : "Phpactor\\LanguageServerProtocol\\DefinitionClientCapabilities",
"documentSymbolProvider" : "Phpactor\\LanguageServerProtocol\\DocumentSymbolClientCapabilities",

This response is just returning the Phpactor class as is for some reason rather than the values.

If we look at registerCapabilties className as strings are returned? I could be very well wrong. I might fork and hardcode the values such as true for hoverProvider and see what happens after the build. 🤔

    public function registerCapabiltiies(ServerCapabilities $capabilities): void
    {
        $options = new CompletionOptions();
        $options->triggerCharacters = ['<', ':', '@'];

        $capabilities->completionProvider = $options;
        $capabilities->definitionProvider = DefinitionClientCapabilities::class;
        $capabilities->hoverProvider = HoverClientCapabilities::class;
        $capabilities->documentSymbolProvider = DocumentSymbolClientCapabilities::class;
    }
EmranMR commented 11 months ago

I just hardcoded the hoverProvider in registerCapabilties as true and that error got cleared.

"hoverProvider" : true,
"definitionProvider" : "Phpactor\\LanguageServerProtocol\\DefinitionClientCapabilities",
"documentSymbolProvider" : "Phpactor\\LanguageServerProtocol\\DocumentSymbolClientCapabilities",

so registerCapabilties worth having a look at.

Although now I am getting errors such as:

Example Language Server connection closed unexpectedly: dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "result", intValue: nil), CodingKeys(stringValue: "capabilities", intValue: nil), CodingKeys(stringValue: "definitionProvider", intValue: nil)], debugDescription: "Expected Bool or DefinitionOptions", underlyingError: nil))

I reckon VsCode prob has better error handling that is why it is working in VScode?

Thanks Emran!