1
- import process , { allowedNodeEnvironmentFlags } from "process" ;
1
+ import process from "process" ;
2
2
import * as p from "vscode-languageserver-protocol" ;
3
3
import * as t from "vscode-languageserver-types" ;
4
4
import * as j from "vscode-jsonrpc" ;
5
5
import * as m from "vscode-jsonrpc/lib/messages" ;
6
6
import * as v from "vscode-languageserver" ;
7
7
import * as path from 'path' ;
8
8
import fs from 'fs' ;
9
- // TODO: check DidChangeWatchedFilesNotification. Check DidChangeTextDocumentNotification. Do they fire on uninitialized files?
9
+ // TODO: check DidChangeWatchedFilesNotification.
10
10
import { DidOpenTextDocumentNotification , DidChangeTextDocumentNotification , DidCloseTextDocumentNotification , DidChangeWatchedFilesNotification , CompletionResolveRequest } from 'vscode-languageserver-protocol' ;
11
11
import * as utils from './utils' ;
12
12
import * as c from './constants' ;
13
13
import * as chokidar from 'chokidar'
14
14
import { assert } from 'console' ;
15
- // TODO: what's this?
16
15
import { fileURLToPath } from 'url' ;
17
16
18
17
// https://microsoft.github.io/language-server-protocol/specification#initialize
@@ -106,7 +105,7 @@ let openedFile = (fileUri: string, fileContent: string) => {
106
105
107
106
stupidFileContentCache . set ( filePath , fileContent )
108
107
109
- let projectRootPath = utils . findDirOfFileNearFile ( c . bsconfigPartialPath , filePath )
108
+ let projectRootPath = utils . findProjectRootOfFile ( filePath )
110
109
if ( projectRootPath != null ) {
111
110
if ( ! projectsFiles . has ( projectRootPath ) ) {
112
111
projectsFiles . set ( projectRootPath , { openFiles : new Set ( ) , filesWithDiagnostics : new Set ( ) } )
@@ -123,7 +122,7 @@ let closedFile = (fileUri: string) => {
123
122
124
123
stupidFileContentCache . delete ( filePath )
125
124
126
- let projectRootPath = utils . findDirOfFileNearFile ( c . bsconfigPartialPath , filePath )
125
+ let projectRootPath = utils . findProjectRootOfFile ( filePath )
127
126
if ( projectRootPath != null ) {
128
127
let root = projectsFiles . get ( projectRootPath )
129
128
if ( root != null ) {
@@ -155,7 +154,6 @@ process.on('message', (a: (m.RequestMessage | m.NotificationMessage)) => {
155
154
if ( ! initialized && aa . method !== 'exit' ) {
156
155
// From spec: "Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request"
157
156
// For us: do nothing. We don't have anything we need to clean up right now
158
- // TODO: think of fs watcher
159
157
} else if ( aa . method === 'exit' ) {
160
158
// The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1
161
159
if ( shutdownRequestAlreadyReceived ) {
@@ -200,7 +198,6 @@ process.on('message', (a: (m.RequestMessage | m.NotificationMessage)) => {
200
198
} ;
201
199
process . send ! ( response ) ;
202
200
} else if ( aa . method === 'initialize' ) {
203
- // startWatchingCompilerLog(process)
204
201
// send the list of things we support
205
202
let result : p . InitializeResult = {
206
203
capabilities : {
@@ -263,58 +260,71 @@ process.on('message', (a: (m.RequestMessage | m.NotificationMessage)) => {
263
260
} ;
264
261
process . send ! ( response ) ;
265
262
} else {
266
- let nodeModulesParentPath = utils . findDirOfFileNearFile ( c . bscPartialPath , filePath )
267
- if ( nodeModulesParentPath == null ) {
263
+ let projectRootPath = utils . findProjectRootOfFile ( filePath )
264
+ if ( projectRootPath == null ) {
268
265
let response : m . ResponseMessage = {
269
266
jsonrpc : c . jsonrpcVersion ,
270
267
id : aa . id ,
271
268
error : {
272
269
code : m . ErrorCodes . InvalidRequest ,
273
- message : `Cannot find a nearby ${ c . bscPartialPath } . It's needed for formatting .` ,
270
+ message : `Cannot find a nearby ${ c . bsconfigPartialPath } . It's needed for determining the project's root .` ,
274
271
}
275
272
} ;
276
273
process . send ! ( response ) ;
277
274
} else {
278
- // code will always be defined here, even though technically it can be undefined
279
- let code = getOpenedFileContent ( params . textDocument . uri )
280
- let formattedResult = utils . formatUsingValidBscPath (
281
- code ,
282
- path . join ( nodeModulesParentPath , c . bscPartialPath ) ,
283
- extension === c . resiExt ,
284
- ) ;
285
- if ( formattedResult . kind === 'success' ) {
286
- let result : p . TextEdit [ ] = [ {
287
- range : {
288
- start : { line : 0 , character : 0 } ,
289
- end : { line : Number . MAX_VALUE , character : Number . MAX_VALUE }
290
- } ,
291
- newText : formattedResult . result ,
292
- } ]
275
+ let bscPath = path . join ( projectRootPath , c . bscPartialPath )
276
+ if ( ! fs . existsSync ( bscPath ) ) {
293
277
let response : m . ResponseMessage = {
294
278
jsonrpc : c . jsonrpcVersion ,
295
279
id : aa . id ,
296
- result : result ,
280
+ error : {
281
+ code : m . ErrorCodes . InvalidRequest ,
282
+ message : `Cannot find a nearby ${ c . bscPartialPath } . It's needed for formatting.` ,
283
+ }
297
284
} ;
298
285
process . send ! ( response ) ;
299
286
} else {
300
- let response : m . ResponseMessage = {
301
- jsonrpc : c . jsonrpcVersion ,
302
- id : aa . id ,
303
- result : [ ] ,
304
- // technically a formatting failure should return the error but
305
- // since this is LSP... the idiom seems to be to silently return
306
- // nothing (to avoid an alert window each time on bad formatting)
307
- // while sending a diagnostic about the error afterward. We won't
308
- // send an extra diagnostic because the .compiler.log watcher
309
- // should have reported th won't send an extra diagnostic because
310
- // theiler.log watcher should have reported them.
287
+ // code will always be defined here, even though technically it can be undefined
288
+ let code = getOpenedFileContent ( params . textDocument . uri )
289
+ let formattedResult = utils . formatUsingValidBscPath (
290
+ code ,
291
+ bscPath ,
292
+ extension === c . resiExt ,
293
+ ) ;
294
+ if ( formattedResult . kind === 'success' ) {
295
+ let result : p . TextEdit [ ] = [ {
296
+ range : {
297
+ start : { line : 0 , character : 0 } ,
298
+ end : { line : Number . MAX_VALUE , character : Number . MAX_VALUE }
299
+ } ,
300
+ newText : formattedResult . result ,
301
+ } ]
302
+ let response : m . ResponseMessage = {
303
+ jsonrpc : c . jsonrpcVersion ,
304
+ id : aa . id ,
305
+ result : result ,
306
+ } ;
307
+ process . send ! ( response ) ;
308
+ } else {
309
+ let response : m . ResponseMessage = {
310
+ jsonrpc : c . jsonrpcVersion ,
311
+ id : aa . id ,
312
+ result : [ ] ,
313
+ // technically a formatting failure should return the error but
314
+ // since this is LSP... the idiom seems to be to silently return
315
+ // nothing (to avoid an alert window each time on bad formatting)
316
+ // while sending a diagnostic about the error afterward. We won't
317
+ // send an extra diagnostic because the .compiler.log watcher
318
+ // should have reported th won't send an extra diagnostic because
319
+ // theiler.log watcher should have reported them.
311
320
312
- // error: {
313
- // code: m.ErrorCodes.ParseError,
314
- // message: formattedResult.error,
315
- // }
316
- } ;
317
- process . send ! ( response ) ;
321
+ // error: {
322
+ // code: m.ErrorCodes.ParseError,
323
+ // message: formattedResult.error,
324
+ // }
325
+ } ;
326
+ process . send ! ( response ) ;
327
+ }
318
328
}
319
329
}
320
330
}
0 commit comments