From d3213db3ed8c8ce70de9d700a1dc079dcda7768d Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sat, 22 Jan 2022 23:16:10 +0100
Subject: [PATCH 01/18] Allow to disable `textDocument/signatureHelp` and
 `textDocument/completion`

---
 .../Handler/CompletionHandler.php             | 28 +++++++++++++------
 .../Handler/SignatureHelpHandler.php          | 15 +++++++---
 .../LanguageServerCompletionExtension.php     |  5 ++--
 3 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/lib/LanguageServerCompletion/Handler/CompletionHandler.php b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
index 50778af6..a72fb011 100644
--- a/lib/LanguageServerCompletion/Handler/CompletionHandler.php
+++ b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
@@ -9,6 +9,7 @@
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\Extension\LanguageServerCodeTransform\Model\NameImport\NameImporter;
 use Phpactor\Extension\LanguageServerCodeTransform\Model\NameImport\NameImporterResult;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\CompletionItem;
 use Phpactor\LanguageServerProtocol\CompletionList;
 use Phpactor\LanguageServerProtocol\CompletionOptions;
@@ -51,21 +52,21 @@ class CompletionHandler implements Handler, CanRegisterCapabilities
     private $workspace;
 
     /**
-     * @var bool
+     * @var NameImporter
      */
-    private $supportSnippets;
+    private $nameImporter;
 
     /**
-     * @var NameImporter
+     * @var ClientCapabilities
      */
