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

Commit 4260a76

Browse files
committed
refactor: remove unneeded Component, use visibleTextDocuments directly
This suffices for a while. BREAKING CHANGE: The environment component has been removed; now you need to specify the visible text documents directly.
1 parent 3bc8eac commit 4260a76

12 files changed

+61
-61
lines changed

src/client/api/documents.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { Observable, Subscription } from 'rxjs'
2-
import { filter } from 'rxjs/operators'
32
import { TextDocument } from 'sourcegraph'
43
import { createProxyAndHandleRequests } from '../../common/proxy'
54
import { ExtDocumentsAPI } from '../../extension/api/documents'
65
import { Connection } from '../../protocol/jsonrpc2/connection'
7-
import { TextDocumentItem } from '../types/textDocument'
86
import { SubscriptionMap } from './common'
97

108
/** @internal */
@@ -15,13 +13,13 @@ export class ClientDocuments {
1513

1614
constructor(
1715
connection: Connection,
18-
environmentTextDocument: Observable<Pick<TextDocument, 'uri' | 'languageId'> | null>
16+
environmentTextDocuments: Observable<Pick<TextDocument, 'uri' | 'languageId' | 'text'>[] | null>
1917
) {
2018
this.proxy = createProxyAndHandleRequests('documents', connection, this)
2119

2220
this.subscriptions.add(
23-
environmentTextDocument.pipe(filter((v): v is TextDocumentItem => v !== null)).subscribe(doc => {
24-
this.proxy.$acceptDocumentData(doc)
21+
environmentTextDocuments.subscribe(docs => {
22+
this.proxy.$acceptDocumentData(docs || [])
2523
})
2624
)
2725

src/client/api/windows.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Observable, Subscription } from 'rxjs'
2-
import { filter } from 'rxjs/operators'
32
import * as sourcegraph from 'sourcegraph'
43
import { createProxyAndHandleRequests } from '../../common/proxy'
54
import { ExtWindowsAPI } from '../../extension/api/windows'
@@ -11,7 +10,7 @@ import {
1110
ShowMessageRequestParams,
1211
} from '../../protocol'
1312
import { Connection } from '../../protocol/jsonrpc2/connection'
14-
import { Component } from '../environment'
13+
import { TextDocumentItem } from '../types/textDocument'
1514
import { SubscriptionMap } from './common'
1615

1716
/** @internal */
@@ -29,7 +28,7 @@ export class ClientWindows implements ClientWindowsAPI {
2928

3029
constructor(
3130
connection: Connection,
32-
environmentComponent: Observable<Component | null>,
31+
environmentTextDocuments: Observable<TextDocumentItem[] | null>,
3332
/** Called when the client receives a window/showMessage notification. */
3433
private showMessage: (params: ShowMessageParams) => void,
3534
/**
@@ -46,8 +45,10 @@ export class ClientWindows implements ClientWindowsAPI {
4645
this.proxy = createProxyAndHandleRequests('windows', connection, this)
4746

4847
this.subscriptions.add(
49-
environmentComponent.pipe(filter((v): v is Component => v !== null)).subscribe(component => {
50-
this.proxy.$acceptWindowData(component ? [{ visibleTextDocument: component.document.uri }] : [])
48+
environmentTextDocuments.subscribe(textDocuments => {
49+
this.proxy.$acceptWindowData(
50+
textDocuments ? textDocuments.map(textDocument => ({ visibleTextDocument: textDocument.uri })) : []
51+
)
5152
})
5253
)
5354

src/client/context/context.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ describe('getComputedContextProperty', () => {
3333
describe('environment with component', () => {
3434
const env: Environment = {
3535
...EMPTY_ENVIRONMENT,
36-
component: {
37-
document: {
36+
visibleTextDocuments: [
37+
{
3838
uri: 'file:///a/b.c',
3939
languageId: 'l',
4040
text: 't',
4141
},
42-
},
42+
],
4343
}
4444

4545
describe('resource', () => {

src/client/context/context.ts

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { basename, dirname, extname } from 'path'
2-
import { Component, Environment } from '../environment'
2+
import { Environment } from '../environment'
3+
import { TextDocumentItem } from '../types/textDocument'
34

45
/**
56
* Returns a new context created by applying the update context to the base context. It is equivalent to `{...base,
@@ -34,7 +35,7 @@ export const EMPTY_CONTEXT: Context = {}
3435
* @param key the context property key to look up
3536
* @param scope the user interface component in whose scope this computation should occur
3637
*/
37-
export function getComputedContextProperty(environment: Environment, key: string, scope?: Component): any {
38+
export function getComputedContextProperty(environment: Environment, key: string, scope?: TextDocumentItem): any {
3839
if (key.startsWith('config.')) {
3940
const prop = key.slice('config.'.length)
4041
const value = environment.configuration.merged[prop]
@@ -43,12 +44,13 @@ export function getComputedContextProperty(environment: Environment, key: string
4344
// which a falsey null default is useful).
4445
return value === undefined ? null : value
4546
}
46-
const component = scope || environment.component
47-
if (key === 'resource' || key === 'component') {
48-
return !!component
47+
const textDocument: TextDocumentItem | null =
48+
scope || (environment.visibleTextDocuments && environment.visibleTextDocuments[0])
49+
if (key === 'resource' || key === 'component' /* BACKCOMPAT: allow 'component' */) {
50+
return !!textDocument
4951
}
5052
if (key.startsWith('resource.')) {
51-
if (!component) {
53+
if (!textDocument) {
5254
return undefined
5355
}
5456
// TODO(sqs): Define these precisely. If the resource is in a repository, what is the "path"? Is it the
@@ -57,23 +59,23 @@ export function getComputedContextProperty(environment: Environment, key: string
5759
const prop = key.slice('resource.'.length)
5860
switch (prop) {
5961
case 'uri':
60-
return component.document.uri
62+
return textDocument.uri
6163
case 'basename':
62-
return basename(component.document.uri)
64+
return basename(textDocument.uri)
6365
case 'dirname':
64-
return dirname(component.document.uri)
66+
return dirname(textDocument.uri)
6567
case 'extname':
66-
return extname(component.document.uri)
68+
return extname(textDocument.uri)
6769
case 'language':
68-
return component.document.languageId
70+
return textDocument.languageId
6971
case 'textContent':
70-
return component.document.text
72+
return textDocument.text
7173
case 'type':
7274
return 'textDocument'
7375
}
7476
}
7577
if (key.startsWith('component.')) {
76-
if (!component) {
78+
if (!textDocument) {
7779
return undefined
7880
}
7981
const prop = key.slice('component.'.length)

src/client/controller.test.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ const create = (environment?: Environment): TestController => {
3030
}
3131

3232
const FIXTURE_ENVIRONMENT: Environment<any, any> = {
33-
component: {
34-
document: { uri: 'file:///f', languageId: 'l', text: '' },
35-
},
33+
visibleTextDocuments: [{ uri: 'file:///f', languageId: 'l', text: '' }],
3634
extensions: [{ id: 'x' }],
3735
configuration: {},
3836
context: {},

src/client/controller.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export class Controller<X extends Extension, C extends ConfigurationCascade> imp
234234
new ClientWindows(
235235
client,
236236
this.environment.pipe(
237-
map(({ component }) => component),
237+
map(({ visibleTextDocuments }) => visibleTextDocuments),
238238
distinctUntilChanged()
239239
),
240240
(params: ShowMessageParams) => this._showMessages.next({ ...params }),
@@ -253,7 +253,7 @@ export class Controller<X extends Extension, C extends ConfigurationCascade> imp
253253
new ClientDocuments(
254254
client,
255255
this.environment.pipe(
256-
map(({ component }) => component && component.document),
256+
map(({ visibleTextDocuments }) => visibleTextDocuments),
257257
distinctUntilChanged()
258258
)
259259
)

src/client/environment.ts

+4-11
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ import { TextDocumentItem } from './types/textDocument'
1414
*/
1515
export interface Environment<X extends Extension = Extension, C extends ConfigurationCascade = ConfigurationCascade> {
1616
/**
17-
* The active user interface component (i.e., file view or editor), or null if there is none.
18-
*
19-
* TODO(sqs): Support multiple components.
17+
* The text documents that are currently visible. Each text document is represented to extensions as being
18+
* in its own visible CodeEditor.
2019
*/
21-
readonly component: Component | null
20+
readonly visibleTextDocuments: TextDocumentItem[] | null
2221

2322
/** The active extensions, or null if there are none. */
2423
readonly extensions: X[] | null
@@ -32,14 +31,8 @@ export interface Environment<X extends Extension = Extension, C extends Configur
3231

3332
/** An empty Sourcegraph extension client environment. */
3433
export const EMPTY_ENVIRONMENT: Environment<any, any> = {
35-
component: null,
34+
visibleTextDocuments: null,
3635
extensions: null,
3736
configuration: { merged: {} },
3837
context: EMPTY_CONTEXT,
3938
}
40-
41-
/** An application component that displays a [TextDocument](#TextDocument). */
42-
export interface Component {
43-
/** The document displayed by the component. */
44-
readonly document: TextDocumentItem
45-
}

src/client/providers/contribution.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import { flatten, isEqual } from '../../util'
1212
import { getComputedContextProperty } from '../context/context'
1313
import { ComputedContext, evaluate, evaluateTemplate } from '../context/expr/evaluator'
1414
import { TEMPLATE_BEGIN } from '../context/expr/lexer'
15-
import { Component, Environment } from '../environment'
15+
import { Environment } from '../environment'
16+
import { TextDocumentItem } from '../types/textDocument'
1617

1718
/** A registered set of contributions from an extension in the registry. */
1819
export interface ContributionsEntry {
@@ -74,13 +75,13 @@ export class ContributionRegistry {
7475
* Returns an observable that emits all contributions (merged) evaluated in the current
7576
* environment (with the optional scope). It emits whenever there is any change.
7677
*/
77-
public getContributions(scope?: Component): Observable<Contributions> {
78+
public getContributions(scope?: TextDocumentItem): Observable<Contributions> {
7879
return this.getContributionsFromEntries(this._entries, scope)
7980
}
8081

8182
protected getContributionsFromEntries(
8283
entries: Observable<ContributionsEntry[]>,
83-
scope?: Component
84+
scope?: TextDocumentItem
8485
): Observable<Contributions> {
8586
return combineLatest(
8687
entries.pipe(

src/extension/api/documents.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { TextDocumentItem } from '../../client/types/textDocument'
44

55
/** @internal */
66
export interface ExtDocumentsAPI {
7-
$acceptDocumentData(doc: TextDocumentItem): void
7+
$acceptDocumentData(doc: TextDocumentItem[]): void
88
}
99

1010
/** @internal */
@@ -54,8 +54,17 @@ export class ExtDocuments implements ExtDocumentsAPI {
5454
private textDocumentAdds = new Subject<TextDocument>()
5555
public readonly onDidOpenTextDocument: Observable<TextDocument> = this.textDocumentAdds
5656

57-
public $acceptDocumentData(doc: TextDocumentItem): void {
58-
this.documents.set(doc.uri, doc)
59-
this.textDocumentAdds.next(doc)
57+
public $acceptDocumentData(docs: TextDocumentItem[] | null): void {
58+
if (!docs) {
59+
// We don't ever (yet) communicate to the extension when docs are closed.
60+
return
61+
}
62+
for (const doc of docs) {
63+
const isNew = !this.documents.has(doc.uri)
64+
this.documents.set(doc.uri, doc)
65+
if (isNew) {
66+
this.textDocumentAdds.next(doc)
67+
}
68+
}
6069
}
6170
}

src/integration-test/documents.test.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ describe('Documents (integration)', () => {
1919
const prevEnvironment = getEnvironment()
2020
clientController.setEnvironment({
2121
...prevEnvironment,
22-
component: {
23-
document: { uri: 'file:///f2', languageId: 'l2', text: 't2' },
24-
},
22+
visibleTextDocuments: [{ uri: 'file:///f2', languageId: 'l2', text: 't2' }],
2523
})
2624

2725
await ready
@@ -43,9 +41,7 @@ describe('Documents (integration)', () => {
4341
const prevEnvironment = getEnvironment()
4442
clientController.setEnvironment({
4543
...prevEnvironment,
46-
component: {
47-
document: { uri: 'file:///f2', languageId: 'l2', text: 't2' },
48-
},
44+
visibleTextDocuments: [{ uri: 'file:///f2', languageId: 'l2', text: 't2' }],
4945
})
5046
await extensionHost.internal.sync()
5147

src/integration-test/helpers.test.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ import { createExtensionHost } from '../extension/extensionHost'
66
import { createMessageTransports } from '../protocol/jsonrpc2/helpers.test'
77

88
const FIXTURE_ENVIRONMENT: Environment = {
9-
component: {
10-
document: { uri: 'file:///f', languageId: 'l', text: 't' },
11-
},
9+
visibleTextDocuments: [
10+
{
11+
uri: 'file:///f',
12+
languageId: 'l',
13+
text: 't',
14+
},
15+
],
1216
extensions: [{ id: 'x' }],
1317
configuration: { merged: { a: 1 } },
1418
context: {},

src/integration-test/windows.test.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ describe('Windows (integration)', () => {
4343
const prevEnvironment = getEnvironment()
4444
clientController.setEnvironment({
4545
...prevEnvironment,
46-
component: {
47-
document: { uri: 'file:///f2', languageId: 'l2', text: 't2' },
48-
},
46+
visibleTextDocuments: [{ uri: 'file:///f2', languageId: 'l2', text: 't2' }],
4947
})
5048

5149
await ready

0 commit comments

Comments
 (0)