1
1
import * as fs from 'fs' ;
2
+ import * as path from 'path' ;
2
3
import * as vscode from 'vscode' ;
3
4
import * as vscodelc from 'vscode-languageclient' ;
4
5
@@ -20,31 +21,36 @@ export class MLIRContext implements vscode.Disposable {
20
21
async activate ( outputChannel : vscode . OutputChannel ,
21
22
warnOnEmptyServerPath : boolean ) {
22
23
// Create the language clients for mlir and pdll.
23
- this . pdllClient = this . startLanguageClient (
24
+ let mlirServerPath : string , pdllServerPath : string ;
25
+ [ this . client , mlirServerPath ] = await this . startLanguageClient (
26
+ outputChannel , warnOnEmptyServerPath , 'server_path' , 'mlir' ) ;
27
+ [ this . pdllClient , pdllServerPath ] = await this . startLanguageClient (
24
28
outputChannel , warnOnEmptyServerPath , 'pdll_server_path' , 'pdll' ) ;
25
- this . client = this . startLanguageClient ( outputChannel , warnOnEmptyServerPath ,
26
- 'server_path' , 'mlir' ) ;
27
29
28
30
// Watch for configuration changes.
29
- configWatcher . activate ( this ) ;
31
+ const serverPathsToWatch = [ mlirServerPath , pdllServerPath ] ;
32
+ await configWatcher . activate ( this , serverPathsToWatch ) ;
30
33
}
31
34
32
35
/**
33
- * Start a new language client for the given language.
36
+ * Start a new language client for the given language. Returns an array
37
+ * containing the opened server, or null if the server could not be started,
38
+ * and the resolved server path.
34
39
*/
35
- startLanguageClient ( outputChannel : vscode . OutputChannel ,
36
- warnOnEmptyServerPath : boolean , serverSettingName : string ,
37
- languageName : string ) : vscodelc . LanguageClient {
40
+ async startLanguageClient ( outputChannel : vscode . OutputChannel ,
41
+ warnOnEmptyServerPath : boolean ,
42
+ serverSettingName : string , languageName : string ) :
43
+ Promise < [ vscodelc . LanguageClient , string ] > {
38
44
const clientTitle = languageName . toUpperCase ( ) + ' Language Client' ;
39
45
40
46
// Get the path of the lsp-server that is used to provide language
41
47
// functionality.
42
- const serverPath = config . get < string > ( serverSettingName ) ;
48
+ var serverPath = await this . resolveServerPath ( serverSettingName ) ;
43
49
44
50
// If we aren't emitting warnings on an empty server path, and the server
45
51
// path is empty, bail.
46
52
if ( ! warnOnEmptyServerPath && serverPath === '' ) {
47
- return null ;
53
+ return [ null , serverPath ] ;
48
54
}
49
55
50
56
// Check that the file actually exists.
@@ -61,7 +67,7 @@ export class MLIRContext implements vscode.Disposable {
61
67
{ openToSide : false , query : `mlir.${ serverSettingName } ` } ) ;
62
68
}
63
69
} ) ;
64
- return null ;
70
+ return [ null , serverPath ] ;
65
71
}
66
72
67
73
// Configure the server options.
@@ -94,7 +100,53 @@ export class MLIRContext implements vscode.Disposable {
94
100
let languageClient = new vscodelc . LanguageClient (
95
101
languageName + '-lsp' , clientTitle , serverOptions , clientOptions ) ;
96
102
this . subscriptions . push ( languageClient . start ( ) ) ;
97
- return languageClient ;
103
+ return [ languageClient , serverPath ] ;
104
+ }
105
+
106
+ /**
107
+ * Given a server setting, return the default server path.
108
+ */
109
+ static getDefaultServerFilename ( serverSettingName : string ) : string {
110
+ if ( serverSettingName === 'pdll_server_path' ) {
111
+ return 'mlir-pdll-lsp-server' ;
112
+ }
113
+ if ( serverSettingName === 'server_path' ) {
114
+ return 'mlir-lsp-server' ;
115
+ }
116
+ return '' ;
117
+ }
118
+
119
+ /**
120
+ * Try to resolve the path for the given server setting.
121
+ */
122
+ async resolveServerPath ( serverSettingName : string ) : Promise < string > {
123
+ let configServerPath = config . get < string > ( serverSettingName ) ;
124
+ let serverPath = configServerPath ;
125
+
126
+ // If the path is already fully resolved, there is nothing to do.
127
+ if ( path . isAbsolute ( serverPath ) ) {
128
+ return serverPath ;
129
+ }
130
+
131
+ // If a path hasn't been set, try to use the default path.
132
+ if ( serverPath === '' ) {
133
+ serverPath = MLIRContext . getDefaultServerFilename ( serverSettingName ) ;
134
+ if ( serverPath === '' ) {
135
+ return serverPath ;
136
+ }
137
+ // Fallthrough to try resolving the default path.
138
+ }
139
+
140
+ // Try to resolve the path relative to the workspace.
141
+ const foundUris : vscode . Uri [ ] =
142
+ await vscode . workspace . findFiles ( '**/' + serverPath , null , 1 ) ;
143
+ if ( foundUris . length === 0 ) {
144
+ // If we couldn't resolve it, just return the current configuration path
145
+ // anyways. The file might not exist yet.
146
+ return configServerPath ;
147
+ }
148
+ // Otherwise, return the resolved path.
149
+ return foundUris [ 0 ] . fsPath ;
98
150
}
99
151
100
152
dispose ( ) {
0 commit comments