Skip to content
This repository was archived by the owner on Feb 22, 2020. It is now read-only.

Commit 9b7accd

Browse files
committed
fix: pass right URIs from withConnection()
1 parent fc21e48 commit 9b7accd

File tree

4 files changed

+64
-34
lines changed

4 files changed

+64
-34
lines changed

src/connection.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
WebSocketMessageReader,
88
WebSocketMessageWriter,
99
} from '@sourcegraph/vscode-ws-jsonrpc'
10+
import { attempt } from 'lodash'
1011
import { fromEvent, merge, Subject } from 'rxjs'
1112
import { filter, map, mapTo, take } from 'rxjs/operators'
1213
import { Subscribable, Unsubscribable } from 'sourcegraph'
@@ -70,8 +71,8 @@ export const webSocketTransport = ({
7071
map(({ params }) => params)
7172
),
7273
unsubscribe: () => {
73-
socket.close()
74-
connection.dispose()
74+
attempt(() => socket.close())
75+
attempt(() => connection.dispose())
7576
},
7677
}
7778
}

src/features/feature.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,19 @@ export type RegistrationOptions<T extends RequestType<any, any, any, any>> = Exc
2323

2424
export function scopeDocumentSelectorToRoot(
2525
documentSelector: DocumentSelector | null,
26-
rootUri: URL | null
26+
clientRootUri: URL | null
2727
): DocumentSelector {
2828
if (!documentSelector || documentSelector.length === 0) {
2929
documentSelector = [{ pattern: '**' }]
3030
}
31-
if (!rootUri) {
31+
if (!clientRootUri) {
3232
return documentSelector
3333
}
3434
return documentSelector
3535
.map((filter): DocumentFilter => (typeof filter === 'string' ? { language: filter } : filter))
3636
.map(filter => ({
3737
...filter,
38-
pattern: new URL(filter.pattern || '**', rootUri).href,
38+
// TODO filter.pattern needs to be run resolved relative to server root URI before mounting on clientRootUri
39+
pattern: new URL(filter.pattern || '**', clientRootUri).href,
3940
}))
4041
}

src/index.ts

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export interface LSPClient extends Unsubscribable {
6060
* Ensures a connection with the given workspace root, passes it to the given function.
6161
* If the workspace is not currently open in Sourcegraph, the connection is closed again after the Promise returned by the function resolved.
6262
*
63-
* @param workspaceRoot The workspace folder root URI that will be ensured to be open before calling the function.
63+
* @param workspaceRoot The client workspace folder root URI that will be ensured to be open before calling the function.
6464
* @param fn Callback that is called with the connection.
6565
*/
6666
withConnection<R>(workspaceRoot: URL, fn: (connection: LSPConnection) => Promise<R>): Promise<R>
@@ -128,7 +128,7 @@ export async function register({
128128

129129
const registrationSubscriptions = new Map<string, Unsubscribable>()
130130
/**
131-
* @param scopeRootUri A workspace folder root URI to scope the providers to. If `null`, the provider is registered for all workspace folders.
131+
* @param scopeRootUri A client workspace folder root URI to scope the providers to. If `null`, the provider is registered for all workspace folders.
132132
*/
133133
function registerCapabilities(
134134
connection: LSPConnection,
@@ -153,7 +153,7 @@ export async function register({
153153
}
154154
}
155155

156-
async function connect(): Promise<LSPConnection> {
156+
async function connect(clientRootUri: URL | null, initParams: InitializeParams): Promise<LSPConnection> {
157157
const subscriptions = new Subscription()
158158
const decorationType = sourcegraph.app.createDecorationType()
159159
const connection = await createConnection()
@@ -256,12 +256,13 @@ export async function register({
256256
}
257257
})
258258
)
259+
await initializeConnection(connection, clientRootUri, initParams)
259260
return connection
260261
}
261262

262263
async function initializeConnection(
263264
connection: LSPConnection,
264-
rootUri: URL | null,
265+
clientRootUri: URL | null,
265266
initParams: InitializeParams
266267
): Promise<void> {
267268
const initializeResult = await connection.sendRequest(InitializeRequest.type, initParams)
@@ -273,18 +274,26 @@ export async function register({
273274

274275
// Listen for dynamic capabilities
275276
connection.setRequestHandler(RegistrationRequest.type, params => {
276-
registerCapabilities(connection, rootUri, params.registrations)
277+
registerCapabilities(connection, clientRootUri, params.registrations)
277278
})
278279
// Register static capabilities
279-
registerCapabilities(connection, rootUri, staticRegistrations)
280+
registerCapabilities(connection, clientRootUri, staticRegistrations)
280281

281282
await afterInitialize(initializeResult)
282283
}
283284

284285
let withConnection: <R>(workspaceFolder: URL, fn: (connection: LSPConnection) => Promise<R>) => Promise<R>
285286

286287
if (supportsWorkspaceFolders) {
287-
const connection = await connect()
288+
const connection = await connect(
289+
null,
290+
{
291+
processId: null,
292+
rootUri: null,
293+
capabilities: clientCapabilities,
294+
workspaceFolders: sourcegraph.workspace.roots.map(toLSPWorkspaceFolder({ clientToServerURI })),
295+
}
296+
)
288297
subscriptions.add(connection)
289298
withConnection = async (workspaceFolder, fn) => {
290299
let tempWorkspaceFolder: WorkspaceFolder | undefined
@@ -310,12 +319,6 @@ export async function register({
310319
}
311320
}
312321
}
313-
await initializeConnection(connection, null, {
314-
processId: null,
315-
rootUri: null,
316-
capabilities: clientCapabilities,
317-
workspaceFolders: sourcegraph.workspace.roots.map(toLSPWorkspaceFolder),
318-
})
319322

320323
// Forward root changes
321324
subscriptions.add(
@@ -328,8 +331,12 @@ export async function register({
328331
after,
329332
})),
330333
map(({ before, after }) => ({
331-
added: differenceBy(after, before, root => root.uri.toString()).map(toLSPWorkspaceFolder),
332-
removed: differenceBy(before, after, root => root.uri.toString()).map(toLSPWorkspaceFolder),
334+
added: differenceBy(after, before, root => root.uri.toString()).map(
335+
toLSPWorkspaceFolder({ clientToServerURI })
336+
),
337+
removed: differenceBy(before, after, root => root.uri.toString()).map(
338+
toLSPWorkspaceFolder({ clientToServerURI })
339+
),
333340
}))
334341
)
335342
.subscribe(event => {
@@ -338,31 +345,47 @@ export async function register({
338345
)
339346
} else {
340347
// Supports only one workspace root
348+
// TODO this should store a refcount to avoid closing connections other consumers have a reference to
349+
/** Map from client root URI to connection */
341350
const connectionsByRootUri = new Map<string, Promise<LSPConnection>>()
342351
withConnection = async (workspaceFolder, fn) => {
343352
let connection = await connectionsByRootUri.get(workspaceFolder.href)
344-
if (!connection) {
345-
connection = await connect()
346-
subscriptions.add(connection)
353+
if (connection) {
354+
return await fn(connection)
347355
}
356+
const serverRootUri = clientToServerURI(workspaceFolder)
357+
connection = await connect(
358+
workspaceFolder,
359+
{
360+
processId: null,
361+
rootUri: serverRootUri.href,
362+
capabilities: clientCapabilities,
363+
workspaceFolders: null,
364+
}
365+
)
366+
subscriptions.add(connection)
348367
try {
349368
return await fn(connection)
350369
} finally {
370+
connectionsByRootUri.delete(workspaceFolder.href)
351371
connection.unsubscribe()
352372
}
353373
}
354374
function addRoots(added: ReadonlyArray<WorkspaceRoot>): void {
355375
for (const root of added) {
356376
const connectionPromise = (async () => {
357377
try {
358-
const connection = await connect()
378+
const serverRootUri = clientToServerURI(new URL(root.uri.toString()))
379+
const connection = await connect(
380+
new URL(root.uri.toString()),
381+
{
382+
processId: null,
383+
rootUri: serverRootUri.href,
384+
capabilities: clientCapabilities,
385+
workspaceFolders: null,
386+
}
387+
)
359388
subscriptions.add(connection)
360-
await initializeConnection(connection, new URL(root.uri.toString()), {
361-
processId: null,
362-
rootUri: root.uri.toString(),
363-
capabilities: clientCapabilities,
364-
workspaceFolders: null,
365-
})
366389
return connection
367390
} catch (err) {
368391
logger.error('Error creating connection', err)

src/lsp-conversion.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,15 @@ export const convertDiagnosticToDecoration = (
9494
range: convertRange(sourcegraph, diagnostic.range),
9595
})
9696

97-
export const toLSPWorkspaceFolder = (root: sourcegraph.WorkspaceRoot): WorkspaceFolder => ({
98-
uri: root.uri.toString(),
99-
name: new URL(root.uri.toString()).pathname.split('/').pop()!,
100-
})
97+
export const toLSPWorkspaceFolder = ({ clientToServerURI }: { clientToServerURI: (u: URL) => URL }) => (
98+
root: sourcegraph.WorkspaceRoot
99+
): WorkspaceFolder => {
100+
const serverUri = clientToServerURI(new URL(root.uri.toString()))
101+
return {
102+
uri: serverUri.href,
103+
name: new URL(serverUri.href).pathname.split('/').pop()!,
104+
}
105+
}
101106

102107
/**
103108
* Rewrites all `uri` properties in an object, recursively

0 commit comments

Comments
 (0)