GithubHelp home page GithubHelp logo

language-server's Introduction

Phpactor Language Server

CI

This package provides a platform for building a Language Server according to the Language Server Specification

  • ✔️ Can run as either a TCP server or on STDIO.
  • ✔️ Multiple connections.
  • ✔️ Text document synchronization.
  • ✔️ Background services.
  • ✔️ Bi-directional requests.
  • ✔️ Commands.
  • ✔️ Request cancellation.
  • ✔️ Initialization handling.
  • ✔️ Up-to-date and self-instantiating protocol classes.

See the Language Server Specification for a list of methods which you can implement with this package.

Documentation

Documentation can be found on readthedocs.

Installing

$ composer require phpactor/language-server

Running the tests

With composer:

$ composer integrate

or:

$ ./vendor/bin/phpunit
$ ./vendor/bin/phpstan analyse
$ ./vendor/bin/php-cs-fixer fix

Built With

  • Amphp: Event-driven concurrency framework.

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Contributing

This package is open source and welcomes contributions! Feel free to open a pull request on this repository.

Support

  • Create an issue on the main Phpactor repository.
  • Join the #phpactor channel on the Slack Symfony Devs channel.

language-server's People

Contributors

camilledejoye avatar dantleech avatar lumnn avatar mamazu avatar matmarex avatar muglug avatar weeman1337 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

language-server's Issues

PHP Fatal error: Uncaught Error: Cannot instantiate interface Phpactor\LanguageServer\Core\Server\Transmitter\MessageFormatter in ***/language-server/bin/proxy:48

just trying example from documentation.
echo '{"id":1,"method":"foobar","params":[]}' | ./bin/proxy request | php example/server/minimal.php
then got error:
PHP Fatal error: Uncaught Error: Cannot instantiate interface Phpactor\LanguageServer\Core\Server\Transmitter\MessageFormatter in ***/language-server/bin/proxy:48 Stack trace: #0 {main} thrown in ***/language-server/bin/proxy on line 48
my php-version is : PHP 8.0.11

Index files in looping

I use coc.nvim on index showing a message "Indexed n/n", when it completes 100% it ends up indexing again and returns to 1%.

NeoVim

NVIM v0.4.3
Build type: Release
LuaJIT 2.0.5
Compilation: /usr/bin/cc -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -O2 -DNDEBUG -DMIN_LOG_LEVEL=3 -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -I/build/neovim/src/build/config -I/build/neovim/src/neovim-0.4.3/src -I/usr/include -I/build/neovim/src/build/src/nvim/auto -I/build/neovim/src/build/include
Compiled by builduser

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/share/nvim"

Run :checkhealth for more info

Project
image

coc-settings.json
image

allow extensions to be defined

for example the core extension would include the handlers for all the workspace operstions etc.

extensions should also be able to mutate the ServerCapabilities object which is returned from the initialize command.

this is necessary, f.e. to support specifying the completion trigger characters, a phpactor extension might look like:

class PhpactorExtension
{
    public function setCapabilities(ServerCapabilities $capabilities)
    {
        $capabilities->completionProvider = new CompletionOptions(...);
    }
  
    public function handlers(): array
    {
        return [
            new CompletionHandler(),
            new GotoDefinitionHandler(),
            // ...
        ];
    }
}

emacs client gives null value for initializationOptions

I'm a bit unsure whether this belongs to emacs's emacs-lsp package or here.

I've used emacs' lsp-php package and redefined the server command to use phpactor's lsp server.

In the error, I can see this json is given as input

{
  "jsonrpc": "2.0",
  "method": "initialize",
  "params": {
    "processId": 4543,
    "rootPath": "/home/mikael/workspace/lmt/project/",
    "rootUri": "file:///home/mikael/workspace/lmt/project/",
    "capabilities": {
      "workspace": {
        "applyEdit": true,
        "executeCommand": {
          "dynamicRegistration": true
        }
      },
      "textDocument": {
        "synchronization": {
          "willSave": true,
          "didSave": true,
          "willSaveWaitUntil": true
        },
        "documentSymbol": {
          "symbolKind": {
            "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
            ]
          },
          "hierarchicalDocumentSymbolSupport": true
        },
        "formatting": {
          "dynamicRegistration": true
        },
        "codeAction": {
          "dynamicRegistration": true
        },
        "completion": {
          "completionItem": {
            "snippetSupport": true
          }
        }
      }
    },
    "initializationOptions": null
  },
  "id": 1
}

Resulting in this error

[2018-10-23 13:47:29] phpactor.ERROR: Argument 2 passed to Phpactor\LanguageServer\Extension\Core\Initialize::__invoke() must be of the type array, null given, ca

an array is expected as second argument (

array $initializationOptions = [],
)

