Skip to content
This repository was archived by the owner on Nov 6, 2018. It is now read-only.

Commit 221679c

Browse files
committed
fix: provide backcompat for extensions written before the root removal
Also sends dynamic capabilities equivalent to the default static capabilities.
1 parent 322d416 commit 221679c

File tree

5 files changed

+64
-24
lines changed

5 files changed

+64
-24
lines changed

src/client/client.ts

+9
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,15 @@ export class Client implements Unsubscribable {
225225
connection.onRequest(RegistrationRequest.type, params => this.handleRegistrationRequest(params))
226226
connection.onRequest(UnregistrationRequest.type, params => this.handleUnregistrationRequest(params))
227227

228+
// Initialize static features.
229+
for (const feature of this.features) {
230+
if (!DynamicFeature.is(feature)) {
231+
if (feature.initialize) {
232+
feature.initialize()
233+
}
234+
}
235+
}
236+
228237
connection.sendNotification(InitializedNotification.type, {})
229238

230239
this._state.next(ClientState.Active)

src/client/features/common.test.ts

-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ class TextDocumentFeature extends AbstractTextDocumentFeature<TextDocumentRegist
2626
public fillClientCapabilities(): void {
2727
/* noop */
2828
}
29-
public initialize(): void {
30-
/* noop */
31-
}
3229
}
3330

3431
const FIXTURE_REGISTER_OPTIONS: TextDocumentRegistrationOptions = { documentSelector: ['*'], extensionID: 'test' }

src/client/features/decoration.ts

+17-18
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
1-
import { BehaviorSubject, Observable, Unsubscribable } from 'rxjs'
2-
import uuidv4 from 'uuid/v4'
1+
import { BehaviorSubject, Observable } from 'rxjs'
32
import { TextDocumentIdentifier } from 'vscode-languageserver-types'
43
import { ProvideTextDocumentDecorationSignature } from '../../environment/providers/decoration'
54
import { FeatureProviderRegistry } from '../../environment/providers/registry'
65
import { ClientCapabilities } from '../../protocol'
76
import { TextDocumentDecoration, TextDocumentPublishDecorationsNotification } from '../../protocol/decoration'
87
import { Client } from '../client'
9-
import { ensure, Feature } from './common'
8+
import { ensure, StaticFeature } from './common'
109

1110
/**
1211
* Support for text document decorations published by the server (textDocument/publishDecorations notifications
1312
* from the server).
1413
*/
15-
export class TextDocumentDecorationFeature extends Feature<undefined> {
14+
export class TextDocumentDecorationFeature implements StaticFeature {
1615
/** Map of document URI to its decorations (last published by the server). */
1716
private decorations = new Map<string, BehaviorSubject<TextDocumentDecoration[] | null>>()
1817

1918
constructor(
20-
client: Client,
19+
private client: Client,
2120
private registry: FeatureProviderRegistry<undefined, ProvideTextDocumentDecorationSignature>
2221
) {
23-
super(client)
24-
this.register(this.messages, { id: uuidv4(), registerOptions: undefined })
22+
this.registry.registerProvider(
23+
undefined,
24+
(textDocument: TextDocumentIdentifier): Observable<TextDocumentDecoration[] | null> =>
25+
this.getDecorationsSubject(textDocument)
26+
)
2527
}
2628

2729
public readonly messages = TextDocumentPublishDecorationsNotification.type
@@ -31,24 +33,21 @@ export class TextDocumentDecorationFeature extends Feature<undefined> {
3133
}
3234

3335
public initialize(): void {
36+
// TODO(sqs): no way to unregister this
3437
this.client.onNotification(TextDocumentPublishDecorationsNotification.type, params => {
3538
this.getDecorationsSubject(params.textDocument, params.decorations)
3639
})
3740
}
3841

39-
protected registerProvider(): Unsubscribable {
40-
return this.registry.registerProvider(
41-
undefined,
42-
(textDocument: TextDocumentIdentifier): Observable<TextDocumentDecoration[] | null> =>
43-
this.getDecorationsSubject(textDocument)
44-
)
42+
public deinitialize(): void {
43+
// Clear decorations;
44+
for (const subject of Object.values(this.decorations)) {
45+
subject.next(null)
46+
}
4547
}
4648

47-
protected validateRegistrationOptions(data: any): undefined {
48-
if (data) {
49-
throw new Error('TextDocumentDecorationFeature registration options should be undefined')
50-
}
51-
return data
49+
protected validateRegistrationOptions(_data: any): undefined {
50+
return
5251
}
5352

5453
private getDecorationsSubject(

src/extension/extension.test.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import * as assert from 'assert'
22
import { createConnection as createClientConnection } from '../client/connection'
3-
import { InitializedNotification, InitializeParams, InitializeRequest, InitializeResult } from '../protocol'
3+
import {
4+
InitializedNotification,
5+
InitializeParams,
6+
InitializeRequest,
7+
InitializeResult,
8+
RegistrationRequest,
9+
} from '../protocol'
410
import { createMessageTransports } from '../test/integration/helpers'
511
import { activateExtension } from './extension'
612

@@ -16,6 +22,8 @@ describe('activateExtension', () => {
1622
}
1723
const initResult: InitializeResult = {}
1824

25+
clientConnection.onRequest(RegistrationRequest.type, () => void 0)
26+
1927
const [, result] = await Promise.all([
2028
activateExtension<{}>(serverTransports, sourcegraph => {
2129
assert.deepStrictEqual(sourcegraph.initializeParams, initParams)

src/extension/extension.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
InitializeParams,
77
InitializeRequest,
88
InitializeResult,
9+
RegistrationParams,
10+
RegistrationRequest,
911
} from '../protocol'
1012
import { Commands, Configuration, ExtensionContext, Observable, SourcegraphExtensionAPI, Window, Windows } from './api'
1113
import { createExtCommands } from './features/commands'
@@ -81,8 +83,33 @@ export function activateExtension<C>(
8183
return {} as InitializeResult
8284
})
8385
connection.onNotification(InitializedNotification.type, () => {
84-
run(new ExtensionHandle<C>(connection, initializationParams))
85-
resolve()
86+
const handle = new ExtensionHandle<C>(connection, initializationParams)
87+
88+
// Register some capabilities that used to be implicit, for backcompat.
89+
connection
90+
.sendRequest(RegistrationRequest.type, {
91+
registrations: [
92+
{
93+
id: '__backcompat_1',
94+
method: 'textDocument/didOpen',
95+
registerOptions: { documentSelector: ['*'] },
96+
},
97+
{
98+
id: '__backcompat_2',
99+
method: 'textDocument/didClose',
100+
registerOptions: { documentSelector: ['*'] },
101+
},
102+
{
103+
id: '__backcompat_3',
104+
method: 'workspace/didChangeConfiguration',
105+
},
106+
],
107+
} as RegistrationParams)
108+
.then(() => {
109+
run(handle)
110+
resolve()
111+
})
112+
.catch(err => console.error(err))
86113
})
87114

88115
connection.listen()

0 commit comments

Comments
 (0)