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

Commit 46ba1f2

Browse files
committed
feat: add references
1 parent cd77aca commit 46ba1f2

File tree

4 files changed

+136
-6
lines changed

4 files changed

+136
-6
lines changed

src/features/references.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Feature, scopeDocumentSelectorToRoot } from './feature'
55
export const referencesFeature: Feature<typeof ReferencesRequest.type, 'referencesProvider'> = {
66
requestType: ReferencesRequest.type,
77
capabilityName: 'referencesProvider',
8-
capabilityToRegisterOptions: capability => ({ documentSelector: null }),
8+
capabilityToRegisterOptions: (capability, defaultSelector) => ({ documentSelector: defaultSelector }),
99
register: ({ sourcegraph, connection, scopeRootUri, clientToServerURI, serverToClientURI, registerOptions }) =>
1010
sourcegraph.languages.registerReferenceProvider(
1111
scopeDocumentSelectorToRoot(registerOptions.documentSelector, scopeRootUri),
@@ -15,7 +15,10 @@ export const referencesFeature: Feature<typeof ReferencesRequest.type, 'referenc
1515
textDocument: {
1616
uri: clientToServerURI(new URL(textDocument.uri)).href,
1717
},
18-
position,
18+
position: {
19+
line: position.line,
20+
character: position.character,
21+
},
1922
context,
2023
})
2124
rewriteUris(result, serverToClientURI)

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ export async function register({
169169
definition: {
170170
dynamicRegistration: true,
171171
},
172+
references: {
173+
dynamicRegistration: true,
174+
},
172175
},
173176
experimental: {
174177
progress: true,

src/test/integration.test.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import {
66
Hover,
77
InitializeParams,
88
InitializeResult,
9+
Location,
910
MarkupKind,
1011
TextDocumentPositionParams,
12+
ReferenceParams,
1113
} from 'vscode-languageserver-protocol'
1214
import { createMockSourcegraphAPI, stubTransport } from './stubs'
1315

@@ -96,6 +98,87 @@ describe('register()', () => {
9698
await unsubscribed
9799
sinon.assert.calledOnce(createConnection.returnValues[0].unsubscribe)
98100
})
101+
it('should register a references provider if the server reports the references capability', async () => {
102+
const repoRoot = 'https://sourcegraph.test/repo@rev/-/raw/'
103+
const server = {
104+
initialize: sinon.spy(
105+
(params: InitializeParams): InitializeResult => ({
106+
capabilities: {
107+
referencesProvider: true,
108+
},
109+
})
110+
),
111+
'textDocument/references': sinon.spy(
112+
(params: ReferenceParams): Location[] => [
113+
{
114+
uri: new URL('bar.ts', repoRoot).href,
115+
range: {
116+
start: { line: 1, character: 2 },
117+
end: { line: 3, character: 4 },
118+
},
119+
},
120+
]
121+
),
122+
}
123+
const createConnection = stubTransport(server)
124+
125+
sourcegraph.workspace.textDocuments = [
126+
{
127+
uri: new URL('foo.ts', repoRoot).href,
128+
languageId: 'typescript',
129+
text: 'console.log("Hello world")',
130+
},
131+
]
132+
sourcegraph.workspace.roots = [{ uri: repoRoot }]
133+
134+
const documentSelector = [{ language: 'typescript' }]
135+
await register({
136+
sourcegraph: sourcegraph as any,
137+
transport: createConnection,
138+
documentSelector,
139+
logger,
140+
})
141+
142+
sinon.assert.calledWith(
143+
server.initialize,
144+
sinon.match({
145+
capabilities: {
146+
textDocument: {
147+
references: {
148+
dynamicRegistration: true,
149+
},
150+
},
151+
},
152+
})
153+
)
154+
155+
sinon.assert.calledOnce(sourcegraph.languages.registerReferenceProvider)
156+
157+
const [selector, provider] = sourcegraph.languages.registerReferenceProvider.args[0]
158+
assert.deepStrictEqual(selector, [
159+
{
160+
language: 'typescript',
161+
pattern: 'https://sourcegraph.test/repo@rev/-/raw/**',
162+
},
163+
])
164+
const result = await provider.provideReferences(
165+
sourcegraph.workspace.textDocuments[0],
166+
new sourcegraph.Position(0, 2),
167+
{ includeDeclaration: false }
168+
)
169+
sinon.assert.calledOnce(server['textDocument/references'])
170+
sinon.assert.calledWith(server['textDocument/references'], {
171+
textDocument: { uri: sourcegraph.workspace.textDocuments[0].uri },
172+
position: { line: 0, character: 2 },
173+
context: { includeDeclaration: false },
174+
})
175+
assert.deepStrictEqual(result, [
176+
{
177+
uri: new URL('bar.ts', repoRoot),
178+
range: new sourcegraph.Range(new sourcegraph.Position(1, 2), new sourcegraph.Position(3, 4)),
179+
},
180+
])
181+
})
99182
it('should register a definition provider if the server reports the definition capability', async () => {
100183
const repoRoot = 'https://sourcegraph.test/repo@rev/-/raw/'
101184
const server = {

src/test/stubs.ts

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,51 @@ export const createMockSourcegraphAPI = () => {
6868
}
6969
) => new Subscription()
7070
),
71-
registerLocationProvider: sinon.spy(),
72-
registerReferenceProvider: sinon.spy(),
73-
registerTypeDefinitionProvider: sinon.spy(),
74-
registerImplementationProvider: sinon.spy(),
71+
registerLocationProvider: sinon.spy(
72+
(
73+
selector: sourcegraph.DocumentSelector,
74+
provider: {
75+
provideLocations: (
76+
textDocument: sourcegraph.TextDocument,
77+
position: Position
78+
) => Promise<sourcegraph.Definition>
79+
}
80+
) => new Subscription()
81+
),
82+
registerReferenceProvider: sinon.spy(
83+
(
84+
selector: sourcegraph.DocumentSelector,
85+
provider: {
86+
provideReferences: (
87+
textDocument: sourcegraph.TextDocument,
88+
position: Position,
89+
context: sourcegraph.ReferenceContext
90+
) => Promise<sourcegraph.Location[]>
91+
}
92+
) => new Subscription()
93+
),
94+
registerTypeDefinitionProvider: sinon.spy(
95+
(
96+
selector: sourcegraph.DocumentSelector,
97+
provider: {
98+
provideTypeDefinition: (
99+
textDocument: sourcegraph.TextDocument,
100+
position: Position
101+
) => Promise<sourcegraph.Definition>
102+
}
103+
) => new Subscription()
104+
),
105+
registerImplementationProvider: sinon.spy(
106+
(
107+
selector: sourcegraph.DocumentSelector,
108+
provider: {
109+
provideImplementation: (
110+
textDocument: sourcegraph.TextDocument,
111+
position: Position
112+
) => Promise<sourcegraph.Definition>
113+
}
114+
) => new Subscription()
115+
),
75116
},
76117
app: {
77118
createDecorationType: () => ({ key: uniqueId('decorationType') }),

0 commit comments

Comments
 (0)