From 82da1113f9530b5bf3d368d44f94c6caad64a919 Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 20:45:42 -0600 Subject: [PATCH 1/8] wip --- src/lang-go.ts | 396 +++++++++++++++++++++++++------------------------ 1 file changed, 203 insertions(+), 193 deletions(-) diff --git a/src/lang-go.ts b/src/lang-go.ts index 33d02b7..433ee1b 100644 --- a/src/lang-go.ts +++ b/src/lang-go.ts @@ -1,16 +1,17 @@ import '@babel/polyfill' -import { activateBasicCodeIntel, registerFeedbackButton } from '@sourcegraph/basic-code-intel' +import { Handler, initLSIF, registerFeedbackButton } from '@sourcegraph/basic-code-intel' import * as wsrpc from '@sourcegraph/vscode-ws-jsonrpc' import { ajax } from 'rxjs/ajax' import * as sourcegraph from 'sourcegraph' import * as rpc from 'vscode-jsonrpc' import * as lsp from 'vscode-languageserver-protocol' +import * as LSP from 'vscode-languageserver-types' import * as convert from './convert-lsp-to-sea' import * as lspext from './lspext' import * as path from 'path' -import { BehaviorSubject, from, Observable, Observer, of, throwError } from 'rxjs' +import { BehaviorSubject, from, Observable, Observer, of, throwError, Unsubscribable } from 'rxjs' import { concatMap, distinctUntilChanged, @@ -26,6 +27,7 @@ import { import { ConsoleLogger, createWebSocketConnection } from '@sourcegraph/vscode-ws-jsonrpc' import gql from 'tagged-template-noop' import { Settings } from './settings' +import { asyncFirst, wrapMaybe, when } from '@sourcegraph/basic-code-intel/lib/lsif' // If we can rid ourselves of file:// URIs, this type won't be necessary and we // can use lspext.Xreference directly. @@ -278,15 +280,15 @@ function repoNameFromDoc(doc: sourcegraph.TextDocument): string { } /** - * Creates a function of type SendRequest that can be used to send LSP - * requests to the corresponding language server. This returns an Observable - * so that all the connections to that language server can be disposed of - * when calling .unsubscribe(). + * Creates a function of type SendRequest that can be used to send LSP requests + * to the corresponding language server. This returns an Unsubscribable so that + * all the connections to that language server can be disposed of when calling + * .unsubscribe(). * * Internally, this maintains a mapping from rootURI to the connection * associated with that rootURI, so it supports multiple roots (untested). */ -function mkSendRequest(address: string, token: string | undefined): Observable { +function mkSendRequest(address: string, token: string | undefined): { sendRequest: SendRequest } & Unsubscribable { const rootURIToConnection: { [rootURI: string]: Promise } = {} async function connectionFor(root: URL): Promise { if (rootURIToConnection[root.href]) { @@ -315,9 +317,9 @@ function mkSendRequest(address: string, token: string | undefined): Observable) => { - observer.next(sendRequest) - return () => { + return { + sendRequest, + unsubscribe: () => { for (const rootURI of Object.keys(rootURIToConnection)) { if (rootURIToConnection[rootURI]) { // tslint:disable-next-line: no-floating-promises @@ -325,8 +327,8 @@ function mkSendRequest(address: string, token: string | undefined): Observable { +export async function initLSP(ctx: sourcegraph.ExtensionContext) { const accessToken = await getOrTryToCreateAccessToken() - const settings: BehaviorSubject = new BehaviorSubject({}) - ctx.subscriptions.add( - sourcegraph.configuration.subscribe(() => { - settings.next(sourcegraph.configuration.get().value) - }) - ) - const langserverAddress = settings.pipe(map(settings => settings['go.serverUrl'])) - - const NO_ADDRESS_ERROR = `To get Go code intelligence, add "${'go.address' as keyof Settings}": "wss://example.com" to your settings.` - - const sendRequestObservable = langserverAddress.pipe( - switchMap(address => (address ? mkSendRequest(address, accessToken) : of(undefined))), - shareReplay(1) - ) - - function sendRequest(params: SendRequestParams): Promise { - return sendRequestObservable - .pipe( - take(1), - switchMap(send => (send ? send(params) : throwError(NO_ADDRESS_ERROR))) - ) - .toPromise() + const langserverAddress = sourcegraph.configuration.get().get('go.serverUrl') + if (!langserverAddress) { + return { + hover: () => Promise.resolve(undefined), + definition: () => Promise.resolve(undefined), + references: () => Promise.resolve(undefined), + } } - // TODO When go.langserver-address is set to an invalid address - // and this extension fails to connect, the hover spinner hangs - // indefinitely. @felix, could you take a look? I'm guessing the - // error is not getting propagated, but despite 30 minutes of - // debugging I can't figure out why. - const sendDocPositionRequest = ({ + const unsubscribableSendRequest = mkSendRequest(langserverAddress, accessToken) + const sendRequest = unsubscribableSendRequest.sendRequest + ctx.subscriptions.add(unsubscribableSendRequest) + + const sendDocPositionRequest = ({ doc, pos, ty, @@ -607,7 +593,7 @@ export async function activateUsingWebSockets(ctx: sourcegraph.ExtensionContext) pos: sourcegraph.Position ty: any useCache: boolean - }): Promise => + }): Promise => sendRequest({ rootURI: rootURIFromDoc(doc), requestType: ty, @@ -615,116 +601,115 @@ export async function activateUsingWebSockets(ctx: sourcegraph.ExtensionContext) useCache, }) - ctx.subscriptions.add( - sourcegraph.languages.registerHoverProvider([{ pattern: '*.go' }], { - provideHover: async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => { - const response = await sendDocPositionRequest({ doc, pos, ty: lsp.HoverRequest.type, useCache: true }) - return convert.hover(response) - }, - }) - ) - - ctx.subscriptions.add( - sourcegraph.languages.registerDefinitionProvider([{ pattern: '*.go' }], { - provideDefinition: async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => { - const response = await sendDocPositionRequest({ - doc, - pos, - ty: new lsp.RequestType('textDocument/xdefinition') as any, - useCache: true, - }) - return convert.xdefinition({ currentDocURI: doc.uri, xdefinition: response }) - }, + const hover = async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => + convert.hover( + await sendDocPositionRequest({ + doc, + pos, + ty: lsp.HoverRequest.type, + useCache: true, + }) + ) + const definition = async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => + convert.xdefinition({ + currentDocURI: doc.uri, + xdefinition: await sendDocPositionRequest({ + doc, + pos, + ty: new lsp.RequestType('textDocument/xdefinition') as any, + useCache: true, + }), }) - ) - - ctx.subscriptions.add( - sourcegraph.languages.registerReferenceProvider([{ pattern: '*.go' }], { - provideReferences: async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => { - const response = await sendDocPositionRequest({ - doc, - pos, - ty: lsp.ReferencesRequest.type, - useCache: true, - }) - return convert.references({ currentDocURI: doc.uri, references: response }) - }, + const references = async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => + convert.references({ + currentDocURI: doc.uri, + references: await sendDocPositionRequest({ + doc, + pos, + ty: lsp.ReferencesRequest.type, + useCache: true, + }), }) - ) - /** - * Automatically registers/deregisters a provider based on the given predicate of the settings. - */ - function registerWhile({ - register, - settingsPredicate, - }: { - register: () => sourcegraph.Unsubscribable - settingsPredicate: (settings: Settings) => boolean - }): sourcegraph.Unsubscribable { - let registration: sourcegraph.Unsubscribable | undefined - return from(settings) - .pipe( - map(settingsPredicate), - distinctUntilChanged(), - map(enabled => { - if (enabled) { - registration = register() - } else { - if (registration) { - registration.unsubscribe() - registration = undefined - } - } - }), - finalize(() => { - if (registration) { - registration.unsubscribe() - registration = undefined - } - }) - ) - .subscribe() + return { + hover: wrapMaybe(hover), + definition: wrapMaybe(definition), + references: wrapMaybe(references), } - ctx.subscriptions.add( - registerWhile({ - register: () => - sourcegraph.languages.registerReferenceProvider([{ pattern: '*.go' }], { - provideReferences: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => - xrefs({ - doc, - pos, - sendRequest, - }).pipe( - scan((acc: XRef[], curr: XRef) => [...acc, curr], [] as XRef[]), - map(response => convert.xreferences({ references: response })) - ), - }), - settingsPredicate: settings => Boolean(settings['go.showExternalReferences']), - }) - ) - - // Implementations panel. - const IMPL_ID = 'go.impl' // implementations panel and provider ID - ctx.subscriptions.add( - sourcegraph.languages.registerLocationProvider(IMPL_ID, [{ pattern: '*.go' }], { - provideLocations: async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => { - const response = await sendDocPositionRequest({ - doc, - pos, - ty: lsp.ImplementationRequest.type, - useCache: true, - }) - return convert.references({ currentDocURI: doc.uri, references: response }) - }, - }) - ) - const panelView = sourcegraph.app.createPanelView(IMPL_ID) - panelView.title = 'Go ifaces/impls' - panelView.component = { locationProvider: IMPL_ID } - panelView.priority = 160 - ctx.subscriptions.add(panelView) + // /** + // * Automatically registers/deregisters a provider based on the given predicate of the settings. + // */ + // function registerWhile({ + // register, + // settingsPredicate, + // }: { + // register: () => sourcegraph.Unsubscribable + // settingsPredicate: (settings: Settings) => boolean + // }): sourcegraph.Unsubscribable { + // let registration: sourcegraph.Unsubscribable | undefined + // return from(settings) + // .pipe( + // map(settingsPredicate), + // distinctUntilChanged(), + // map(enabled => { + // if (enabled) { + // registration = register() + // } else { + // if (registration) { + // registration.unsubscribe() + // registration = undefined + // } + // } + // }), + // finalize(() => { + // if (registration) { + // registration.unsubscribe() + // registration = undefined + // } + // }) + // ) + // .subscribe() + // } + + // ctx.subscriptions.add( + // registerWhile({ + // register: () => + // sourcegraph.languages.registerReferenceProvider([{ pattern: '*.go' }], { + // provideReferences: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => + // xrefs({ + // doc, + // pos, + // sendRequest, + // }).pipe( + // scan((acc: XRef[], curr: XRef) => [...acc, curr], [] as XRef[]), + // map(response => convert.xreferences({ references: response })) + // ), + // }), + // settingsPredicate: settings => Boolean(settings['go.showExternalReferences']), + // }) + // ) + + // // Implementations panel. + // const IMPL_ID = 'go.impl' // implementations panel and provider ID + // ctx.subscriptions.add( + // sourcegraph.languages.registerLocationProvider(IMPL_ID, [{ pattern: '*.go' }], { + // provideLocations: async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => { + // const response = await sendDocPositionRequest({ + // doc, + // pos, + // ty: lsp.ImplementationRequest.type, + // useCache: true, + // }) + // return convert.references({ currentDocURI: doc.uri, references: response }) + // }, + // }) + // ) + // const panelView = sourcegraph.app.createPanelView(IMPL_ID) + // panelView.title = 'Go ifaces/impls' + // panelView.component = { locationProvider: IMPL_ID } + // panelView.priority = 160 + // ctx.subscriptions.add(panelView) } function pathname(url: string): string { @@ -734,56 +719,81 @@ function pathname(url: string): string { return pathname } +function initBasicCodeIntel() { + const handler = new Handler({ + sourcegraph, + languageID: 'go', + fileExts: ['go'], + filterDefinitions: ({ repo, filePath, pos, fileContent, results }) => { + const currentFileImportedPaths = fileContent + .split('\n') + .map(line => { + // Matches the import at index 3 + const match = /^(import |\t)(\w+ |\. )?"(.*)"$/.exec(line) + return match ? match[3] : undefined + }) + .filter((x): x is string => Boolean(x)) + + const currentFileImportPath = repo + '/' + path.dirname(filePath) + + const filteredResults = results.filter(result => { + const resultImportPath = result.repo + '/' + path.dirname(result.file) + return ( + currentFileImportedPaths.some(i => resultImportPath.includes(i)) || + resultImportPath === currentFileImportPath + ) + }) + + return filteredResults.length === 0 ? results : filteredResults + }, + commentStyle: { + lineRegex: /\/\/\s?/, + }, + }) + return { + hover: handler.hover.bind(handler), + definition: handler.definition.bind(handler), + references: handler.references.bind(handler), + } +} + // No-op for Sourcegraph versions prior to 3.0. const DUMMY_CTX = { subscriptions: { add: (_unsubscribable: any) => void 0 } } export function activate(ctx: sourcegraph.ExtensionContext = DUMMY_CTX): void { - async function afterActivate(): Promise { - const address = sourcegraph.configuration.get().get('go.serverUrl') - if (address) { - ctx.subscriptions.add(registerFeedbackButton({ languageID: 'go', sourcegraph, isPrecise: true })) - - await activateUsingWebSockets(ctx) - } else { - ctx.subscriptions.add( - registerFeedbackButton({ - languageID: 'go', - sourcegraph, - isPrecise: false, - }) - ) - - activateBasicCodeIntel({ - sourcegraph, - languageID: 'go', - fileExts: ['go'], - filterDefinitions: ({ repo, filePath, pos, fileContent, results }) => { - const currentFileImportedPaths = fileContent - .split('\n') - .map(line => { - // Matches the import at index 3 - const match = /^(import |\t)(\w+ |\. )?"(.*)"$/.exec(line) - return match ? match[3] : undefined - }) - .filter((x): x is string => Boolean(x)) - - const currentFileImportPath = repo + '/' + path.dirname(filePath) - - const filteredResults = results.filter(result => { - const resultImportPath = result.repo + '/' + path.dirname(result.file) - return ( - currentFileImportedPaths.some(i => resultImportPath.includes(i)) || - resultImportPath === currentFileImportPath - ) - }) - return filteredResults.length === 0 ? results : filteredResults - }, - commentStyle: { - lineRegex: /\/\/\s?/, + ctx.subscriptions.add( + sourcegraph.languages.registerHoverProvider(['*.go'], { + provideHover: (doc: any,pos:any) => { + console.log('hov2') + return null }, - })(ctx) - } - } - setTimeout(afterActivate, 100) + }) + ) + console.log('reggedit') + // async function afterActivate(): Promise { + // const lsif = initLSIF() + // const lsp = await initLSP(ctx) + // const basicCodeIntel = initBasicCodeIntel() + + // ctx.subscriptions.add( + // sourcegraph.languages.registerHoverProvider(['*.go'], { + // provideHover: (doc,pos) => { + // console.log('hov') + // return asyncFirst([lsif.hover, lsp.hover, wrapMaybe(basicCodeIntel.hover)], null)(doc, pos) + // }, + // }) + // ) + // ctx.subscriptions.add( + // sourcegraph.languages.registerDefinitionProvider(['*.go'], { + // provideDefinition: asyncFirst([lsif.definition, lsp.definition, wrapMaybe(basicCodeIntel.definition)], null), + // }) + // ) + // ctx.subscriptions.add( + // sourcegraph.languages.registerReferenceProvider(['*.go'], { + // provideReferences: asyncFirst([lsif.references, lsp.references, wrapMaybe(basicCodeIntel.references)], null), + // }) + // ) + // } + // setTimeout(afterActivate, 100) } From a589dbea57cb6762e3a8c92683b42062dd7118fc Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 21:21:31 -0600 Subject: [PATCH 2/8] Use tsc-watch --- dev | 9 +-------- package.json | 1 + 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/dev b/dev index 847eb91..93b55d1 100755 --- a/dev +++ b/dev @@ -2,11 +2,4 @@ set -ex -yarn -env FORCE_COLOR=0 \ - yarn run concurrently \ - --names serve,build \ - --prefix name \ - --kill-others \ - 'yarn run serve --no-cache | cat' \ - 'yarn run watch:typecheck' +yarn run tsc-watch --onSuccess "yarn run serve" --noClear diff --git a/package.json b/package.json index 615b661..158c377 100644 --- a/package.json +++ b/package.json @@ -148,6 +148,7 @@ "mkdirp-promise": "^5.0.1", "parcel-bundler": "^1.11.0", "sourcegraph": "^23.0.1", + "tsc-watch": "^2.2.1", "tslint": "^5.18.0", "typescript": "^3.1.6" }, From 640909e9b9f8e55bda2f7b483b118afc80da149f Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 21:21:52 -0600 Subject: [PATCH 3/8] wip --- package.json | 2 +- src/lang-go.ts | 59 ++++++++++++++---------------- yarn.lock | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 158c377..f52d7aa 100644 --- a/package.json +++ b/package.json @@ -153,7 +153,7 @@ "typescript": "^3.1.6" }, "dependencies": { - "@sourcegraph/basic-code-intel": "6.0.18", + "@sourcegraph/basic-code-intel": "7.0.0", "@sourcegraph/vscode-ws-jsonrpc": "0.0.3-fork", "prettier": "^1.16.4", "rxjs": "^6.3.3", diff --git a/src/lang-go.ts b/src/lang-go.ts index 433ee1b..320ac3e 100644 --- a/src/lang-go.ts +++ b/src/lang-go.ts @@ -1,6 +1,6 @@ import '@babel/polyfill' -import { Handler, initLSIF, registerFeedbackButton } from '@sourcegraph/basic-code-intel' +import { Handler, initLSIF } from '@sourcegraph/basic-code-intel' import * as wsrpc from '@sourcegraph/vscode-ws-jsonrpc' import { ajax } from 'rxjs/ajax' import * as sourcegraph from 'sourcegraph' @@ -760,40 +760,35 @@ function initBasicCodeIntel() { // No-op for Sourcegraph versions prior to 3.0. const DUMMY_CTX = { subscriptions: { add: (_unsubscribable: any) => void 0 } } +const goFiles = [{ pattern: '*.go' }] + export function activate(ctx: sourcegraph.ExtensionContext = DUMMY_CTX): void { + async function afterActivate(): Promise { + const lsif = initLSIF() + const lsp = await initLSP(ctx) + const basicCodeIntel = initBasicCodeIntel() ctx.subscriptions.add( - sourcegraph.languages.registerHoverProvider(['*.go'], { - provideHover: (doc: any,pos:any) => { - console.log('hov2') - return null - }, + sourcegraph.languages.registerHoverProvider(goFiles, { + provideHover: asyncFirst([lsif.hover, lsp.hover, wrapMaybe(basicCodeIntel.hover)], null), }) ) - console.log('reggedit') - // async function afterActivate(): Promise { - // const lsif = initLSIF() - // const lsp = await initLSP(ctx) - // const basicCodeIntel = initBasicCodeIntel() - - // ctx.subscriptions.add( - // sourcegraph.languages.registerHoverProvider(['*.go'], { - // provideHover: (doc,pos) => { - // console.log('hov') - // return asyncFirst([lsif.hover, lsp.hover, wrapMaybe(basicCodeIntel.hover)], null)(doc, pos) - // }, - // }) - // ) - // ctx.subscriptions.add( - // sourcegraph.languages.registerDefinitionProvider(['*.go'], { - // provideDefinition: asyncFirst([lsif.definition, lsp.definition, wrapMaybe(basicCodeIntel.definition)], null), - // }) - // ) - // ctx.subscriptions.add( - // sourcegraph.languages.registerReferenceProvider(['*.go'], { - // provideReferences: asyncFirst([lsif.references, lsp.references, wrapMaybe(basicCodeIntel.references)], null), - // }) - // ) - // } - // setTimeout(afterActivate, 100) + ctx.subscriptions.add( + sourcegraph.languages.registerDefinitionProvider(goFiles, { + provideDefinition: asyncFirst( + [lsif.definition, lsp.definition, wrapMaybe(basicCodeIntel.definition)], + null + ), + }) + ) + ctx.subscriptions.add( + sourcegraph.languages.registerReferenceProvider(goFiles, { + provideReferences: asyncFirst( + [lsif.references, lsp.references, wrapMaybe(basicCodeIntel.references)], + null + ), + }) + ) + } + setTimeout(afterActivate, 100) } diff --git a/yarn.lock b/yarn.lock index 7946e51..3c10a39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,6 +1556,15 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^6.0.0, cross-spawn@^6.0.4: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -1992,6 +2001,11 @@ duplexer2@~0.1.4: dependencies: readable-stream "^2.0.2" +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + editorconfig@^0.15.0: version "0.15.2" resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.2.tgz#047be983abb9ab3c2eefe5199cb2b7c5689f0702" @@ -2130,6 +2144,19 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +event-stream@=3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -2282,6 +2309,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -3111,6 +3143,14 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" @@ -3150,6 +3190,11 @@ map-obj@^1.0.0, map-obj@^1.0.1: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -3365,6 +3410,11 @@ node-addon-api@^1.6.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.1.tgz#a9881c8dbc6400bac6ddedcb96eccf8051678536" integrity sha512-GcLOYrG5/enbqH4SMsqXt6GQUQGGnDnE3FLDZzXYkCgQHuZV5UDFR+EboeY8kpG0avroyOjpFQ2qLEBosFcRIA== +node-cleanup@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c" + integrity sha1-esGavSl+Caf3KnFUXZUbUX5N3iw= + node-forge@^0.7.1: version "0.7.6" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac" @@ -3865,6 +3915,13 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -4488,6 +4545,13 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +ps-tree@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd" + integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA== + dependencies: + event-stream "=3.3.4" + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -5095,6 +5159,13 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -5153,6 +5224,13 @@ stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + stream-http@^2.7.2: version "2.8.3" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" @@ -5169,6 +5247,11 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +string-argv@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.1.2.tgz#c5b7bc03fb2b11983ba3a72333dd0559e77e4738" + integrity sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA== + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -5334,6 +5417,11 @@ through2@^2.0.0, through2@~2.0.3: readable-stream "~2.3.6" xtend "~4.0.1" +through@2, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + timers-browserify@^2.0.4: version "2.0.10" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" @@ -5406,6 +5494,17 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= +tsc-watch@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tsc-watch/-/tsc-watch-2.2.1.tgz#6e41a091e07d26dbcf5c815bfb514435ded33286" + integrity sha512-E61+ozEutLDgmXN+1+rkoCaUmd2g/cpa4mpEPMA3gPi89PBJiAcIUtH0xdCxeChXlR9TcuwOuTqu5jZDRhgfRw== + dependencies: + cross-spawn "^5.1.0" + node-cleanup "^2.1.2" + ps-tree "^1.2.0" + string-argv "^0.1.1" + strip-ansi "^4.0.0" + tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" From 283a0228e22e6ce9b2a10c31c813127768fe2ca3 Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 22:22:00 -0600 Subject: [PATCH 4/8] More refactoring --- src/lang-go.ts | 234 ++++++++++++++++++++++++++----------------------- 1 file changed, 124 insertions(+), 110 deletions(-) diff --git a/src/lang-go.ts b/src/lang-go.ts index 320ac3e..204d970 100644 --- a/src/lang-go.ts +++ b/src/lang-go.ts @@ -266,7 +266,7 @@ interface SendRequestParams { useCache: boolean } -type SendRequest = (params: SendRequestParams) => Promise +type SendRequest = (params: SendRequestParams) => Promise function rootURIFromDoc(doc: sourcegraph.TextDocument): URL { const url = new URL(doc.uri) @@ -288,7 +288,7 @@ function repoNameFromDoc(doc: sourcegraph.TextDocument): string { * Internally, this maintains a mapping from rootURI to the connection * associated with that rootURI, so it supports multiple roots (untested). */ -function mkSendRequest(address: string, token: string | undefined): { sendRequest: SendRequest } & Unsubscribable { +function mkSendRequest(address: string, token: string | undefined): { sendRequest: SendRequest } & Unsubscribable { const rootURIToConnection: { [rootURI: string]: Promise } = {} async function connectionFor(root: URL): Promise { if (rootURIToConnection[root.href]) { @@ -306,7 +306,7 @@ function mkSendRequest(address: string, token: string | undefined): { sendReques } } - const sendRequest: SendRequest = async ({ rootURI, requestType, request, useCache }) => { + const sendRequest: SendRequest = async ({ rootURI, requestType, request, useCache }) => { if (useCache) { return await (await connectionFor(rootURI)).sendRequest(requestType, request) } else { @@ -477,7 +477,7 @@ function xrefs({ }: { doc: sourcegraph.TextDocument pos: sourcegraph.Position - sendRequest: SendRequest + sendRequest: SendRequest }): Observable { const candidates = (async () => { const definitions = (await sendRequest({ @@ -565,10 +565,111 @@ function positionParams(doc: sourcegraph.TextDocument, pos: sourcegraph.Position } } +/** + * Automatically registers/deregisters a provider based on the given predicate of the settings. + */ +function registerWhile({ + register, + settingsPredicate, + settings, +}: { + register: () => sourcegraph.Unsubscribable + settingsPredicate: (settings: Settings) => boolean + settings: Observable +}): sourcegraph.Unsubscribable { + let registration: sourcegraph.Unsubscribable | undefined + return from(settings) + .pipe( + map(settingsPredicate), + distinctUntilChanged(), + map(enabled => { + if (enabled) { + registration = register() + } else { + if (registration) { + registration.unsubscribe() + registration = undefined + } + } + }), + finalize(() => { + if (registration) { + registration.unsubscribe() + registration = undefined + } + }) + ) + .subscribe() +} + +function registerExternalReferences({ + ctx, + sendRequest, + settings, +}: { + ctx: sourcegraph.ExtensionContext + sendRequest: SendRequest + settings: Observable +}): void { + ctx.subscriptions.add( + registerWhile({ + register: () => + sourcegraph.languages.registerReferenceProvider([{ pattern: '*.go' }], { + provideReferences: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => + xrefs({ + doc, + pos, + sendRequest, + }).pipe( + scan((acc: XRef[], curr: XRef) => [...acc, curr], [] as XRef[]), + map(response => convert.xreferences({ references: response })) + ), + }), + settingsPredicate: settings => Boolean(settings['go.showExternalReferences']), + settings, + }) + ) +} + +function registerImplementations({ + ctx, + sendRequest, +}: { + ctx: sourcegraph.ExtensionContext + sendRequest: SendRequest +}): void { + // Implementations panel. + const IMPL_ID = 'go.impl' // implementations panel and provider ID + ctx.subscriptions.add( + sourcegraph.languages.registerLocationProvider(IMPL_ID, [{ pattern: '*.go' }], { + provideLocations: async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => { + const response = await sendRequest({ + rootURI: rootURIFromDoc(doc), + requestType: lsp.ImplementationRequest.type, + request: positionParams(doc, pos), + useCache: true, + }) + return convert.references({ currentDocURI: doc.uri, references: response }) + }, + }) + ) + const panelView = sourcegraph.app.createPanelView(IMPL_ID) + panelView.title = 'Go ifaces/impls' + panelView.component = { locationProvider: IMPL_ID } + panelView.priority = 160 + ctx.subscriptions.add(panelView) +} + /** * Uses WebSockets to communicate with a language server. */ export async function initLSP(ctx: sourcegraph.ExtensionContext) { + const settings: BehaviorSubject = new BehaviorSubject({}) + ctx.subscriptions.add( + sourcegraph.configuration.subscribe(() => { + settings.next(sourcegraph.configuration.get().value) + }) + ) const accessToken = await getOrTryToCreateAccessToken() const langserverAddress = sourcegraph.configuration.get().get('go.serverUrl') if (!langserverAddress) { @@ -579,137 +680,50 @@ export async function initLSP(ctx: sourcegraph.ExtensionContext) { } } - const unsubscribableSendRequest = mkSendRequest(langserverAddress, accessToken) - const sendRequest = unsubscribableSendRequest.sendRequest + const unsubscribableSendRequest = mkSendRequest(langserverAddress, accessToken) + const sendRequest = (...args: Parameters): Promise => unsubscribableSendRequest.sendRequest(...args) ctx.subscriptions.add(unsubscribableSendRequest) - const sendDocPositionRequest = ({ - doc, - pos, - ty, - useCache, - }: { - doc: sourcegraph.TextDocument - pos: sourcegraph.Position - ty: any - useCache: boolean - }): Promise => - sendRequest({ - rootURI: rootURIFromDoc(doc), - requestType: ty, - request: positionParams(doc, pos), - useCache, - }) - const hover = async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => convert.hover( - await sendDocPositionRequest({ - doc, - pos, - ty: lsp.HoverRequest.type, + await sendRequest({ + rootURI: rootURIFromDoc(doc), + requestType: lsp.HoverRequest.type, + request: positionParams(doc, pos), useCache: true, }) ) + const definition = async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => convert.xdefinition({ currentDocURI: doc.uri, - xdefinition: await sendDocPositionRequest({ - doc, - pos, - ty: new lsp.RequestType('textDocument/xdefinition') as any, + xdefinition: await sendRequest({ + rootURI: rootURIFromDoc(doc), + requestType: new lsp.RequestType('textDocument/xdefinition') as any, + request: positionParams(doc, pos), useCache: true, }), }) + const references = async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => convert.references({ currentDocURI: doc.uri, - references: await sendDocPositionRequest({ - doc, - pos, - ty: lsp.ReferencesRequest.type, + references: await sendRequest({ + rootURI: rootURIFromDoc(doc), + requestType: lsp.ReferencesRequest.type, + request: positionParams(doc, pos), useCache: true, }), }) + registerExternalReferences({ ctx, sendRequest, settings }) + registerImplementations({ ctx, sendRequest }) + return { hover: wrapMaybe(hover), definition: wrapMaybe(definition), references: wrapMaybe(references), } - - // /** - // * Automatically registers/deregisters a provider based on the given predicate of the settings. - // */ - // function registerWhile({ - // register, - // settingsPredicate, - // }: { - // register: () => sourcegraph.Unsubscribable - // settingsPredicate: (settings: Settings) => boolean - // }): sourcegraph.Unsubscribable { - // let registration: sourcegraph.Unsubscribable | undefined - // return from(settings) - // .pipe( - // map(settingsPredicate), - // distinctUntilChanged(), - // map(enabled => { - // if (enabled) { - // registration = register() - // } else { - // if (registration) { - // registration.unsubscribe() - // registration = undefined - // } - // } - // }), - // finalize(() => { - // if (registration) { - // registration.unsubscribe() - // registration = undefined - // } - // }) - // ) - // .subscribe() - // } - - // ctx.subscriptions.add( - // registerWhile({ - // register: () => - // sourcegraph.languages.registerReferenceProvider([{ pattern: '*.go' }], { - // provideReferences: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => - // xrefs({ - // doc, - // pos, - // sendRequest, - // }).pipe( - // scan((acc: XRef[], curr: XRef) => [...acc, curr], [] as XRef[]), - // map(response => convert.xreferences({ references: response })) - // ), - // }), - // settingsPredicate: settings => Boolean(settings['go.showExternalReferences']), - // }) - // ) - - // // Implementations panel. - // const IMPL_ID = 'go.impl' // implementations panel and provider ID - // ctx.subscriptions.add( - // sourcegraph.languages.registerLocationProvider(IMPL_ID, [{ pattern: '*.go' }], { - // provideLocations: async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => { - // const response = await sendDocPositionRequest({ - // doc, - // pos, - // ty: lsp.ImplementationRequest.type, - // useCache: true, - // }) - // return convert.references({ currentDocURI: doc.uri, references: response }) - // }, - // }) - // ) - // const panelView = sourcegraph.app.createPanelView(IMPL_ID) - // panelView.title = 'Go ifaces/impls' - // panelView.component = { locationProvider: IMPL_ID } - // panelView.priority = 160 - // ctx.subscriptions.add(panelView) } function pathname(url: string): string { From 1581586cefa0f273bd96b338006c4a6b3e383bdd Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 22:58:41 -0600 Subject: [PATCH 5/8] 7.0.1 --- package.json | 2 +- yarn.lock | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f52d7aa..64a0168 100644 --- a/package.json +++ b/package.json @@ -153,7 +153,7 @@ "typescript": "^3.1.6" }, "dependencies": { - "@sourcegraph/basic-code-intel": "7.0.0", + "@sourcegraph/basic-code-intel": "7.0.1", "@sourcegraph/vscode-ws-jsonrpc": "0.0.3-fork", "prettier": "^1.16.4", "rxjs": "^6.3.3", diff --git a/yarn.lock b/yarn.lock index 3c10a39..927d51b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -700,14 +700,15 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== -"@sourcegraph/basic-code-intel@6.0.18": - version "6.0.18" - resolved "https://registry.yarnpkg.com/@sourcegraph/basic-code-intel/-/basic-code-intel-6.0.18.tgz#ca8a658213bab7295b98619af5623c51d39b6ea8" - integrity sha512-PE9mWg/HNBesShKZrILVtxF2VQjtQ9nV9DHECvqqiJ70savcRphcpAmdpPICFvqh5GxYUIoRo3AkzdPGI0DUjw== +"@sourcegraph/basic-code-intel@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@sourcegraph/basic-code-intel/-/basic-code-intel-7.0.1.tgz#149d3551ad30e4249ecbb51786f8799d67e91ae3" + integrity sha512-DYUWZbCL8Hnp54FL1zrHBAv77SrtPuh3pY5yXaOpmebwSMZt3SiAiy0xhAJaPIS8zK7Pga9o9RQh9axUPUsb7g== dependencies: lodash "^4.17.11" rxjs "^6.3.3" sourcegraph "^23.0.0" + vscode-languageserver-types "^3.14.0" "@sourcegraph/prettierrc@^3.0.0": version "3.0.0" @@ -5727,7 +5728,7 @@ vscode-languageserver-protocol@^3.14.1: vscode-jsonrpc "^4.0.0" vscode-languageserver-types "3.14.0" -vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.12.0: +vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.12.0, vscode-languageserver-types@^3.14.0: version "3.14.0" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== From 6c4bbfbd2e2b20df5fad282250c212a758a470e9 Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 23:07:50 -0600 Subject: [PATCH 6/8] prettier --- src/lang-go.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lang-go.ts b/src/lang-go.ts index 204d970..9f73387 100644 --- a/src/lang-go.ts +++ b/src/lang-go.ts @@ -288,7 +288,10 @@ function repoNameFromDoc(doc: sourcegraph.TextDocument): string { * Internally, this maintains a mapping from rootURI to the connection * associated with that rootURI, so it supports multiple roots (untested). */ -function mkSendRequest(address: string, token: string | undefined): { sendRequest: SendRequest } & Unsubscribable { +function mkSendRequest( + address: string, + token: string | undefined +): { sendRequest: SendRequest } & Unsubscribable { const rootURIToConnection: { [rootURI: string]: Promise } = {} async function connectionFor(root: URL): Promise { if (rootURIToConnection[root.href]) { @@ -681,7 +684,8 @@ export async function initLSP(ctx: sourcegraph.ExtensionContext) { } const unsubscribableSendRequest = mkSendRequest(langserverAddress, accessToken) - const sendRequest = (...args: Parameters): Promise => unsubscribableSendRequest.sendRequest(...args) + const sendRequest = (...args: Parameters): Promise => + unsubscribableSendRequest.sendRequest(...args) ctx.subscriptions.add(unsubscribableSendRequest) const hover = async (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => From cdf50e55d7e5e02a215d1045df17fa57bb6ae94a Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 23:16:58 -0600 Subject: [PATCH 7/8] linter --- src/lang-go.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/lang-go.ts b/src/lang-go.ts index 9f73387..3a22044 100644 --- a/src/lang-go.ts +++ b/src/lang-go.ts @@ -27,7 +27,9 @@ import { import { ConsoleLogger, createWebSocketConnection } from '@sourcegraph/vscode-ws-jsonrpc' import gql from 'tagged-template-noop' import { Settings } from './settings' -import { asyncFirst, wrapMaybe, when } from '@sourcegraph/basic-code-intel/lib/lsif' +// This is the (temporarily) intended usage. +// tslint:disable-next-line: no-submodule-imports +import { asyncFirst, wrapMaybe, Maybe } from '@sourcegraph/basic-code-intel/lib/lsif' // If we can rid ourselves of file:// URIs, this type won't be necessary and we // can use lspext.Xreference directly. @@ -663,10 +665,28 @@ function registerImplementations({ ctx.subscriptions.add(panelView) } +interface MaybeProviders { + hover: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => Promise> + definition: ( + doc: sourcegraph.TextDocument, + pos: sourcegraph.Position + ) => Promise> + references: ( + doc: sourcegraph.TextDocument, + pos: sourcegraph.Position + ) => Promise> +} + +interface Providers { + hover: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => Promise + definition: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => Promise + references: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => Promise +} + /** * Uses WebSockets to communicate with a language server. */ -export async function initLSP(ctx: sourcegraph.ExtensionContext) { +export async function initLSP(ctx: sourcegraph.ExtensionContext): Promise { const settings: BehaviorSubject = new BehaviorSubject({}) ctx.subscriptions.add( sourcegraph.configuration.subscribe(() => { @@ -737,7 +757,7 @@ function pathname(url: string): string { return pathname } -function initBasicCodeIntel() { +function initBasicCodeIntel(): Providers { const handler = new Handler({ sourcegraph, languageID: 'go', From 6c2faaabe14623d0ce8ed2b78bd9748399043487 Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Fri, 19 Jul 2019 23:41:53 -0600 Subject: [PATCH 8/8] Catch error initializing LSP --- src/lang-go.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/lang-go.ts b/src/lang-go.ts index 3a22044..2ef34fa 100644 --- a/src/lang-go.ts +++ b/src/lang-go.ts @@ -683,6 +683,12 @@ interface Providers { references: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => Promise } +const noopMaybeProviders = { + hover: () => Promise.resolve(undefined), + definition: () => Promise.resolve(undefined), + references: () => Promise.resolve(undefined), +} + /** * Uses WebSockets to communicate with a language server. */ @@ -696,11 +702,7 @@ export async function initLSP(ctx: sourcegraph.ExtensionContext): Promise().get('go.serverUrl') if (!langserverAddress) { - return { - hover: () => Promise.resolve(undefined), - definition: () => Promise.resolve(undefined), - references: () => Promise.resolve(undefined), - } + return noopMaybeProviders } const unsubscribableSendRequest = mkSendRequest(langserverAddress, accessToken) @@ -803,7 +805,7 @@ const goFiles = [{ pattern: '*.go' }] export function activate(ctx: sourcegraph.ExtensionContext = DUMMY_CTX): void { async function afterActivate(): Promise { const lsif = initLSIF() - const lsp = await initLSP(ctx) + const lsp = await initLSP(ctx).catch(() => noopMaybeProviders) const basicCodeIntel = initBasicCodeIntel() ctx.subscriptions.add(