Middleware Refactor

  • All handlers should be session based
  • Dispatcher should be the extension point of the server
  • Handlers should be implemented as middlewares
  • Middlewares are however an implementation detail of the Dispatcher implementation.

Example:

  • The existing "system handlers" can be made into middlewares
  • The exisitng handler decorators transition well to middlewares.
  • The (for example) Phpactor implementation can be implemented as a middleware - replacing the "HandlerLoader" interface.

Consequences:

  • Middlewares can be instantiated per session with necessary dependencies: can stop passing special dependencies as method arguments.

Normalize absolute file:// URIs

Prevent crashes:

Trying to create descendant from absolute path \\\"/home/daniel/www/phpactor/language-ser
ver/vendor/phpspec/prophecy/src\\\" that does not lie within context path \\\"file:///home/daniel/www/phpactor/language-server\\\"\

on ubuntu system php7.4 can't use composer require install

composer version

Composer version 2.1.8 2021-09-15 13:55:14

php version

PHP 7.4.3 (cli) (built: Mar  2 2022 15:36:52) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies

php extensions

image

php origin author

image

composer command

composer global require --ignore-platform-reqs --dev felixfbecker/language-server:dev-master

Changed current directory to /home/vv/.config/composer
Info from https://repo.packagist.org: #StandWithUkraine
./composer.json has been created
Running composer update felixfbecker/language-server
Loading composer repositories with package information
Info from https://repo.packagist.org: #StandWithUkraine
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires felixfbecker/language-server dev-master -> satisfiable by felixfbecker/language-server[dev-master].
    - felixfbecker/language-server dev-master requires jetbrains/phpstorm-stubs dev-master -> found jetbrains/phpstorm-stubs[dev-master] but it does not match your minimum-stability.


Installation failed, deleting ./composer.json.

how fix it?

handle infinite loop situations

currently shutting down isn't possible when the server gets into certain invalid states (i.e. when trying to read headers that are never coming, or waiting for the wrong information).

Ignore unrecognized keys in `initializationOptions`

I'm writing a new LSP client, and testing with phpactor. In addition, I'm also testing with Intelephense. In order to support Intelephense, my client passes the following in the initializationOptions parameter to the initialize message:

    initializationOptions =     {
        globalStoragePath = "/Users/siegel/path/to/intelephense-storage/global-storage";
        storagePath = "/Users/siegel/path/to/intelephense-storage/storage";
    };

phpactor doesn't recognize the globalStoragePath or storagePath keys, and throws an exception.

