1
1
import * as lc from "vscode-languageclient" ;
2
2
import * as vscode from "vscode" ;
3
+ import { promises as dns } from "dns" ;
3
4
import { strict as nativeAssert } from "assert" ;
4
5
5
6
export function assert ( condition : boolean , explanation : string ) : asserts condition {
@@ -11,21 +12,40 @@ export function assert(condition: boolean, explanation: string): asserts conditi
11
12
}
12
13
}
13
14
14
- export const log = {
15
- enabled : true ,
15
+ export const log = new class {
16
+ private enabled = true ;
17
+
18
+ setEnabled ( yes : boolean ) : void {
19
+ log . enabled = yes ;
20
+ }
21
+
16
22
debug ( message ?: any , ...optionalParams : any [ ] ) : void {
17
23
if ( ! log . enabled ) return ;
18
24
// eslint-disable-next-line no-console
19
25
console . log ( message , ...optionalParams ) ;
20
- } ,
26
+ }
27
+
21
28
error ( message ?: any , ...optionalParams : any [ ] ) : void {
22
29
if ( ! log . enabled ) return ;
23
30
debugger ;
24
31
// eslint-disable-next-line no-console
25
32
console . error ( message , ...optionalParams ) ;
26
- } ,
27
- setEnabled ( yes : boolean ) : void {
28
- log . enabled = yes ;
33
+ }
34
+
35
+ downloadError ( err : Error , artifactName : string , repoName : string ) {
36
+ vscode . window . showErrorMessage (
37
+ `Failed to download the rust-analyzer ${ artifactName } from ${ repoName } ` +
38
+ `GitHub repository: ${ err . message } `
39
+ ) ;
40
+ log . error ( err ) ;
41
+ dns . resolve ( 'example.com' ) . then (
42
+ addrs => log . debug ( "DNS resolution for example.com was successful" , addrs ) ,
43
+ err => log . error (
44
+ "DNS resolution for example.com failed, " +
45
+ "there might be an issue with Internet availability" ,
46
+ err
47
+ )
48
+ ) ;
29
49
}
30
50
} ;
31
51
@@ -66,6 +86,17 @@ function sleep(ms: number) {
66
86
return new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
67
87
}
68
88
89
+ export function notReentrant < TThis , TParams extends any [ ] , TRet > (
90
+ fn : ( this : TThis , ...params : TParams ) => Promise < TRet >
91
+ ) : typeof fn {
92
+ let entered = false ;
93
+ return function ( ...params ) {
94
+ assert ( ! entered , `Reentrancy invariant for ${ fn . name } is violated` ) ;
95
+ entered = true ;
96
+ return fn . apply ( this , params ) . finally ( ( ) => entered = false ) ;
97
+ } ;
98
+ }
99
+
69
100
export type RustDocument = vscode . TextDocument & { languageId : "rust" } ;
70
101
export type RustEditor = vscode . TextEditor & { document : RustDocument ; id : string } ;
71
102
@@ -79,3 +110,29 @@ export function isRustDocument(document: vscode.TextDocument): document is RustD
79
110
export function isRustEditor ( editor : vscode . TextEditor ) : editor is RustEditor {
80
111
return isRustDocument ( editor . document ) ;
81
112
}
113
+
114
+ /**
115
+ * @param extensionId The canonical extension identifier in the form of: `publisher.name`
116
+ */
117
+ export async function vscodeReinstallExtension ( extensionId : string ) {
118
+ // Unfortunately there is no straightforward way as of now, these commands
119
+ // were found in vscode source code.
120
+
121
+ log . debug ( "Uninstalling extension" , extensionId ) ;
122
+ await vscode . commands . executeCommand ( "workbench.extensions.uninstallExtension" , extensionId ) ;
123
+ log . debug ( "Installing extension" , extensionId ) ;
124
+ await vscode . commands . executeCommand ( "workbench.extensions.installExtension" , extensionId ) ;
125
+ }
126
+
127
+ export async function vscodeReloadWindow ( ) : Promise < never > {
128
+ await vscode . commands . executeCommand ( "workbench.action.reloadWindow" ) ;
129
+
130
+ assert ( false , "unreachable" ) ;
131
+ }
132
+
133
+ export async function vscodeInstallExtensionFromVsix ( vsixPath : string ) {
134
+ await vscode . commands . executeCommand (
135
+ "workbench.extensions.installExtension" ,
136
+ vscode . Uri . file ( vsixPath )
137
+ ) ;
138
+ }
0 commit comments