-    private $nameImporter;
+    private ClientCapabilities $clientCapabilities;
 
     public function __construct(
         Workspace $workspace,
         TypedCompletorRegistry $registry,
         SuggestionNameFormatter $suggestionNameFormatter,
         NameImporter $nameImporter,
-        bool $supportSnippets,
+        ClientCapabilities $clientCapabilities,
         bool $provideTextEdit = false
     ) {
         $this->registry = $registry;
@@ -73,7 +74,7 @@ public function __construct(
         $this->workspace = $workspace;
         $this->suggestionNameFormatter = $suggestionNameFormatter;
         $this->nameImporter = $nameImporter;
-        $this->supportSnippets = $supportSnippets;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     public function methods(): array
@@ -142,8 +143,12 @@ public function completion(CompletionParams $params, CancellationToken $token):
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $capabilities->completionProvider = new CompletionOptions([':', '>', '$']);
-        $capabilities->signatureHelpProvider = new SignatureHelpOptions(['(', ',']);
+        $capabilities->completionProvider = (null !== $this->clientCapabilities->textDocument->completion)
+            ? new CompletionOptions([':', '>', '$'])
+            : null;
+        $capabilities->signatureHelpProvider = (null !== $this->clientCapabilities->textDocument->signatureHelp)
+            ? new SignatureHelpOptions(['(', ','])
+            : null;
     }
 
     private function determineInsertTextAndFormat(
@@ -154,7 +159,7 @@ private function determineInsertTextAndFormat(
         $insertText = $name;
         $insertTextFormat = InsertTextFormat::PLAIN_TEXT;
 
-        if ($this->supportSnippets) {
+        if ($this->supportSnippets()) {
             $insertText = $suggestion->snippet() ?: $name;
             $insertTextFormat = $suggestion->snippet()
                 ? InsertTextFormat::SNIPPET
@@ -170,6 +175,11 @@ private function determineInsertTextAndFormat(
         return [$insertText, $insertTextFormat];
     }
 
+    private function supportSnippets(): bool
+    {
+        return $this->clientCapabilities->textDocument->completion->completionItem['snippetSupport'] ?? false;
+    }
+
     private function importClassOrFunctionName(
         Suggestion $suggestion,
         CompletionParams $params
diff --git a/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php b/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php
index 7deb47cb..8559a3ee 100644
--- a/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php
+++ b/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Position;
 use Phpactor\LanguageServerProtocol\ServerCapabilities;
 use Phpactor\LanguageServerProtocol\SignatureHelp;
@@ -29,10 +30,16 @@ class SignatureHelpHandler implements Handler, CanRegisterCapabilities
      */
     private $helper;
 
-    public function __construct(Workspace $workspace, SignatureHelper $helper)
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(Workspace $workspace, SignatureHelper $helper, ClientCapabilities $clientCapabilities)
     {
         $this->workspace = $workspace;
         $this->helper = $helper;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     /**
@@ -67,8 +74,8 @@ public function signatureHelp(
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $options = new SignatureHelpOptions();
-        $options->triggerCharacters = [ '(', ',' ];
-        $capabilities->signatureHelpProvider = $options;
+        $capabilities->signatureHelpProvider = (null !== $this->clientCapabilities->textDocument->signatureHelp)
+            ? new SignatureHelpOptions(['(', ','])
+            : null;
     }
 }
diff --git a/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php b/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
index 66f1093a..205f455c 100644
--- a/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
+++ b/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
@@ -47,7 +47,7 @@ private function registerHandlers(ContainerBuilder $container): void
                 $container->get(CompletionExtension::SERVICE_REGISTRY),
                 $container->get(SuggestionNameFormatter::class),
                 $container->get(NameImporter::class),
-                $this->clientCapabilities($container)->textDocument->completion->completionItem['snippetSupport'] ?? false
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [
             'methods' => [
@@ -62,7 +62,8 @@ private function registerHandlers(ContainerBuilder $container): void
         $container->register('language_server_completion.handler.signature_help', function (Container $container) {
             return new SignatureHelpHandler(
                 $container->get(LanguageServerExtension::SERVICE_SESSION_WORKSPACE),
-                $container->get(CompletionExtension::SERVICE_SIGNATURE_HELPER)
+                $container->get(CompletionExtension::SERVICE_SIGNATURE_HELPER),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
     }

From c5f4d7b8cbebcbc69a32526822dde87e7e22f22d Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 00:09:57 +0100
Subject: [PATCH 02/18] Fix CompletionHandlerTest

---
 .../Unit/Handler/CompletionHandlerTest.php    | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
index 2880503b..91dae5b5 100644
--- a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
+++ b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
@@ -8,10 +8,13 @@
 use Phpactor\CodeTransform\Domain\Refactor\ImportClass\NameImport;
 use Phpactor\Extension\LanguageServerCodeTransform\Model\NameImport\NameImporter;
 use Phpactor\Extension\LanguageServerCodeTransform\Model\NameImport\NameImporterResult;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
+use Phpactor\LanguageServerProtocol\CompletionClientCapabilities;
 use Phpactor\LanguageServerProtocol\CompletionItem;
 use Phpactor\LanguageServerProtocol\CompletionList;
 use Phpactor\LanguageServerProtocol\Position;
 use Phpactor\LanguageServerProtocol\Range;
+use Phpactor\LanguageServerProtocol\TextDocumentClientCapabilities;
 use Phpactor\LanguageServerProtocol\TextEdit;
 use PHPUnit\Framework\TestCase;
 use Phpactor\Completion\Core\Completor;
@@ -389,7 +392,7 @@ private function create(
             $registry,
             new SuggestionNameFormatter(true),
             $this->createNameImporter($suggestions, $aliases, $importNameTextEdits),
-            $supportSnippets,
+            $this->createClientCapabilities(true, $supportSnippets),
             true
         ))->build();
         $tester->textDocument()->open(self::EXAMPLE_URI, self::EXAMPLE_TEXT);
@@ -397,6 +400,20 @@ private function create(
         return $tester;
     }
 
+    private function createClientCapabilities(
+        bool $completion = true,
+        bool $supportSnippets = true,
+    ): ClientCapabilities {
+        $capabilities = new ClientCapabilities();
+        $capabilities->textDocument = new TextDocumentClientCapabilities();
+        $capabilities->textDocument->completion = $completion ? new CompletionClientCapabilities() : null;
+        if ($completion && $supportSnippets) {
+            $capabilities->textDocument->completion->completionItem['snippetSupport'] = true;
+        }
+
+        return $capabilities;
+    }
+
     /**
      * @param array<Suggestion> $suggestions
      * @param array<string|null> $aliases

From ec58d09cfc80ecce8bb7c5a1657e0ffcb1bfe382 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 00:13:46 +0100
Subject: [PATCH 03/18] fixup! Fix CompletionHandlerTest

---
 .../Unit/Handler/CompletionHandlerTest.php         | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
index 91dae5b5..3c678976 100644
--- a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
+++ b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
@@ -406,11 +406,19 @@ private function createClientCapabilities(
     ): ClientCapabilities {
         $capabilities = new ClientCapabilities();
         $capabilities->textDocument = new TextDocumentClientCapabilities();
-        $capabilities->textDocument->completion = $completion ? new CompletionClientCapabilities() : null;
-        if ($completion && $supportSnippets) {
-            $capabilities->textDocument->completion->completionItem['snippetSupport'] = true;
+
+        if (false === $completion) {
+            return $capabilities;
         }
 
+        $completionCapabilities = new CompletionClientCapabilities();
+
+        if ($supportSnippets) {
+            $completionCapabilities->completionItem['snippetSupport'] = true;
+        }
+
+        $capabilities->textDocument->completion = $completionCapabilities;
+
         return $capabilities;
     }
 

From 7248124829e07b3bb887fa4715941a1eab016a8e Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 00:25:58 +0100
Subject: [PATCH 04/18] Fix SignatureHelpHandlerTest

---
 .../Unit/Handler/SignatureHelpHandlerTest.php | 22 ++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/tests/LanguageServerCompletion/Unit/Handler/SignatureHelpHandlerTest.php b/tests/LanguageServerCompletion/Unit/Handler/SignatureHelpHandlerTest.php
index c2430223..9edc486d 100644
--- a/tests/LanguageServerCompletion/Unit/Handler/SignatureHelpHandlerTest.php
+++ b/tests/LanguageServerCompletion/Unit/Handler/SignatureHelpHandlerTest.php
@@ -2,7 +2,10 @@
 
 namespace Phpactor\Extension\LanguageServerCompletion\Tests\Unit\Handler;
 
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\SignatureHelp as LspSignatureHelp;
+use Phpactor\LanguageServerProtocol\SignatureHelpClientCapabilities;
+use Phpactor\LanguageServerProtocol\TextDocumentClientCapabilities;
 use Phpactor\LanguageServerProtocol\TextDocumentIdentifier;
 use PHPUnit\Framework\TestCase;
 use Phpactor\Completion\Core\SignatureHelp;
@@ -38,10 +41,27 @@ private function create(array $suggestions): LanguageServerTester
         $builder = LanguageServerTesterBuilder::create();
         return $builder->addHandler(new SignatureHelpHandler(
             $builder->workspace(),
-            $this->createHelper()
+            $this->createHelper(),
+            $this->createClientCapabilities(true)
         ))->build();
     }
 
+    private function createClientCapabilities(
+        bool $supportSignatureHelp = true
+    ): ClientCapabilities {
+        $capabilities = new ClientCapabilities();
+        $capabilities->textDocument = new TextDocumentClientCapabilities();
+
+        if (false === $supportSignatureHelp) {
+            return $capabilities;
+        }
+
+        $signatureHelpCapabilities = new SignatureHelpClientCapabilities();
+        $capabilities->textDocument->signatureHelp = $signatureHelpCapabilities;
+
+        return $capabilities;
+    }
+
     private function createHelper(): SignatureHelper
     {
         return new class() implements SignatureHelper {

From 94c2e590e7a1b16bb704d3825dcc34cd45018764 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 00:36:50 +0100
Subject: [PATCH 05/18] Avoid cs-fixer deprecations

---
 .php_cs.dist => .php-cs-fixer.dist.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
 rename .php_cs.dist => .php-cs-fixer.dist.php (93%)

diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php
similarity index 93%
rename from .php_cs.dist
rename to .php-cs-fixer.dist.php
index 47f1c506..aecc1615 100644
--- a/.php_cs.dist
+++ b/.php-cs-fixer.dist.php
@@ -8,7 +8,7 @@
     ])
 ;
 
-return PhpCsFixer\Config::create()
+return (new PhpCsFixer\Config())
     ->setRiskyAllowed(true)
     ->setRules([
         '@PSR2' => true,
@@ -22,4 +22,3 @@
     ])
     ->setFinder($finder)
 ;
-

From 619ad404ea9261071b982480c346172b5f56b130 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 02:23:14 +0100
Subject: [PATCH 06/18] Add test that should not pass

---
 .../Unit/Handler/CompletionHandlerTest.php    | 33 +++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
index 3c678976..4ed7e874 100644
--- a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
+++ b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
@@ -49,6 +49,34 @@ public function testHandleNoSuggestions(): void
         $this->assertFalse($response->result->isIncomplete);
     }
 
+    public function testHandleWithDisabledCapability(): void
+    {
+        $tester = $this->create(
+            [
+                Suggestion::create('hello'),
+                Suggestion::create('goodbye'),
+            ],
+            true,
+            false,
+            [],
+            [],
+            false
+        );
+        $response = $tester->requestAndWait(
+            'textDocument/completion',
+            [
+                'textDocument' => ProtocolFactory::textDocumentIdentifier(self::EXAMPLE_URI),
+                'position' => ProtocolFactory::position(0, 0)
+            ]
+        );
+        $this->assertInstanceOf(CompletionList::class, $response->result);
+        $this->assertEquals([
+            self::completionItem('hello', null),
+            self::completionItem('goodbye', null),
+        ], $response->result->items);
+        $this->assertFalse($response->result->isIncomplete);
+    }
+
     public function testHandleACompleteListOfSuggestions(): void
     {
         $tester = $this->create([
@@ -380,7 +408,8 @@ private function create(
         bool $supportSnippets = true,
         bool $isIncomplete = false,
         array $importNameTextEdits = [],
-        array $aliases = []
+        array $aliases = [],
+        bool $supportCompletion = true
     ): LanguageServerTester {
         $completor = $this->createCompletor($suggestions, $isIncomplete);
         $registry = new TypedCompletorRegistry([
@@ -392,7 +421,7 @@ private function create(
             $registry,
             new SuggestionNameFormatter(true),
             $this->createNameImporter($suggestions, $aliases, $importNameTextEdits),
-            $this->createClientCapabilities(true, $supportSnippets),
+            $this->createClientCapabilities($supportCompletion, $supportSnippets),
             true
         ))->build();
         $tester->textDocument()->open(self::EXAMPLE_URI, self::EXAMPLE_TEXT);

From c34bac9b2f0fcec431ad73b74b675106f85cf53a Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 18:26:47 +0100
Subject: [PATCH 07/18] Allow to disable the rest of method

---
 .../Handler/HoverHandler.php                  | 19 +++++++++++++----
 .../LanguageServerHoverExtension.php          | 13 +++++++++---
 .../Handler/WorkspaceSymbolHandler.php        | 11 ++++++++--
 .../LanguageServerIndexerExtension.php        |  8 ++++++-
 .../Handler/GotoDefinitionHandler.php         | 17 ++++++++++++---
 .../Handler/GotoImplementationHandler.php     | 16 ++++++++++++--
 .../Handler/HighlightHandler.php              | 13 +++++++++++-
 .../Handler/ReferencesHandler.php             | 12 +++++++++--
 .../Handler/TypeDefinitionHandler.php         | 16 ++++++++++++--
 ...LanguageServerReferenceFinderExtension.php | 21 ++++++++++++++-----
 .../Handler/DocumentSymbolProviderHandler.php | 18 ++++++++++++++--
 .../LanguageServerSymbolProviderExtension.php |  9 +++++++-
 12 files changed, 145 insertions(+), 28 deletions(-)

diff --git a/lib/LanguageServerHover/Handler/HoverHandler.php b/lib/LanguageServerHover/Handler/HoverHandler.php
index a396ac4a..7b1b4992 100644
--- a/lib/LanguageServerHover/Handler/HoverHandler.php
+++ b/lib/LanguageServerHover/Handler/HoverHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Hover;
 use Phpactor\LanguageServerProtocol\MarkupContent;
 use Phpactor\LanguageServerProtocol\Position;
@@ -43,11 +44,21 @@ class HoverHandler implements Handler, CanRegisterCapabilities
      */
     private $workspace;
 
-    public function __construct(Workspace $workspace, Reflector $reflector, ObjectRenderer $renderer)
-    {
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(
+        Workspace $workspace,
+        Reflector $reflector,
+        ObjectRenderer $renderer,
+        ClientCapabilities $clientCapabilities
+    ) {
         $this->reflector = $reflector;
         $this->renderer = $renderer;
         $this->workspace = $workspace;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     public function methods(): array
@@ -73,7 +84,7 @@ public function hover(
             $symbolContext = $offsetReflection->symbolContext();
             $info = $this->infoFromReflecionOffset($offsetReflection);
             $string = new MarkupContent('markdown', $info);
-            
+
             return new Hover($string, new Range(
                 PositionConverter::byteOffsetToPosition(
                     ByteOffset::fromInt($symbolContext->symbol()->position()->start()),
@@ -89,7 +100,7 @@ public function hover(
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $capabilities->hoverProvider = true;
+        $capabilities->hoverProvider = null !== $this->clientCapabilities->textDocument->hover;
     }
 
     private function infoFromReflecionOffset(ReflectionOffset $offset): string
diff --git a/lib/LanguageServerHover/LanguageServerHoverExtension.php b/lib/LanguageServerHover/LanguageServerHoverExtension.php
index 62935168..0880fea4 100644
--- a/lib/LanguageServerHover/LanguageServerHoverExtension.php
+++ b/lib/LanguageServerHover/LanguageServerHoverExtension.php
@@ -9,6 +9,7 @@
 use Phpactor\Extension\Php\Model\PhpVersionResolver;
 use Phpactor\Extension\WorseReflection\WorseReflectionExtension;
 use Phpactor\FilePathResolverExtension\FilePathResolverExtension;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\ObjectRenderer\ObjectRendererBuilder;
 use Phpactor\Extension\LanguageServer\LanguageServerExtension;
 use Phpactor\Extension\LanguageServerHover\Handler\HoverHandler;
@@ -18,7 +19,7 @@
 class LanguageServerHoverExtension implements Extension
 {
     public const PARAM_TEMPLATE_PATHS = 'language_server_hover.template_paths';
-    
+
     private const SERVICE_MARKDOWN_RENDERER = 'language_server_completion.object_renderer.markdown';
 
     /**
@@ -47,7 +48,8 @@ public function load(ContainerBuilder $container): void
             return new HoverHandler(
                 $container->get(LanguageServerExtension::SERVICE_SESSION_WORKSPACE),
                 $container->get(WorseReflectionExtension::SERVICE_REFLECTOR),
-                $container->get(self::SERVICE_MARKDOWN_RENDERER)
+                $container->get(self::SERVICE_MARKDOWN_RENDERER),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => []]);
 
@@ -71,8 +73,13 @@ public function load(ContainerBuilder $container): void
             foreach ($paths as $path) {
                 $builder = $builder->addTemplatePath($path);
             }
-            
+
             return $builder->build();
         });
     }
+
+    private function clientCapabilities(Container $container): ClientCapabilities
+    {
+        return $container->get(ClientCapabilities::class);
+    }
 }
diff --git a/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php b/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php
index 44260069..06f48994 100644
--- a/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php
+++ b/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Phpactor\Extension\LanguageServerIndexer\Model\WorkspaceSymbolProvider;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\ServerCapabilities;
 use Phpactor\LanguageServerProtocol\SymbolInformation;
 use Phpactor\LanguageServerProtocol\WorkspaceSymbolParams;
@@ -17,9 +18,15 @@ class WorkspaceSymbolHandler implements Handler, CanRegisterCapabilities
      */
     private $provider;
 
-    public function __construct(WorkspaceSymbolProvider $provider)
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(WorkspaceSymbolProvider $provider, ClientCapabilities $clientCapabilities)
     {
         $this->provider = $provider;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     public function methods(): array
@@ -42,6 +49,6 @@ public function symbol(
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $capabilities->workspaceSymbolProvider = true;
+        $capabilities->workspaceSymbolProvider = null !== ($this->clientCapabilities->workspace['symbol'] ?? null);
     }
 }
diff --git a/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php b/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php
index 7304d183..e2a063d6 100644
--- a/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php
+++ b/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php
@@ -40,7 +40,8 @@ public function load(ContainerBuilder $container): void
                     $container->get(SearchClient::class),
                     $container->get(TextDocumentLocator::class),
                     $container->getParameter(self::WORKSPACE_SYMBOL_SEARCH_LIMIT)
-                )
+                ),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
 
@@ -84,4 +85,9 @@ private function registerSessionHandler(ContainerBuilder $container): void
             LanguageServerExtension::TAG_LISTENER_PROVIDER => [],
         ]);
     }
+
+    private function clientCapabilities(Container $container): ClientCapabilities
+    {
+        return $container->get(ClientCapabilities::class);
+    }
 }
diff --git a/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php b/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php
index 28107629..87d4a32e 100644
--- a/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\DefinitionParams;
 use Phpactor\LanguageServerProtocol\ServerCapabilities;
 use Phpactor\Extension\LanguageServerBridge\Converter\LocationConverter;
@@ -31,11 +32,21 @@ class GotoDefinitionHandler implements Handler, CanRegisterCapabilities
      */
     private $locationConverter;
 
-    public function __construct(Workspace $workspace, DefinitionLocator $definitionLocator, LocationConverter $locationConverter)
-    {
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(
+        Workspace $workspace,
+        DefinitionLocator $definitionLocator,
+        LocationConverter $locationConverter,
+        ClientCapabilities $clientCapabilities
+    ) {
         $this->definitionLocator = $definitionLocator;
         $this->workspace = $workspace;
         $this->locationConverter = $locationConverter;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     public function methods(): array
@@ -70,6 +81,6 @@ public function definition(
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $capabilities->definitionProvider = true;
+        $capabilities->definitionProvider = null !== $this->clientCapabilities->textDocument->definition;
     }
 }
diff --git a/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php b/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
index f0fa10b9..5ca4fb90 100644
--- a/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\ImplementationParams;
 use Phpactor\LanguageServerProtocol\ServerCapabilities;
 use Phpactor\Extension\LanguageServerBridge\Converter\LocationConverter;
@@ -30,11 +31,22 @@ class GotoImplementationHandler implements Handler, CanRegisterCapabilities
      */
     private $locationConverter;
 
-    public function __construct(Workspace $workspace, ClassImplementationFinder $finder, LocationConverter $locationConverter)
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(
+        Workspace $workspace,
+        ClassImplementationFinder $finder,
+        LocationConverter $locationConverter,
+        ClientCapabilities $clientCapabilities
+    )
     {
         $this->workspace = $workspace;
         $this->finder = $finder;
         $this->locationConverter = $locationConverter;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     /**
@@ -68,6 +80,6 @@ public function gotoImplementation(ImplementationParams $params): Promise
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $capabilities->implementationProvider = true;
+        $capabilities->implementationProvider = null !== $this->clientCapabilities->textDocument->implementation;
     }
 }
diff --git a/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php b/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php
index 78a6d2f6..4467500f 100644
--- a/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php
@@ -6,6 +6,7 @@
 use Amp\Success;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\Extension\LanguageServerReferenceFinder\Model\Highlighter;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\DocumentHighlight;
 use Phpactor\LanguageServerProtocol\DocumentHighlightOptions;
 use Phpactor\LanguageServerProtocol\DocumentHighlightParams;
@@ -27,10 +28,16 @@ class HighlightHandler implements Handler, CanRegisterCapabilities
      */
     private $highlighter;
 
-    public function __construct(Workspace $workspace, Highlighter $highlighter)
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(Workspace $workspace, Highlighter $highlighter, ClientCapabilities $clientCapabilities)
     {
         $this->workspace = $workspace;
         $this->highlighter = $highlighter;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     /**
@@ -56,6 +63,10 @@ public function highlight(DocumentHighlightParams $params): Promise
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
+        if (null === $this->clientCapabilities->textDocument->documentHighlight) {
+            return;
+        }
+
         $options = new DocumentHighlightOptions();
         $capabilities->documentHighlightProvider = $options;
     }
diff --git a/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php b/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php
index 7b686560..e7e19cb5 100644
--- a/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php
@@ -5,6 +5,7 @@
 use Amp\Delayed;
 use Amp\Promise;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Location as LspLocation;
 use Phpactor\LanguageServerProtocol\Position;
 use Phpactor\LanguageServerProtocol\ReferenceContext;
@@ -55,13 +56,19 @@ class ReferencesHandler implements Handler, CanRegisterCapabilities
      */
     private $clientApi;
 
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
     public function __construct(
         Workspace $workspace,
         ReferenceFinder $finder,
         DefinitionLocator $definitionLocator,
         LocationConverter $locationConverter,
         ClientApi $clientApi,
-        float $timeoutSeconds = 5.0
+        float $timeoutSeconds = 5.0,
+        ClientCapabilities $clientCapabilities
     ) {
         $this->workspace = $workspace;
         $this->finder = $finder;
@@ -69,6 +76,7 @@ public function __construct(
         $this->timeoutSeconds = $timeoutSeconds;
         $this->locationConverter = $locationConverter;
         $this->clientApi = $clientApi;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     /**
@@ -157,7 +165,7 @@ public function references(
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $capabilities->referencesProvider = true;
+        $capabilities->referencesProvider = null !== $this->clientCapabilities->textDocument->references;
     }
 
     /**
diff --git a/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php b/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
index 6917ef2b..f189e418 100644
--- a/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Position;
 use Phpactor\LanguageServerProtocol\ServerCapabilities;
 use Phpactor\LanguageServerProtocol\TextDocumentIdentifier;
@@ -32,11 +33,22 @@ class TypeDefinitionHandler implements Handler, CanRegisterCapabilities
      */
     private $locationConverter;
 
-    public function __construct(Workspace $workspace, TypeLocator $typeLocator, LocationConverter $locationConverter)
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(
+        Workspace $workspace,
+        TypeLocator $typeLocator,
+        LocationConverter $locationConverter,
+        ClientCapabilities $clientCapabilities
+    )
     {
         $this->typeLocator = $typeLocator;
         $this->workspace = $workspace;
         $this->locationConverter = $locationConverter;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     public function methods(): array
@@ -70,6 +82,6 @@ public function type(
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
-        $capabilities->typeDefinitionProvider = true;
+        $capabilities->typeDefinitionProvider = null !== $this->clientCapabilities->textDocument->typeDefinition;
     }
 }
diff --git a/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php b/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
index ec33b307..229d5e4b 100644
--- a/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
+++ b/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
@@ -17,6 +17,7 @@
 use Phpactor\Extension\LanguageServer\LanguageServerExtension;
 use Phpactor\Extension\ReferenceFinder\ReferenceFinderExtension;
 use Phpactor\Indexer\Model\Indexer;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServer\Core\Server\ClientApi;
 use Phpactor\MapResolver\Resolver;
 use Phpactor\ReferenceFinder\ReferenceFinder;
@@ -34,7 +35,8 @@ public function load(ContainerBuilder $container): void
             return new GotoDefinitionHandler(
                 $container->get(LanguageServerExtension::SERVICE_SESSION_WORKSPACE),
                 $container->get(ReferenceFinderExtension::SERVICE_DEFINITION_LOCATOR),
-                $container->get(LocationConverter::class)
+                $container->get(LocationConverter::class),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
 
@@ -42,7 +44,8 @@ public function load(ContainerBuilder $container): void
             return new TypeDefinitionHandler(
                 $container->get(LanguageServerExtension::SERVICE_SESSION_WORKSPACE),
                 $container->get(ReferenceFinderExtension::SERVICE_TYPE_LOCATOR),
-                $container->get(LocationConverter::class)
+                $container->get(LocationConverter::class),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
 
@@ -61,7 +64,8 @@ public function load(ContainerBuilder $container): void
                 $container->get(ReferenceFinderExtension::SERVICE_DEFINITION_LOCATOR),
                 $container->get(LocationConverter::class),
                 $container->get(ClientApi::class),
-                $container->getParameter(self::PARAM_REFERENCE_TIMEOUT)
+                $container->getParameter(self::PARAM_REFERENCE_TIMEOUT),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
 
@@ -69,14 +73,16 @@ public function load(ContainerBuilder $container): void
             return new GotoImplementationHandler(
                 $container->get(LanguageServerExtension::SERVICE_SESSION_WORKSPACE),
                 $container->get(ReferenceFinderExtension::SERVICE_IMPLEMENTATION_FINDER),
-                $container->get(LocationConverter::class)
+                $container->get(LocationConverter::class),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
 
         $container->register(HighlightHandler::class, function (Container $container) {
             return new HighlightHandler(
                 $container->get(LanguageServerExtension::SERVICE_SESSION_WORKSPACE),
-                new Highlighter(new Parser())
+                new Highlighter(new Parser()),
+                $this->clientCapabilities($container)
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
     }
@@ -93,4 +99,9 @@ public function configure(Resolver $schema): void
             self::PARAM_REFERENCE_TIMEOUT => 'Stop searching for references after this time (in seconds) has expired',
         ]);
     }
+
+    private function clientCapabilities(Container $container): ClientCapabilities
+    {
+        return $container->get(ClientCapabilities::class);
+    }
 }
diff --git a/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php b/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
index e9a8e1aa..e7bd8311 100644
--- a/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
+++ b/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
@@ -5,6 +5,7 @@
 use Amp\Promise;
 use Amp\Success;
 use Phpactor\Extension\LanguageServerSymbolProvider\Model\DocumentSymbolProvider;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\DocumentSymbolOptions;
 use Phpactor\LanguageServerProtocol\DocumentSymbolParams;
 use Phpactor\LanguageServerProtocol\DocumentSymbolRequest;
@@ -25,10 +26,19 @@ class DocumentSymbolProviderHandler implements Handler, CanRegisterCapabilities
      */
     private $provider;
 
-    public function __construct(Workspace $workspace, DocumentSymbolProvider $provider)
-    {
+    /**
+     * @var ClientCapabilities
+     */
+    private ClientCapabilities $clientCapabilities;
+
+    public function __construct(
+        Workspace $workspace,
+        DocumentSymbolProvider $provider,
+        ClientCapabilities $clientCapabilities,
+    ) {
         $this->workspace = $workspace;
         $this->provider = $provider;
+        $this->clientCapabilities = $clientCapabilities;
     }
 
     /**
@@ -53,6 +63,10 @@ public function documentSymbols(DocumentSymbolParams $params): Promise
 
     public function registerCapabiltiies(ServerCapabilities $capabilities): void
     {
+        if (null === $this->clientCapabilities->textDocument->documentSymbol) {
+            return;
+        }
+
         $capabilities->documentSymbolProvider = new DocumentSymbolOptions();
     }
 }
diff --git a/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php b/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
index c293f537..4eee898d 100644
--- a/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
+++ b/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
@@ -10,6 +10,7 @@
 use Phpactor\Extension\LanguageServerSymbolProvider\Handler\DocumentSymbolProviderHandler;
 use Phpactor\Extension\LanguageServerSymbolProvider\Model\DocumentSymbolProvider;
 use Phpactor\Extension\LanguageServer\LanguageServerExtension;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\MapResolver\Resolver;
 
 class LanguageServerSymbolProviderExtension implements Extension
@@ -22,7 +23,8 @@ public function load(ContainerBuilder $container): void
         $container->register(DocumentSymbolProviderHandler::class, function (Container $container) {
             return new DocumentSymbolProviderHandler(
                 $container->get(LanguageServerExtension::SERVICE_SESSION_WORKSPACE),
-                $container->get(DocumentSymbolProvider::class)
+                $container->get(DocumentSymbolProvider::class),
+                $this->clientCapabilities($container)
             );
         }, [
             LanguageServerExtension::TAG_METHOD_HANDLER => [],
@@ -38,4 +40,9 @@ public function load(ContainerBuilder $container): void
     public function configure(Resolver $schema): void
     {
     }
+
+    private function clientCapabilities(Container $container): ClientCapabilities
+    {
+        return $container->get(ClientCapabilities::class);
+    }
 }

From 5aa58fe1890d4a481968826c1fa6740cfd6820b4 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 19:45:19 +0100
Subject: [PATCH 08/18] Move duplicated clientCapabilities() to
 AbstractExtension

---
 lib/AbstractExtension.php                          | 14 ++++++++++++++
 .../LanguageServerCompletionExtension.php          |  8 ++------
 .../LanguageServerHoverExtension.php               |  8 ++------
 .../LanguageServerIndexerExtension.php             |  8 ++------
 .../LanguageServerReferenceFinderExtension.php     |  8 ++------
 .../LanguageServerSymbolProviderExtension.php      |  8 ++------
 6 files changed, 24 insertions(+), 30 deletions(-)
 create mode 100644 lib/AbstractExtension.php

diff --git a/lib/AbstractExtension.php b/lib/AbstractExtension.php
new file mode 100644
index 00000000..5c41128c
--- /dev/null
+++ b/lib/AbstractExtension.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Phpactor\Extension;
+
+use Phpactor\Container\Container;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
+
+abstract class AbstractExtension
+{
+    protected function clientCapabilities(Container $container): ClientCapabilities
+    {
+        return $container->get(ClientCapabilities::class);
+    }
+}
diff --git a/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php b/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
index 205f455c..ce90de42 100644
--- a/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
+++ b/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
@@ -5,6 +5,7 @@
 use Phpactor\Container\Container;
 use Phpactor\Container\ContainerBuilder;
 use Phpactor\Container\Extension;
+use Phpactor\Extension\AbstractExtension;
 use Phpactor\Extension\Completion\CompletionExtension;
 use Phpactor\Extension\LanguageServerCodeTransform\Model\NameImport\NameImporter;
 use Phpactor\Extension\LanguageServerCompletion\Handler\SignatureHelpHandler;
@@ -14,7 +15,7 @@
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\MapResolver\Resolver;
 
-class LanguageServerCompletionExtension implements Extension
+class LanguageServerCompletionExtension extends AbstractExtension implements Extension
 {
     private const PARAM_TRIM_LEADING_DOLLAR = 'language_server_completion.trim_leading_dollar';
 
@@ -67,9 +68,4 @@ private function registerHandlers(ContainerBuilder $container): void
             );
         }, [ LanguageServerExtension::TAG_METHOD_HANDLER => [] ]);
     }
-
-    private function clientCapabilities(Container $container): ClientCapabilities
-    {
-        return $container->get(ClientCapabilities::class);
-    }
 }
diff --git a/lib/LanguageServerHover/LanguageServerHoverExtension.php b/lib/LanguageServerHover/LanguageServerHoverExtension.php
index 0880fea4..7abf735e 100644
--- a/lib/LanguageServerHover/LanguageServerHoverExtension.php
+++ b/lib/LanguageServerHover/LanguageServerHoverExtension.php
@@ -5,6 +5,7 @@
 use Phpactor\CodeBuilder\Domain\TemplatePathResolver\PhpVersionPathResolver;
 use Phpactor\Container\Container;
 use Phpactor\Container\ContainerBuilder;
+use Phpactor\Extension\AbstractExtension;
 use Phpactor\Extension\Logger\LoggingExtension;
 use Phpactor\Extension\Php\Model\PhpVersionResolver;
 use Phpactor\Extension\WorseReflection\WorseReflectionExtension;
@@ -16,7 +17,7 @@
 use Phpactor\Container\Extension;
 use Phpactor\MapResolver\Resolver;
 
-class LanguageServerHoverExtension implements Extension
+class LanguageServerHoverExtension extends AbstractExtension implements Extension
 {
     public const PARAM_TEMPLATE_PATHS = 'language_server_hover.template_paths';
 
@@ -77,9 +78,4 @@ public function load(ContainerBuilder $container): void
             return $builder->build();
         });
     }
-
-    private function clientCapabilities(Container $container): ClientCapabilities
-    {
-        return $container->get(ClientCapabilities::class);
-    }
 }
diff --git a/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php b/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php
index e2a063d6..f623923e 100644
--- a/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php
+++ b/lib/LanguageServerIndexer/LanguageServerIndexerExtension.php
@@ -6,6 +6,7 @@
 use Phpactor\Container\Container;
 use Phpactor\Container\ContainerBuilder;
 use Phpactor\Container\Extension;
+use Phpactor\Extension\AbstractExtension;
 use Phpactor\Extension\LanguageServerIndexer\Handler\IndexerHandler;
 use Phpactor\Extension\LanguageServerIndexer\Handler\WorkspaceSymbolHandler;
 use Phpactor\Extension\LanguageServerIndexer\Listener\ReindexListener;
@@ -23,7 +24,7 @@
 use Phpactor\TextDocument\TextDocumentLocator;
 use Psr\EventDispatcher\EventDispatcherInterface;
 
-class LanguageServerIndexerExtension implements Extension
+class LanguageServerIndexerExtension extends AbstractExtension implements Extension
 {
     public const WORKSPACE_SYMBOL_SEARCH_LIMIT = 'language_server_indexer.workspace_symbol_search_limit';
 
@@ -85,9 +86,4 @@ private function registerSessionHandler(ContainerBuilder $container): void
             LanguageServerExtension::TAG_LISTENER_PROVIDER => [],
         ]);
     }
-
-    private function clientCapabilities(Container $container): ClientCapabilities
-    {
-        return $container->get(ClientCapabilities::class);
-    }
 }
diff --git a/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php b/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
index 229d5e4b..0e8f89a3 100644
--- a/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
+++ b/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
@@ -6,6 +6,7 @@
 use Phpactor\Container\Container;
 use Phpactor\Container\ContainerBuilder;
 use Phpactor\Container\Extension;
+use Phpactor\Extension\AbstractExtension;
 use Phpactor\Extension\LanguageServerBridge\Converter\LocationConverter;
 use Phpactor\Extension\LanguageServerReferenceFinder\Handler\GotoDefinitionHandler;
 use Phpactor\Extension\LanguageServerReferenceFinder\Handler\GotoImplementationHandler;
@@ -22,7 +23,7 @@
 use Phpactor\MapResolver\Resolver;
 use Phpactor\ReferenceFinder\ReferenceFinder;
 
-class LanguageServerReferenceFinderExtension implements Extension
+class LanguageServerReferenceFinderExtension extends AbstractExtension implements Extension
 {
     const PARAM_REFERENCE_TIMEOUT = 'language_server_reference_reference_finder.reference_timeout';
 
@@ -99,9 +100,4 @@ public function configure(Resolver $schema): void
             self::PARAM_REFERENCE_TIMEOUT => 'Stop searching for references after this time (in seconds) has expired',
         ]);
     }
-
-    private function clientCapabilities(Container $container): ClientCapabilities
-    {
-        return $container->get(ClientCapabilities::class);
-    }
 }
diff --git a/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php b/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
index 4eee898d..34a7118e 100644
--- a/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
+++ b/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
@@ -6,6 +6,7 @@
 use Phpactor\Container\Container;
 use Phpactor\Container\ContainerBuilder;
 use Phpactor\Container\Extension;
+use Phpactor\Extension\AbstractExtension;
 use Phpactor\Extension\LanguageServerSymbolProvider\Adapter\TolerantDocumentSymbolProvider;
 use Phpactor\Extension\LanguageServerSymbolProvider\Handler\DocumentSymbolProviderHandler;
 use Phpactor\Extension\LanguageServerSymbolProvider\Model\DocumentSymbolProvider;
@@ -13,7 +14,7 @@
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\MapResolver\Resolver;
 
-class LanguageServerSymbolProviderExtension implements Extension
+class LanguageServerSymbolProviderExtension extends AbstractExtension implements Extension
 {
     /**
      * {@inheritDoc}
@@ -40,9 +41,4 @@ public function load(ContainerBuilder $container): void
     public function configure(Resolver $schema): void
     {
     }
-
-    private function clientCapabilities(Container $container): ClientCapabilities
-    {
-        return $container->get(ClientCapabilities::class);
-    }
 }

From 9a097f335b86714417937c367655a48e723ae168 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 20:27:58 +0100
Subject: [PATCH 09/18] Move $clientCapabilities to AbstractHandler

---
 lib/AbstractHandler.php                        | 18 ++++++++++++++++++
 .../Handler/CompletionHandler.php              | 10 +++-------
 .../Handler/SignatureHelpHandler.php           | 10 +++-------
 .../Handler/HoverHandler.php                   | 10 +++-------
 .../Handler/WorkspaceSymbolHandler.php         | 10 +++-------
 .../Handler/GotoDefinitionHandler.php          | 10 +++-------
 .../Handler/GotoImplementationHandler.php      | 10 +++-------
 .../Handler/HighlightHandler.php               | 10 +++-------
 .../Handler/ReferencesHandler.php              | 10 +++-------
 .../Handler/TypeDefinitionHandler.php          | 10 +++-------
 .../Handler/DocumentSymbolProviderHandler.php  | 10 +++-------
 11 files changed, 48 insertions(+), 70 deletions(-)
 create mode 100644 lib/AbstractHandler.php

diff --git a/lib/AbstractHandler.php b/lib/AbstractHandler.php
new file mode 100644
index 00000000..c8e52cd1
--- /dev/null
+++ b/lib/AbstractHandler.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Phpactor\Extension;
+
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
+
+abstract class AbstractHandler
+{
+    /**
+     * @var ClientCapabilities
+     */
+    protected $clientCapabilities;
+
+    public function __construct(ClientCapabilities $clientCapabilities)
+    {
+        $this->clientCapabilities = $clientCapabilities;
+    }
+}
diff --git a/lib/LanguageServerCompletion/Handler/CompletionHandler.php b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
index a72fb011..74b9bb21 100644
--- a/lib/LanguageServerCompletion/Handler/CompletionHandler.php
+++ b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
@@ -6,6 +6,7 @@
 use Amp\CancelledException;
 use Amp\Delayed;
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\Extension\LanguageServerCodeTransform\Model\NameImport\NameImporter;
 use Phpactor\Extension\LanguageServerCodeTransform\Model\NameImport\NameImporterResult;
@@ -29,7 +30,7 @@
 use Phpactor\LanguageServer\Core\Workspace\Workspace;
 use Phpactor\TextDocument\TextDocumentBuilder;
 
-class CompletionHandler implements Handler, CanRegisterCapabilities
+class CompletionHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var TypedCompletorRegistry
@@ -56,11 +57,6 @@ class CompletionHandler implements Handler, CanRegisterCapabilities
      */
     private $nameImporter;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(
         Workspace $workspace,
         TypedCompletorRegistry $registry,
@@ -74,7 +70,7 @@ public function __construct(
         $this->workspace = $workspace;
         $this->suggestionNameFormatter = $suggestionNameFormatter;
         $this->nameImporter = $nameImporter;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     public function methods(): array
diff --git a/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php b/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php
index 8559a3ee..8c85cb0f 100644
--- a/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php
+++ b/lib/LanguageServerCompletion/Handler/SignatureHelpHandler.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerCompletion\Handler;
 
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Position;
@@ -18,7 +19,7 @@
 use Phpactor\LanguageServer\Core\Workspace\Workspace;
 use Phpactor\TextDocument\TextDocumentBuilder;
 
-class SignatureHelpHandler implements Handler, CanRegisterCapabilities
+class SignatureHelpHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var Workspace
@@ -30,16 +31,11 @@ class SignatureHelpHandler implements Handler, CanRegisterCapabilities
      */
     private $helper;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(Workspace $workspace, SignatureHelper $helper, ClientCapabilities $clientCapabilities)
     {
         $this->workspace = $workspace;
         $this->helper = $helper;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     /**
diff --git a/lib/LanguageServerHover/Handler/HoverHandler.php b/lib/LanguageServerHover/Handler/HoverHandler.php
index 7b1b4992..ae00b683 100644
--- a/lib/LanguageServerHover/Handler/HoverHandler.php
+++ b/lib/LanguageServerHover/Handler/HoverHandler.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerHover\Handler;
 
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Hover;
@@ -27,7 +28,7 @@
 use Phpactor\WorseReflection\Core\Type;
 use Phpactor\WorseReflection\Reflector;
 
-class HoverHandler implements Handler, CanRegisterCapabilities
+class HoverHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var Reflector
@@ -44,11 +45,6 @@ class HoverHandler implements Handler, CanRegisterCapabilities
      */
     private $workspace;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(
         Workspace $workspace,
         Reflector $reflector,
@@ -58,7 +54,7 @@ public function __construct(
         $this->reflector = $reflector;
         $this->renderer = $renderer;
         $this->workspace = $workspace;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     public function methods(): array
diff --git a/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php b/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php
index 06f48994..1c33e684 100644
--- a/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php
+++ b/lib/LanguageServerIndexer/Handler/WorkspaceSymbolHandler.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerIndexer\Handler;
 
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerIndexer\Model\WorkspaceSymbolProvider;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\ServerCapabilities;
@@ -11,22 +12,17 @@
 use Phpactor\LanguageServer\Core\Handler\CanRegisterCapabilities;
 use Phpactor\LanguageServer\Core\Handler\Handler;
 
-class WorkspaceSymbolHandler implements Handler, CanRegisterCapabilities
+class WorkspaceSymbolHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var WorkspaceSymbolProvider
      */
     private $provider;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(WorkspaceSymbolProvider $provider, ClientCapabilities $clientCapabilities)
     {
         $this->provider = $provider;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     public function methods(): array
diff --git a/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php b/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php
index 87d4a32e..81495603 100644
--- a/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/GotoDefinitionHandler.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerReferenceFinder\Handler;
 
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\DefinitionParams;
@@ -15,7 +16,7 @@
 use Phpactor\ReferenceFinder\Exception\CouldNotLocateDefinition;
 use Phpactor\TextDocument\TextDocumentBuilder;
 
-class GotoDefinitionHandler implements Handler, CanRegisterCapabilities
+class GotoDefinitionHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var DefinitionLocator
@@ -32,11 +33,6 @@ class GotoDefinitionHandler implements Handler, CanRegisterCapabilities
      */
     private $locationConverter;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(
         Workspace $workspace,
         DefinitionLocator $definitionLocator,
@@ -46,7 +42,7 @@ public function __construct(
         $this->definitionLocator = $definitionLocator;
         $this->workspace = $workspace;
         $this->locationConverter = $locationConverter;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     public function methods(): array
diff --git a/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php b/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
index 5ca4fb90..1a2c7ee7 100644
--- a/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerReferenceFinder\Handler;
 
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\ImplementationParams;
@@ -14,7 +15,7 @@
 use Phpactor\ReferenceFinder\ClassImplementationFinder;
 use Phpactor\TextDocument\TextDocumentBuilder;
 
-class GotoImplementationHandler implements Handler, CanRegisterCapabilities
+class GotoImplementationHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var Workspace
@@ -31,11 +32,6 @@ class GotoImplementationHandler implements Handler, CanRegisterCapabilities
      */
     private $locationConverter;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(
         Workspace $workspace,
         ClassImplementationFinder $finder,
@@ -46,7 +42,7 @@ public function __construct(
         $this->workspace = $workspace;
         $this->finder = $finder;
         $this->locationConverter = $locationConverter;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     /**
diff --git a/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php b/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php
index 4467500f..f7d088fe 100644
--- a/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/HighlightHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Amp\Success;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\Extension\LanguageServerReferenceFinder\Model\Highlighter;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
@@ -16,7 +17,7 @@
 use Phpactor\LanguageServer\Core\Handler\Handler;
 use Phpactor\LanguageServer\Core\Workspace\Workspace;
 
-class HighlightHandler implements Handler, CanRegisterCapabilities
+class HighlightHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var Workspace
@@ -28,16 +29,11 @@ class HighlightHandler implements Handler, CanRegisterCapabilities
      */
     private $highlighter;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(Workspace $workspace, Highlighter $highlighter, ClientCapabilities $clientCapabilities)
     {
         $this->workspace = $workspace;
         $this->highlighter = $highlighter;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     /**
diff --git a/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php b/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php
index e7e19cb5..44cf12c2 100644
--- a/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/ReferencesHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Delayed;
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Location as LspLocation;
@@ -24,7 +25,7 @@
 use Phpactor\TextDocument\Locations;
 use Phpactor\TextDocument\TextDocumentBuilder;
 
-class ReferencesHandler implements Handler, CanRegisterCapabilities
+class ReferencesHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var Workspace
@@ -56,11 +57,6 @@ class ReferencesHandler implements Handler, CanRegisterCapabilities
      */
     private $clientApi;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(
         Workspace $workspace,
         ReferenceFinder $finder,
@@ -76,7 +72,7 @@ public function __construct(
         $this->timeoutSeconds = $timeoutSeconds;
         $this->locationConverter = $locationConverter;
         $this->clientApi = $clientApi;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     /**
diff --git a/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php b/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
index f189e418..530735ff 100644
--- a/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerReferenceFinder\Handler;
 
 use Amp\Promise;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerBridge\Converter\PositionConverter;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Position;
@@ -16,7 +17,7 @@
 use Phpactor\ReferenceFinder\TypeLocator;
 use Phpactor\TextDocument\TextDocumentBuilder;
 
-class TypeDefinitionHandler implements Handler, CanRegisterCapabilities
+class TypeDefinitionHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var TypeLocator
@@ -33,11 +34,6 @@ class TypeDefinitionHandler implements Handler, CanRegisterCapabilities
      */
     private $locationConverter;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(
         Workspace $workspace,
         TypeLocator $typeLocator,
@@ -48,7 +44,7 @@ public function __construct(
         $this->typeLocator = $typeLocator;
         $this->workspace = $workspace;
         $this->locationConverter = $locationConverter;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     public function methods(): array
diff --git a/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php b/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
index e7bd8311..1d9ec78e 100644
--- a/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
+++ b/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
@@ -4,6 +4,7 @@
 
 use Amp\Promise;
 use Amp\Success;
+use Phpactor\Extension\AbstractHandler;
 use Phpactor\Extension\LanguageServerSymbolProvider\Model\DocumentSymbolProvider;
 use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\DocumentSymbolOptions;
@@ -14,7 +15,7 @@
 use Phpactor\LanguageServer\Core\Handler\Handler;
 use Phpactor\LanguageServer\Core\Workspace\Workspace;
 
-class DocumentSymbolProviderHandler implements Handler, CanRegisterCapabilities
+class DocumentSymbolProviderHandler extends AbstractHandler implements Handler, CanRegisterCapabilities
 {
     /**
      * @var Workspace
@@ -26,11 +27,6 @@ class DocumentSymbolProviderHandler implements Handler, CanRegisterCapabilities
      */
     private $provider;
 
-    /**
-     * @var ClientCapabilities
-     */
-    private ClientCapabilities $clientCapabilities;
-
     public function __construct(
         Workspace $workspace,
         DocumentSymbolProvider $provider,
@@ -38,7 +34,7 @@ public function __construct(
     ) {
         $this->workspace = $workspace;
         $this->provider = $provider;
-        $this->clientCapabilities = $clientCapabilities;
+        parent::__construct($clientCapabilities);
     }
 
     /**

From 1ce025f33aeaf4bf5a34cb0d2e90962f76be3922 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:10:15 +0100
Subject: [PATCH 10/18] Fix unit tests

---
 .../Unit/Handler/GotoDefinitionHandlerTest.php               | 4 +++-
 .../Unit/Handler/GotoImplementationHandlerTest.php           | 4 +++-
 .../Unit/Handler/ReferencesHandlerTest.php                   | 5 ++++-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/tests/LanguageServerReferenceFinder/Unit/Handler/GotoDefinitionHandlerTest.php b/tests/LanguageServerReferenceFinder/Unit/Handler/GotoDefinitionHandlerTest.php
index fd3b7d47..ce2b2942 100644
--- a/tests/LanguageServerReferenceFinder/Unit/Handler/GotoDefinitionHandlerTest.php
+++ b/tests/LanguageServerReferenceFinder/Unit/Handler/GotoDefinitionHandlerTest.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerReferenceFinder\Tests\Unit\Handler;
 
 use Phpactor\Extension\LanguageServerBridge\TextDocument\WorkspaceTextDocumentLocator;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\DefinitionRequest;
 use Phpactor\LanguageServerProtocol\Location;
 use Phpactor\Extension\LanguageServerBridge\Converter\LocationConverter;
@@ -30,7 +31,8 @@ public function testGoesToDefinition(): void
             TestDefinitionLocator::fromLocation(
                 new DefinitionLocation($document->uri(), ByteOffset::fromInt(2))
             ),
-            new LocationConverter(new WorkspaceTextDocumentLocator($builder->workspace()))
+            new LocationConverter(new WorkspaceTextDocumentLocator($builder->workspace())),
+            ClientCapabilities::fromArray(['textDocument' => ['definition' => []]])
         ))->build();
         $tester->textDocument()->open(self::EXAMPLE_URI, self::EXAMPLE_TEXT);
 
diff --git a/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php b/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php
index 117a7dfd..abb05bff 100644
--- a/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php
+++ b/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerReferenceFinder\Tests\Unit\Handler;
 
 use Phpactor\Extension\LanguageServerBridge\TextDocument\WorkspaceTextDocumentLocator;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Location as LspLocation;
 use Phpactor\Extension\LanguageServerBridge\Converter\LocationConverter;
 use Phpactor\Extension\LanguageServerReferenceFinder\Handler\GotoImplementationHandler;
@@ -50,7 +51,8 @@ public function testGoesToImplementation(): void
         $tester = $builder->addHandler(new GotoImplementationHandler(
             $builder->workspace(),
             $this->finder->reveal(),
-            new LocationConverter(new WorkspaceTextDocumentLocator($builder->workspace()))
+            new LocationConverter(new WorkspaceTextDocumentLocator($builder->workspace())),
+            ClientCapabilities::fromArray(['textDocument' => ['definition' => []]])
         ))->build();
         $tester->textDocument()->open(self::EXAMPLE_URI, self::EXAMPLE_TEXT);
 
diff --git a/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php b/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php
index a02b289c..0196a016 100644
--- a/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php
+++ b/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php
@@ -3,6 +3,7 @@
 namespace Phpactor\Extension\LanguageServerReferenceFinder\Tests\Unit\Handler;
 
 use Phpactor\Extension\LanguageServerBridge\TextDocument\WorkspaceTextDocumentLocator;
+use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServerProtocol\Location as LspLocation;
 use Phpactor\LanguageServerProtocol\Position;
 use Phpactor\LanguageServerProtocol\Range;
@@ -172,7 +173,9 @@ private function createTester(): LanguageServerTester
                 $this->finder->reveal(),
                 $this->locator->reveal(),
                 new LocationConverter(new WorkspaceTextDocumentLocator($builder->workspace())),
-                new ClientApi(TestRpcClient::create())
+                new ClientApi(TestRpcClient::create()),
+                5.0,
+                ClientCapabilities::fromArray(['textDocument' => ['definition' => []]])
             )
         );
         $tester = $builder->build();

From d79cb93a5e4ce03cd7a11263dc5b462c7de3688e Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:12:26 +0100
Subject: [PATCH 11/18] fixup! Fix unit tests

---
 .../Unit/Handler/GotoImplementationHandlerTest.php              | 2 +-
 .../Unit/Handler/ReferencesHandlerTest.php                      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php b/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php
index abb05bff..fea408df 100644
--- a/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php
+++ b/tests/LanguageServerReferenceFinder/Unit/Handler/GotoImplementationHandlerTest.php
@@ -52,7 +52,7 @@ public function testGoesToImplementation(): void
             $builder->workspace(),
             $this->finder->reveal(),
             new LocationConverter(new WorkspaceTextDocumentLocator($builder->workspace())),
-            ClientCapabilities::fromArray(['textDocument' => ['definition' => []]])
+            ClientCapabilities::fromArray(['textDocument' => ['implementation' => []]])
         ))->build();
         $tester->textDocument()->open(self::EXAMPLE_URI, self::EXAMPLE_TEXT);
 
diff --git a/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php b/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php
index 0196a016..8fc641bc 100644
--- a/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php
+++ b/tests/LanguageServerReferenceFinder/Unit/Handler/ReferencesHandlerTest.php
@@ -175,7 +175,7 @@ private function createTester(): LanguageServerTester
                 new LocationConverter(new WorkspaceTextDocumentLocator($builder->workspace())),
                 new ClientApi(TestRpcClient::create()),
                 5.0,
-                ClientCapabilities::fromArray(['textDocument' => ['definition' => []]])
+                ClientCapabilities::fromArray(['textDocument' => ['references' => []]])
             )
         );
         $tester = $builder->build();

From 937fdfe1a30140cb485996e787a8836772d0c649 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:16:25 +0100
Subject: [PATCH 12/18] Remove trailig comma

---
 .../Unit/Handler/CompletionHandlerTest.php                      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
index 4ed7e874..d9331255 100644
--- a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
+++ b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
@@ -431,7 +431,7 @@ private function create(
 
     private function createClientCapabilities(
         bool $completion = true,
-        bool $supportSnippets = true,
+        bool $supportSnippets = true
     ): ClientCapabilities {
         $capabilities = new ClientCapabilities();
         $capabilities->textDocument = new TextDocumentClientCapabilities();

From 8e2f6ef658a7ed3767199157ea652636c3024f77 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:19:39 +0100
Subject: [PATCH 13/18] fixup! Remove trailig comma

---
 .../Handler/DocumentSymbolProviderHandler.php                   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php b/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
index 1d9ec78e..9ec156de 100644
--- a/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
+++ b/lib/LanguageServerSymbolProvider/Handler/DocumentSymbolProviderHandler.php
@@ -30,7 +30,7 @@ class DocumentSymbolProviderHandler extends AbstractHandler implements Handler,
     public function __construct(
         Workspace $workspace,
         DocumentSymbolProvider $provider,
-        ClientCapabilities $clientCapabilities,
+        ClientCapabilities $clientCapabilities
     ) {
         $this->workspace = $workspace;
         $this->provider = $provider;

From 5f7fdcbeb06b38877ca45ef1460bf4763d18daf8 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:23:13 +0100
Subject: [PATCH 14/18] Remove unused imports

---
 .../LanguageServerCompletionExtension.php                        | 1 -
 lib/LanguageServerHover/LanguageServerHoverExtension.php         | 1 -
 .../LanguageServerReferenceFinderExtension.php                   | 1 -
 .../LanguageServerSymbolProviderExtension.php                    | 1 -
 4 files changed, 4 deletions(-)

diff --git a/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php b/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
index ce90de42..5e2f7183 100644
--- a/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
+++ b/lib/LanguageServerCompletion/LanguageServerCompletionExtension.php
@@ -12,7 +12,6 @@
 use Phpactor\Extension\LanguageServerCompletion\Util\SuggestionNameFormatter;
 use Phpactor\Extension\LanguageServer\LanguageServerExtension;
 use Phpactor\Extension\LanguageServerCompletion\Handler\CompletionHandler;
-use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\MapResolver\Resolver;
 
 class LanguageServerCompletionExtension extends AbstractExtension implements Extension
diff --git a/lib/LanguageServerHover/LanguageServerHoverExtension.php b/lib/LanguageServerHover/LanguageServerHoverExtension.php
index 7abf735e..19d0df30 100644
--- a/lib/LanguageServerHover/LanguageServerHoverExtension.php
+++ b/lib/LanguageServerHover/LanguageServerHoverExtension.php
@@ -10,7 +10,6 @@
 use Phpactor\Extension\Php\Model\PhpVersionResolver;
 use Phpactor\Extension\WorseReflection\WorseReflectionExtension;
 use Phpactor\FilePathResolverExtension\FilePathResolverExtension;
-use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\ObjectRenderer\ObjectRendererBuilder;
 use Phpactor\Extension\LanguageServer\LanguageServerExtension;
 use Phpactor\Extension\LanguageServerHover\Handler\HoverHandler;
diff --git a/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php b/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
index 0e8f89a3..a5d447a9 100644
--- a/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
+++ b/lib/LanguageServerReferenceFinder/LanguageServerReferenceFinderExtension.php
@@ -18,7 +18,6 @@
 use Phpactor\Extension\LanguageServer\LanguageServerExtension;
 use Phpactor\Extension\ReferenceFinder\ReferenceFinderExtension;
 use Phpactor\Indexer\Model\Indexer;
-use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\LanguageServer\Core\Server\ClientApi;
 use Phpactor\MapResolver\Resolver;
 use Phpactor\ReferenceFinder\ReferenceFinder;
diff --git a/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php b/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
index 34a7118e..e6d357f8 100644
--- a/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
+++ b/lib/LanguageServerSymbolProvider/LanguageServerSymbolProviderExtension.php
@@ -11,7 +11,6 @@
 use Phpactor\Extension\LanguageServerSymbolProvider\Handler\DocumentSymbolProviderHandler;
 use Phpactor\Extension\LanguageServerSymbolProvider\Model\DocumentSymbolProvider;
 use Phpactor\Extension\LanguageServer\LanguageServerExtension;
-use Phpactor\LanguageServerProtocol\ClientCapabilities;
 use Phpactor\MapResolver\Resolver;
 
 class LanguageServerSymbolProviderExtension extends AbstractExtension implements Extension

From a63393764e3335e7430287199fbc3c37a3c8977b Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:25:24 +0100
Subject: [PATCH 15/18] PSR

---
 .../Handler/GotoImplementationHandler.php                      | 3 +--
 .../Handler/TypeDefinitionHandler.php                          | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php b/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
index 1a2c7ee7..40ee8d87 100644
--- a/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/GotoImplementationHandler.php
@@ -37,8 +37,7 @@ public function __construct(
         ClassImplementationFinder $finder,
         LocationConverter $locationConverter,
         ClientCapabilities $clientCapabilities
-    )
-    {
+    ) {
         $this->workspace = $workspace;
         $this->finder = $finder;
         $this->locationConverter = $locationConverter;
diff --git a/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php b/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
index 530735ff..e6e353b5 100644
--- a/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
+++ b/lib/LanguageServerReferenceFinder/Handler/TypeDefinitionHandler.php
@@ -39,8 +39,7 @@ public function __construct(
         TypeLocator $typeLocator,
         LocationConverter $locationConverter,
         ClientCapabilities $clientCapabilities
-    )
-    {
+    ) {
         $this->typeLocator = $typeLocator;
         $this->workspace = $workspace;
         $this->locationConverter = $locationConverter;

From e8433f6a6ca5bfedd649dd255ecd2fb3b1fc6632 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:36:41 +0100
Subject: [PATCH 16/18] Do not override setting signatureHelpProvider in
 CompletionHandler

---
 lib/LanguageServerCompletion/Handler/CompletionHandler.php | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/lib/LanguageServerCompletion/Handler/CompletionHandler.php b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
index 74b9bb21..9c5b5ccf 100644
--- a/lib/LanguageServerCompletion/Handler/CompletionHandler.php
+++ b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
@@ -142,9 +142,6 @@ public function registerCapabiltiies(ServerCapabilities $capabilities): void
         $capabilities->completionProvider = (null !== $this->clientCapabilities->textDocument->completion)
             ? new CompletionOptions([':', '>', '$'])
             : null;
-        $capabilities->signatureHelpProvider = (null !== $this->clientCapabilities->textDocument->signatureHelp)
-            ? new SignatureHelpOptions(['(', ','])
-            : null;
     }
 
     private function determineInsertTextAndFormat(

From 479e4fa555b1703be742b50e49cc9b8dd44911f0 Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 21:39:51 +0100
Subject: [PATCH 17/18] Remove unused import

---
 lib/LanguageServerCompletion/Handler/CompletionHandler.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/LanguageServerCompletion/Handler/CompletionHandler.php b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
index 9c5b5ccf..064fb8cf 100644
--- a/lib/LanguageServerCompletion/Handler/CompletionHandler.php
+++ b/lib/LanguageServerCompletion/Handler/CompletionHandler.php
@@ -18,7 +18,6 @@
 use Phpactor\LanguageServerProtocol\InsertTextFormat;
 use Phpactor\LanguageServerProtocol\Range;
 use Phpactor\LanguageServerProtocol\ServerCapabilities;
-use Phpactor\LanguageServerProtocol\SignatureHelpOptions;
 use Phpactor\LanguageServerProtocol\TextDocumentItem;
 use Phpactor\LanguageServerProtocol\TextEdit;
 use Phpactor\Completion\Core\Suggestion;

From da4abe5d0d9cb496d3d3b751a9c7d2d4ae8c85aa Mon Sep 17 00:00:00 2001
From: przepompownia <przepompownia@users.noreply.github.com>
Date: Sun, 23 Jan 2022 22:16:19 +0100
Subject: [PATCH 18/18] Add tests for CompletionHandler

---
 .../Unit/Handler/CompletionHandlerTest.php    | 80 +++++++++++++------
 1 file changed, 55 insertions(+), 25 deletions(-)

diff --git a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
index d9331255..82b23954 100644
--- a/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
+++ b/tests/LanguageServerCompletion/Unit/Handler/CompletionHandlerTest.php
@@ -12,8 +12,10 @@
 use Phpactor\LanguageServerProtocol\CompletionClientCapabilities;
 use Phpactor\LanguageServerProtocol\CompletionItem;
 use Phpactor\LanguageServerProtocol\CompletionList;
+use Phpactor\LanguageServerProtocol\CompletionOptions;
 use Phpactor\LanguageServerProtocol\Position;
 use Phpactor\LanguageServerProtocol\Range;
+use Phpactor\LanguageServerProtocol\ServerCapabilities;
 use Phpactor\LanguageServerProtocol\TextDocumentClientCapabilities;
 use Phpactor\LanguageServerProtocol\TextEdit;
 use PHPUnit\Framework\TestCase;
@@ -49,32 +51,40 @@ public function testHandleNoSuggestions(): void
         $this->assertFalse($response->result->isIncomplete);
     }
 
-    public function testHandleWithDisabledCapability(): void
+    public function testDisbledCompletion(): void
     {
-        $tester = $this->create(
-            [
-                Suggestion::create('hello'),
-                Suggestion::create('goodbye'),
-            ],
-            true,
+        $handler = $this->createHandler(
+            LanguageServerTesterBuilder::create(),
+            [],
+            false,
             false,
             [],
             [],
             false
         );
-        $response = $tester->requestAndWait(
-            'textDocument/completion',
-            [
-                'textDocument' => ProtocolFactory::textDocumentIdentifier(self::EXAMPLE_URI),
-                'position' => ProtocolFactory::position(0, 0)
-            ]
+
+        $serverCapabilities = new ServerCapabilities();
+        $handler->registerCapabiltiies($serverCapabilities);
+
+        $this->assertNull($serverCapabilities->completionProvider);
+    }
+
+    public function testEnabledCompletion(): void
+    {
+        $handler = $this->createHandler(
+            LanguageServerTesterBuilder::create(),
+            [],
+            false,
+            false,
+            [],
+            [],
+            true
         );
-        $this->assertInstanceOf(CompletionList::class, $response->result);
-        $this->assertEquals([
-            self::completionItem('hello', null),
-            self::completionItem('goodbye', null),
-        ], $response->result->items);
-        $this->assertFalse($response->result->isIncomplete);
+
+        $serverCapabilities = new ServerCapabilities();
+        $handler->registerCapabiltiies($serverCapabilities);
+
+        $this->assertInstanceOf(CompletionOptions::class, $serverCapabilities->completionProvider);
     }
 
     public function testHandleACompleteListOfSuggestions(): void
@@ -411,22 +421,42 @@ private function create(
         array $aliases = [],
         bool $supportCompletion = true
     ): LanguageServerTester {
+        $builder = LanguageServerTesterBuilder::create();
+        $tester = $builder->addHandler($this->createHandler(
+            $builder,
+            $suggestions,
+            $supportSnippets,
+            $isIncomplete,
+            $importNameTextEdits,
+            $aliases,
+            $supportCompletion
+        ))->build();
+        $tester->textDocument()->open(self::EXAMPLE_URI, self::EXAMPLE_TEXT);
+
+        return $tester;
+    }
+
+    private function createHandler(
+        LanguageServerTesterBuilder $builder,
+        array $suggestions,
+        bool $supportSnippets = true,
+        bool $isIncomplete = false,
+        array $importNameTextEdits = [],
+        array $aliases = [],
+        bool $supportCompletion = true
+    ): CompletionHandler {
         $completor = $this->createCompletor($suggestions, $isIncomplete);
         $registry = new TypedCompletorRegistry([
             'php' => $completor,
         ]);
-        $builder = LanguageServerTesterBuilder::create();
-        $tester = $builder->addHandler(new CompletionHandler(
+        return new CompletionHandler(
             $builder->workspace(),
             $registry,
             new SuggestionNameFormatter(true),
             $this->createNameImporter($suggestions, $aliases, $importNameTextEdits),
             $this->createClientCapabilities($supportCompletion, $supportSnippets),
             true
-        ))->build();
-        $tester->textDocument()->open(self::EXAMPLE_URI, self::EXAMPLE_TEXT);
-
-        return $tester;
+        );
     }
 
     private function createClientCapabilities(