clangd / vscode-clangd

Visual Studio Code extension for clangd
https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd
MIT License
629 stars 106 forks source link

Restarting clangd break the exported API #648

Closed sr-tream closed 3 months ago

sr-tream commented 3 months ago
  1. Write an extension what used the clangd API added in #575 (for example https://github.com/HighCommander4/vscode-clangd-api-example)
  2. Trigger extension activation (in provided example hover information for C/C++ symbol)
  3. Execute command clangd.restart
  4. Now extension from example have language client with State.Stopped state.

Getting new instance of API do not fix this issue, because clangd do not update exported language client instance

sr-tream commented 3 months ago

Possible fix:

diff --git a/src/api.ts b/src/api.ts
index dc1968b..d6f17ca 100644
--- a/src/api.ts
+++ b/src/api.ts
@@ -3,7 +3,7 @@ import {BaseLanguageClient} from 'vscode-languageclient';
 import {ClangdApiV1, ClangdExtension} from '../api/vscode-clangd';

 export class ClangdExtensionImpl implements ClangdExtension {
-  constructor(private readonly client: BaseLanguageClient) {}
+  constructor(public client: BaseLanguageClient) { }

   public getApi(version: 1): ClangdApiV1;
   public getApi(version: number): unknown {
diff --git a/src/extension.ts b/src/extension.ts
index c062fde..250038b 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -3,7 +3,9 @@ import * as vscode from 'vscode';
 import {ClangdExtension} from '../api/vscode-clangd';

 import {ClangdExtensionImpl} from './api';
-import {ClangdContext} from './clangd-context';
+import { ClangdContext } from './clangd-context';
+
+let apiInstance: ClangdExtensionImpl | undefined;

 /**
  *  This method is called when the extension is activated. The extension is
@@ -34,6 +36,9 @@ export async function activate(context: vscode.ExtensionContext):
         }
         await clangdContext.dispose();
         await clangdContext.activate(context.globalStoragePath, outputChannel);
+        if (apiInstance) {
+          apiInstance.client = clangdContext.client;
+        }
       }));

   await clangdContext.activate(context.globalStoragePath, outputChannel);
@@ -72,5 +77,6 @@ export async function activate(context: vscode.ExtensionContext):
     }, 5000);
   }

-  return new ClangdExtensionImpl(clangdContext.client);
+  apiInstance = new ClangdExtensionImpl(clangdContext.client);
+  return apiInstance;
 }

With this patch, extension can get new instance via ClangdExtension.getApi(1), when state of old language client changed to State.Stopped

HighCommander4 commented 3 months ago

Fixed by #649