[Mlir-commits] [mlir] ade148d - [mlir-vscode] Add better resolution for server file paths

River Riddle llvmlistbot at llvm.org
Tue Apr 5 13:43:47 PDT 2022


Author: River Riddle
Date: 2022-04-05T13:41:40-07:00
New Revision: ade148d936be84aa5df451de30201bc4f84e607c

URL: https://github.com/llvm/llvm-project/commit/ade148d936be84aa5df451de30201bc4f84e607c
DIFF: https://github.com/llvm/llvm-project/commit/ade148d936be84aa5df451de30201bc4f84e607c.diff

LOG: [mlir-vscode] Add better resolution for server file paths

We currently require that server paths are full paths, which is
fairly inconvenient for a myriad of reasons. This commit
attempts to resolve a given server path with the current workspace.

This has a nice additional affect that we can now actually have
default server paths. This means that mlir-lsp-server and
mlir-pdll-lsp-server can be transparently picked up from
build directories (i.e. generally no need for upstream users to
configure the extension).

Fixes #54627

Differential Revision: https://reviews.llvm.org/D122792

Added: 
    

Modified: 
    mlir/utils/vscode/src/configWatcher.ts
    mlir/utils/vscode/src/mlirContext.ts

Removed: 
    


################################################################################
diff  --git a/mlir/utils/vscode/src/configWatcher.ts b/mlir/utils/vscode/src/configWatcher.ts
index 2725015e4cc94..a89391dca5879 100644
--- a/mlir/utils/vscode/src/configWatcher.ts
+++ b/mlir/utils/vscode/src/configWatcher.ts
@@ -1,5 +1,4 @@
 import * as chokidar from 'chokidar';
-import * as path from 'path';
 import * as vscode from 'vscode';
 
 import * as config from './config';
@@ -42,7 +41,8 @@ async function promptRestart(settingName: string, promptMessage: string) {
  *  Activate the watchers that track configuration changes which decide when to
  *  restart the server.
  */
-export function activate(mlirContext: MLIRContext) {
+export async function activate(mlirContext: MLIRContext,
+                               serverPathsToWatch: string[]) {
   // When a configuration change happens, check to see if we should restart the
   // server.
   mlirContext.subscriptions.push(vscode.workspace.onDidChangeConfiguration(event => {
@@ -61,10 +61,7 @@ export function activate(mlirContext: MLIRContext) {
 
   // Track the server file in case it changes. We use `fs` here because the
   // server may not be in a workspace directory.
-  const settings: string[] = [ 'server_path', 'pdll_server_path' ];
-  for (const setting of settings) {
-    const serverPath = config.get<string>(setting);
-
+  for (const serverPath of serverPathsToWatch) {
     // Check that the path actually exists.
     if (serverPath === '') {
       continue;

diff  --git a/mlir/utils/vscode/src/mlirContext.ts b/mlir/utils/vscode/src/mlirContext.ts
index d6db9a2390113..ea1d0a5496b8e 100644
--- a/mlir/utils/vscode/src/mlirContext.ts
+++ b/mlir/utils/vscode/src/mlirContext.ts
@@ -1,4 +1,5 @@
 import * as fs from 'fs';
+import * as path from 'path';
 import * as vscode from 'vscode';
 import * as vscodelc from 'vscode-languageclient';
 
@@ -20,31 +21,36 @@ export class MLIRContext implements vscode.Disposable {
   async activate(outputChannel: vscode.OutputChannel,
                  warnOnEmptyServerPath: boolean) {
     // Create the language clients for mlir and pdll.
-    this.pdllClient = this.startLanguageClient(
+    let mlirServerPath: string, pdllServerPath: string;
+    [this.client, mlirServerPath] = await this.startLanguageClient(
+        outputChannel, warnOnEmptyServerPath, 'server_path', 'mlir');
+    [this.pdllClient, pdllServerPath] = await this.startLanguageClient(
         outputChannel, warnOnEmptyServerPath, 'pdll_server_path', 'pdll');
-    this.client = this.startLanguageClient(outputChannel, warnOnEmptyServerPath,
-                                           'server_path', 'mlir');
 
     // Watch for configuration changes.
-    configWatcher.activate(this);
+    const serverPathsToWatch = [ mlirServerPath, pdllServerPath ];
+    await configWatcher.activate(this, serverPathsToWatch);
   }
 
   /**
-   *  Start a new language client for the given language.
+   *  Start a new language client for the given language. Returns an array
+   *  containing the opened server, or null if the server could not be started,
+   *  and the resolved server path.
    */
-  startLanguageClient(outputChannel: vscode.OutputChannel,
-                      warnOnEmptyServerPath: boolean, serverSettingName: string,
-                      languageName: string): vscodelc.LanguageClient {
+  async startLanguageClient(outputChannel: vscode.OutputChannel,
+                            warnOnEmptyServerPath: boolean,
+                            serverSettingName: string, languageName: string):
+      Promise<[ vscodelc.LanguageClient, string ]> {
     const clientTitle = languageName.toUpperCase() + ' Language Client';
 
     // Get the path of the lsp-server that is used to provide language
     // functionality.
-    const serverPath = config.get<string>(serverSettingName);
+    var serverPath = await this.resolveServerPath(serverSettingName);
 
     // If we aren't emitting warnings on an empty server path, and the server
     // path is empty, bail.
     if (!warnOnEmptyServerPath && serverPath === '') {
-      return null;
+      return [ null, serverPath ];
     }
 
     // Check that the file actually exists.
@@ -61,7 +67,7 @@ export class MLIRContext implements vscode.Disposable {
                   {openToSide : false, query : `mlir.${serverSettingName}`});
             }
           });
-      return null;
+      return [ null, serverPath ];
     }
 
     // Configure the server options.
@@ -94,7 +100,53 @@ export class MLIRContext implements vscode.Disposable {
     let languageClient = new vscodelc.LanguageClient(
         languageName + '-lsp', clientTitle, serverOptions, clientOptions);
     this.subscriptions.push(languageClient.start());
-    return languageClient;
+    return [ languageClient, serverPath ];
+  }
+
+  /**
+   * Given a server setting, return the default server path.
+   */
+  static getDefaultServerFilename(serverSettingName: string): string {
+    if (serverSettingName === 'pdll_server_path') {
+      return 'mlir-pdll-lsp-server';
+    }
+    if (serverSettingName === 'server_path') {
+      return 'mlir-lsp-server';
+    }
+    return '';
+  }
+
+  /**
+   * Try to resolve the path for the given server setting.
+   */
+  async resolveServerPath(serverSettingName: string): Promise<string> {
+    let configServerPath = config.get<string>(serverSettingName);
+    let serverPath = configServerPath;
+
+    // If the path is already fully resolved, there is nothing to do.
+    if (path.isAbsolute(serverPath)) {
+      return serverPath;
+    }
+
+    // If a path hasn't been set, try to use the default path.
+    if (serverPath === '') {
+      serverPath = MLIRContext.getDefaultServerFilename(serverSettingName);
+      if (serverPath === '') {
+        return serverPath;
+      }
+      // Fallthrough to try resolving the default path.
+    }
+
+    // Try to resolve the path relative to the workspace.
+    const foundUris: vscode.Uri[] =
+        await vscode.workspace.findFiles('**/' + serverPath, null, 1);
+    if (foundUris.length === 0) {
+      // If we couldn't resolve it, just return the current configuration path
+      // anyways. The file might not exist yet.
+      return configServerPath;
+    }
+    // Otherwise, return the resolved path.
+    return foundUris[0].fsPath;
   }
 
   dispose() {


        


More information about the Mlir-commits mailing list