(I think there's a sound argument to be made that the names of these two keys are poorly chosen because they're prone to namespace collisions, but it wasn't my decision and I have no influence over Intelephense.)

When these parameters are present, phpactor throws an exception, and then terminates as follows:

2021-05-05 11:53:02.254: stderr output from server: [�[0;31mCRIT�[0;0m][�[1;37m229982.253487�[0;0m] Key(s) "storagePath", "globalStoragePath" are not known, known keys: "container.extension_classes", "console_dumper_default", "xdebug_disable", "command", "core.warn_on_develop", "core.min_memory_limit", "class_to_file.project_root", "class_to_file.brute_force_conversion", "code_transform.class_new.variants", "code_transform.template_paths", "code_transform.indentation", "code_transform.refactor.generate_accessor.prefix", "code_transform.refactor.generate_accessor.upper_case_first", "completion_worse.completor.class.limit", "completion_worse.disabled_completors", "completion_worse.name_completion_priority", "completion_worse.snippets", "completion_worse.experimantal", "completion.dedupe", "completion.dedupe_match_short_description", "completion.limit", "navigator.destinations", "navigator.autocreate", "rpc.store_replay", "rpc.replay_path", "source_code_filesystem.project_root", "worse_reflection.enable_cache", "worse_reflection.cache_lifetime", "worse_reflection.enable_context_location", "worse_reflection.cache_dir", "worse_reflection.stub_dir", "file_path_resolver.project_root", "file_path_resolver.app_name", "file_path_resolver.application_root", "file_path_resolver.enable_cache", "file_path_resolver.enable_logging", "logging.enabled", "logging.fingers_crossed", "logging.path", "logging.level", "logger.name", "logging.formatter", "composer.enable", "composer.autoloader_path", "composer.autoload_deregister", "composer.class_maps_only", "console.verbosity", "console.decorated", "extension_manager.extension_vendor_dir", "extension_manager.vendor_dir", "extension_manager.config_path", "extension_manager.extension_list_path", "extension_manager.root_package_name", "extension_manager.minimum_stability", "extension_manager.repositories", "extension_manager.quiet", "worse_reference_finder.plain_text_break_chars", "php.version", "language_server.catch_errors", "language_server.enable_workspace", "language_server.session_parameters", "language_server.method_alias_map", "language_server.diagnostic_sleep_time", "language_server.diagnostics_on_update", "language_server.diagnostics_on_save", "language_server.diagnostic_providers", "language_server,file_events", "language_server.file_event_globs", "language_server_completion.trim_leading_dollar", "language_server_reference_reference_finder.reference_timeout", "language_server_worse_reflection.workspace_index.update_interval", "language_server_code_transform.import_globals", "indexer.enabled_watchers", "indexer.index_path", "indexer.include_patterns", "indexer.exclude_patterns", "indexer.stub_paths", "indexer.poll_time", "indexer.buffer_time", "indexer.project_root", "indexer.reference_finder.deep", "indexer.implementation_finder.deep", "extension_manager.extension_vendor_dir", "extension_manager.vendor_dir", "extension_manager.config_path", "extension_manager.extension_list_path"[]

Exception trace:
  at /Users/siegel/git/phpactor/vendor/phpactor/map-resolver/lib/Resolver.php:92

2021-05-05 11:53:02.263: stderr output from server:  Phpactor\MapResolver\Resolver->resolve() at /Users/siegel/git/phpactor/vendor/phpactor/language-server-extension/lib/LanguageServer/Dispatcher/PhpactorDispatcherFactory.php:86
 Phpactor\Extension\LanguageServer\Dispatcher\PhpactorDispatcherFactory->buildContainer() at /Users/siegel/git/phpactor/vendor/phpactor/language-server-extension/lib/LanguageServer/Dispatcher/PhpactorDispatcherFactory.php:56
 Phpactor\Extension\LanguageServer\Dispatcher\PhpactorDispatcherFactory->createContainer() at /Users/siegel/git/phpactor/vendor/phpactor/language-server-extension/lib/LanguageServer/Dispatcher/PhpactorDispatcherFactory.php:33
 Phpactor\Extension\LanguageServer\Dispatcher\PhpactorDispatcherFactory->create() at /Users/siegel/git/phpactor/vendor/phpactor/language-server/lib/Core/Server/LanguageServer.php:210
 Phpactor\LanguageServer\Core\Server\LanguageServer->Phpactor\LanguageServer\Core\Server\{closure}() at n/a:n/a
 Generator->send() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Coroutine.php:118
 Amp\Coroutine->Amp\{closure}() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Internal/Placeholder.php:149
 Amp\Coroutine->resolve() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Coroutine.php:123
 Amp\Coroutine->Amp\{closure}() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Internal/Placeholder.php:149
 Amp\Promise@anonymous\/Users/siegel/git/phpactor/vendor/amphp/amp/lib/Deferred.php:22$374->resolve() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Deferred.php:52
 Amp\Deferred->resolve() at /Users/siegel/git/phpactor/vendor/amphp/byte-stream/lib/ResourceInputStream.php:109
 Amp\ByteStream\ResourceInputStream::Amp\ByteStream\{closure}() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Loop/Driver.php:119
 Amp\Loop\Driver->tick() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Loop/Driver.php:72
 Amp\Loop\Driver->run() at /Users/siegel/git/phpactor/vendor/amphp/amp/lib/Loop.php:95
 Amp\Loop::run() at /Users/siegel/git/phpactor/vendor/phpactor/language-server/lib/Core/Server/LanguageServer.php:113
 Phpactor\LanguageServer\Core\Server\LanguageServer->run() at /Users/siegel/git/phpactor/vendor/phpactor/language-server-extension/lib/LanguageServer/Command/StartCommand.php:59
 Phpactor\Extension\LanguageServer\Command\StartCommand->execute() at /Users/siegel/git/phpactor/vendor/symfony/console/Command/Command.php:256
 Symfony\Component\Console\Command\Command->run() at /Users/siegel/git/phpactor/vendor/symfony/console/Application.php:971
 Symfony\Component\Console\Application->doRunCommand() at /Users/siegel/git/phpactor/vendor/symfony/console/Application.php:290
 Symfony\Component\Console\Application->doRun() at /Users/siegel/git/phpactor/lib/Application.php:54
 Phpactor\Application->doRun() at /Users/siegel/git/phpactor/vendor/symfony/console/Application.php:166
 Symfony\Component\Console\Application->run() at /Users/siegel/git/phpactor/bin/phpactor:42

I'd like to propose that while logging unrecognized parameters is a perfectly suitable debugging behavior when -vvv is specified on the command line, throwing an exception and terminating the server process is probably not the most compatible thing to do for clients.

Would it be possible for phpactor to log (if -vvv is in effect) and then ignore unrecognized parameter keys (in any message)?

Support services

Add support for services (e.g. an indexer)

  • Be able to start and stop services
  • Be able to start services on server initialized call
  • Send "notifications" to the client.

Refactoring:

  • Refactor to extract a "message publsher" class
  • Make the message publisher available in the ApplicationHandlerLoader (e.g. in the connection specific Phpactor instance)
  • Services are long running co-routines
  • A service manager could start / stop services potentially.

Windows support (issues with pcntl extension)

I was looking for an alternative to felixfbecker/php-language-server in VSCode, since it seems a bit abandoned (latest commit was 12 Dec 2018).

I've found phpactor/vscode-phpactor extension and tried it, but it won't even start.
I've patched the extension to let the server start (Windows path were not taken into account to let the server start...), and I've found that it crashes immediately on my Win10-x64.

First error:

PHP Warning:  Use of undefined constant SIGINT - assumed 'SIGINT' (this will throw an Error in a future version of PHP) in C:\src\phpactor\vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php on line 101
Warning: Use of undefined constant SIGINT - assumed 'SIGINT' (this will throw an Error in a future version of PHP) in C:\src\phpactor\vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php on line 101
PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Amp\Loop::onSignal() must be of the type int, string given, called in C:\src\phpactor\vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php on line 104 and defined in C:\src\phpactor\vendor\amphp\amp\lib\Loop.php:241
Stack trace:
#0 C:\src\phpactor\vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php(104): Amp\Loop::onSignal('SIGINT', Object(Closure))
#1 C:\src\phpactor\vendor\phpactor\language-server-extension\lib\LanguageServer\Command\StartCommand.php(59): Phpactor\LanguageServer\Core\Server\LanguageServer->run()
#2 C:\src\phpactor\vendor\symfony\console\Command\Command.php(299): Phpactor\Extension\LanguageServer\Command\StartCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#3 C:\src\phpactor\vendor\symfony\console\Application.php(978): Symfony\Component\Conso in C:\src\phpactor\vendor\amphp\amp\lib\Loop.php on line 241
Fatal error: Uncaught TypeError: Argument 1 passed to Amp\Loop::onSignal() must be of the type int, string given, called in C:\src\phpactor\vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php on line 104 and defined in C:\src\phpactor\vendor\amphp\amp\lib\Loop.php:241
Stack trace:
#0 C:\src\phpactor\vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php(104): Amp\Loop::onSignal('SIGINT', Object(Closure))
#1 C:\src\phpactor\vendor\phpactor\language-server-extension\lib\LanguageServer\Command\StartCommand.php(59): Phpactor\LanguageServer\Core\Server\LanguageServer->run()
#2 C:\src\phpactor\vendor\symfony\console\Command\Command.php(299): Phpactor\Extension\LanguageServer\Command\StartCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#3 C:\src\phpactor\vendor\symfony\console\Application.php(978): Symfony\Component\Conso in C:\src\phpactor\vendor\amphp\amp\lib\Loop.php on line 241

These errors are due to missing SIGINT, defined in pcntl extension, which is not available on Windows.

I've added define ("SIGINT", 2); in \vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php and checked again:

# bin/phpactor language-server -vvv
Starting language server, use -vvv for verbose output

In NativeDriver.php line 91:

  [Amp\Loop\UnsupportedFeatureException]
  Signal handling requires the pcntl extension


Exception trace:
  at C:\src\phpactor\vendor\amphp\amp\lib\Loop\NativeDriver.php:91
 Amp\Loop\NativeDriver->onSignal() at C:\src\phpactor\vendor\amphp\amp\lib\Loop.php:243
 Amp\Loop::onSignal() at C:\src\phpactor\vendor\phpactor\language-server\lib\Core\Server\LanguageServer.php:104
 Phpactor\LanguageServer\Core\Server\LanguageServer->run() at C:\src\phpactor\vendor\phpactor\language-server-extension\lib\LanguageServer\Command\StartCommand.php:59
 Phpactor\Extension\LanguageServer\Command\StartCommand->execute() at C:\src\phpactor\vendor\symfony\console\Command\Command.php:299
 Symfony\Component\Console\Command\Command->run() at C:\src\phpactor\vendor\symfony\console\Application.php:978
 Symfony\Component\Console\Application->doRunCommand() at C:\src\phpactor\vendor\symfony\console\Application.php:295
 Symfony\Component\Console\Application->doRun() at C:\src\phpactor\lib\Application.php:54
 Phpactor\Application->doRun() at C:\src\phpactor\vendor\symfony\console\Application.php:167
 Symfony\Component\Console\Application->run() at C:\src\phpactor\bin\phpactor:42

language-server [--address ADDRESS] [--no-loop]

The same behavior should be reproduced on non-Windows systems by disabling the pcntl extension.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.