vscode-languageclient
Advanced tools
Comparing version 8.0.2-next.5 to 8.0.2
@@ -11,3 +11,3 @@ import { FileSystemWatcher as VFileSystemWatcher, WorkspaceFolder as VWorkspaceFolder } from 'vscode'; | ||
/** | ||
* Configuration pull model. Form server to client. | ||
* Configuration pull model. From server to client. | ||
*/ | ||
@@ -14,0 +14,0 @@ export declare class ConfigurationFeature implements StaticFeature { |
@@ -14,3 +14,3 @@ "use strict"; | ||
/** | ||
* Configuration pull model. Form server to client. | ||
* Configuration pull model. From server to client. | ||
*/ | ||
@@ -17,0 +17,0 @@ class ConfigurationFeature { |
@@ -80,3 +80,3 @@ import { Disposable, CancellationToken, ProviderResult, Diagnostic as VDiagnostic, TextDocument, Event as VEvent, EventEmitter, Uri } from 'vscode'; | ||
* | ||
* @param document the document that changes or got save | ||
* @param document the document that changed or got saved | ||
* @param mode the mode | ||
@@ -94,7 +94,7 @@ */ | ||
/** | ||
* A optional match method that is consulted when pulling for diagnostics | ||
* An optional match method that is consulted when pulling for diagnostics | ||
* when only a URI is known (e.g. for not instantiated tabs) | ||
* | ||
* @param documentSelector the document selector | ||
* @param resource the resource. | ||
* @param resource the resource | ||
*/ | ||
@@ -101,0 +101,0 @@ match?(documentSelector: DocumentSelector, resource: Uri): boolean; |
@@ -38,20 +38,46 @@ "use strict"; | ||
})(RequestStateKind || (RequestStateKind = {})); | ||
/** | ||
* Manages the open tabs. We don't directly use the tab API since for | ||
* diagnostics we need to de-dupe tabs that show the same resources since | ||
* we pull on the model not the UI. | ||
*/ | ||
class Tabs { | ||
constructor() { | ||
this.open = new Set(); | ||
const openTabsHandler = () => { | ||
this.open.clear(); | ||
for (const group of vscode_1.window.tabGroups.all) { | ||
for (const tab of group.tabs) { | ||
const input = tab.input; | ||
if (input instanceof vscode_1.TabInputText) { | ||
this.open.add(input.uri.toString()); | ||
} | ||
else if (input instanceof vscode_1.TabInputTextDiff) { | ||
this.open.add(input.modified.toString()); | ||
} | ||
this._onOpen = new vscode_1.EventEmitter(); | ||
this._onClose = new vscode_1.EventEmitter(); | ||
Tabs.fillTabResources(this.open); | ||
const openTabsHandler = (event) => { | ||
if (event.closed.length === 0 && event.opened.length === 0) { | ||
return; | ||
} | ||
const oldTabs = this.open; | ||
const currentTabs = new Set(); | ||
Tabs.fillTabResources(currentTabs); | ||
const closed = new Set(); | ||
const opened = new Set(currentTabs); | ||
for (const tab of oldTabs.values()) { | ||
if (currentTabs.has(tab)) { | ||
opened.delete(tab); | ||
} | ||
else { | ||
closed.add(tab); | ||
} | ||
} | ||
this.open = currentTabs; | ||
if (closed.size > 0) { | ||
const toFire = new Set(); | ||
for (const item of closed) { | ||
toFire.add(vscode_1.Uri.parse(item)); | ||
} | ||
this._onClose.fire(toFire); | ||
} | ||
if (opened.size > 0) { | ||
const toFire = new Set(); | ||
for (const item of opened) { | ||
toFire.add(vscode_1.Uri.parse(item)); | ||
} | ||
this._onOpen.fire(toFire); | ||
} | ||
}; | ||
openTabsHandler(); | ||
if (vscode_1.window.tabGroups.onDidChangeTabs !== undefined) { | ||
@@ -64,2 +90,8 @@ this.disposable = vscode_1.window.tabGroups.onDidChangeTabs(openTabsHandler); | ||
} | ||
get onClose() { | ||
return this._onClose.event; | ||
} | ||
get onOpen() { | ||
return this._onOpen.event; | ||
} | ||
dispose() { | ||
@@ -78,15 +110,24 @@ this.disposable.dispose(); | ||
getTabResources() { | ||
const result = []; | ||
const result = new Set(); | ||
Tabs.fillTabResources(new Set(), result); | ||
return result; | ||
} | ||
static fillTabResources(strings, uris) { | ||
const seen = strings ?? new Set(); | ||
for (const group of vscode_1.window.tabGroups.all) { | ||
for (const tab of group.tabs) { | ||
const input = tab.input; | ||
let uri; | ||
if (input instanceof vscode_1.TabInputText) { | ||
result.push(input.uri); | ||
uri = input.uri; | ||
} | ||
else if (input instanceof vscode_1.TabInputTextDiff) { | ||
result.push(input.modified); | ||
uri = input.modified; | ||
} | ||
if (uri !== undefined && !seen.has(uri.toString())) { | ||
seen.add(uri.toString()); | ||
uris !== undefined && uris.add(uri); | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
@@ -172,5 +213,8 @@ } | ||
} | ||
knows(kind, textDocument) { | ||
return this.documentStates.tracks(kind, textDocument); | ||
knows(kind, document) { | ||
return this.documentStates.tracks(kind, document); | ||
} | ||
forget(kind, document) { | ||
this.documentStates.unTrack(kind, document); | ||
} | ||
pull(document, cb) { | ||
@@ -258,7 +302,9 @@ if (this.isDisposed) { | ||
} | ||
cleanupPull(document) { | ||
forgetDocument(document) { | ||
const uri = document instanceof vscode_1.Uri ? document : document.uri; | ||
const key = uri.toString(); | ||
const request = this.openRequests.get(key); | ||
if (this.options.workspaceDiagnostics || this.options.interFileDependencies) { | ||
if (this.options.workspaceDiagnostics) { | ||
// If we run workspace diagnostic pull a last time for the diagnostics | ||
// and the rely on getting them from the workspace result. | ||
if (request !== undefined) { | ||
@@ -268,6 +314,11 @@ this.openRequests.set(key, { state: RequestStateKind.reschedule, document: document }); | ||
else { | ||
this.pull(document); | ||
this.pull(document, () => { | ||
this.forget(PullState.document, document); | ||
}); | ||
} | ||
} | ||
else { | ||
// We have normal pull or inter file dependencies. In this case we | ||
// clear the diagnostics (to have the same start as after startup). | ||
// We also cancel outstanding requests. | ||
if (request !== undefined) { | ||
@@ -280,2 +331,3 @@ if (request.state === RequestStateKind.active) { | ||
this.diagnostics.delete(uri); | ||
this.forget(PullState.document, document); | ||
} | ||
@@ -598,2 +650,8 @@ } | ||
}); | ||
// For pull model diagnostics we pull for documents visible in the UI. | ||
// From an eventing point of view we still rely on open document events | ||
// and filter the documents that are not visible in the UI instead of | ||
// listening to Tab events. Major reason is event timing since we need | ||
// to ensure that the pull is send after the document open has reached | ||
// the server. | ||
// We always pull on open. | ||
@@ -608,13 +666,13 @@ const openFeature = client.getFeature(vscode_languageserver_protocol_1.DidOpenTextDocumentNotification.method); | ||
// Pull all diagnostics for documents that are already open | ||
const pullTextDocuments = new Set(); | ||
const pulledTextDocuments = new Set(); | ||
for (const textDocument of vscode_1.workspace.textDocuments) { | ||
if (matches(textDocument)) { | ||
this.diagnosticRequestor.pull(textDocument, () => { addToBackgroundIfNeeded(textDocument); }); | ||
pullTextDocuments.add(textDocument.uri.toString()); | ||
pulledTextDocuments.add(textDocument.uri.toString()); | ||
} | ||
} | ||
// Pull all tabs if not already pull as text document | ||
// Pull all tabs if not already pulled as text document | ||
if (diagnosticPullOptions.onTabs === true) { | ||
for (const resource of tabs.getTabResources()) { | ||
if (!pullTextDocuments.has(resource.toString()) && matches(resource)) { | ||
if (!pulledTextDocuments.has(resource.toString()) && matches(resource)) { | ||
this.diagnosticRequestor.pull(resource, () => { addToBackgroundIfNeeded(resource); }); | ||
@@ -624,2 +682,9 @@ } | ||
} | ||
tabs.onOpen((opened) => { | ||
for (const document of opened) { | ||
if (matches(document) && !this.diagnosticRequestor.knows(PullState.document, document)) { | ||
this.diagnosticRequestor.pull(document, () => { addToBackgroundIfNeeded(document); }); | ||
} | ||
} | ||
}); | ||
if (diagnosticPullOptions.onChange === true) { | ||
@@ -646,6 +711,10 @@ const changeFeature = client.getFeature(vscode_languageserver_protocol_1.DidChangeTextDocumentNotification.method); | ||
disposables.push(closeFeature.onNotificationSent((event) => { | ||
const textDocument = event.original; | ||
this.diagnosticRequestor.cleanupPull(textDocument); | ||
this.backgroundScheduler.remove(textDocument); | ||
this.cleanUpDocument(event.original); | ||
})); | ||
// Same when a tabs closes. | ||
tabs.onClose((closed) => { | ||
for (const document of closed) { | ||
this.cleanUpDocument(document); | ||
} | ||
}); | ||
// We received a did change from the server. | ||
@@ -671,2 +740,8 @@ this.diagnosticRequestor.onDidChangeDiagnosticsEmitter.event(() => { | ||
} | ||
cleanUpDocument(document) { | ||
if (this.diagnosticRequestor.knows(PullState.document, document)) { | ||
this.diagnosticRequestor.forgetDocument(document); | ||
this.backgroundScheduler.remove(document); | ||
} | ||
} | ||
} | ||
@@ -673,0 +748,0 @@ class DiagnosticFeature extends features_1.TextDocumentLanguageFeature { |
@@ -691,12 +691,6 @@ "use strict"; | ||
for (const item of this.options.notebookSelector) { | ||
if (item.notebook === undefined) { | ||
if (item.cells === undefined) { | ||
return undefined; | ||
} | ||
if (item.notebook === undefined || $NotebookDocumentFilter.matchNotebook(item.notebook, notebookDocument)) { | ||
const filtered = this.filterCells(notebookDocument, cells, item.cells); | ||
return filtered.length === 0 ? undefined : filtered; | ||
} | ||
else if ($NotebookDocumentFilter.matchNotebook(item.notebook, notebookDocument)) { | ||
return item.cells === undefined ? cells : this.filterCells(notebookDocument, cells, item.cells); | ||
} | ||
} | ||
@@ -710,9 +704,9 @@ return undefined; | ||
filterCells(notebookDocument, cells, cellSelector) { | ||
const result = cells.filter((cell) => { | ||
const filtered = cellSelector !== undefined ? cells.filter((cell) => { | ||
const cellLanguage = cell.document.languageId; | ||
return cellSelector.some((filter => (filter.language === '*' || cellLanguage === filter.language))); | ||
}); | ||
}) : cells; | ||
return typeof this.client.clientOptions.notebookDocumentOptions?.filterCells === 'function' | ||
? this.client.clientOptions.notebookDocumentOptions.filterCells(notebookDocument, cells) | ||
: result; | ||
? this.client.clientOptions.notebookDocumentOptions.filterCells(notebookDocument, filtered) | ||
: filtered; | ||
} | ||
@@ -719,0 +713,0 @@ } |
@@ -26,2 +26,4 @@ import { CancellationToken } from 'vscode'; | ||
} | ||
export declare function setTestMode(): void; | ||
export declare function clearTestMode(): void; | ||
export declare type YieldOptions = { | ||
@@ -28,0 +30,0 @@ /** |
@@ -7,3 +7,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.forEach = exports.mapAsync = exports.map = exports.Semaphore = exports.Delayer = void 0; | ||
exports.forEach = exports.mapAsync = exports.map = exports.clearTestMode = exports.setTestMode = exports.Semaphore = exports.Delayer = void 0; | ||
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol"); | ||
@@ -128,6 +128,15 @@ class Delayer { | ||
exports.Semaphore = Semaphore; | ||
let $test = false; | ||
function setTestMode() { | ||
$test = true; | ||
} | ||
exports.setTestMode = setTestMode; | ||
function clearTestMode() { | ||
$test = false; | ||
} | ||
exports.clearTestMode = clearTestMode; | ||
const defaultYieldTimeout = 15 /*ms*/; | ||
class Timer { | ||
constructor(yieldAfter = defaultYieldTimeout) { | ||
this.yieldAfter = Math.max(yieldAfter, defaultYieldTimeout); | ||
this.yieldAfter = $test === true ? Math.max(yieldAfter, 2) : Math.max(yieldAfter, defaultYieldTimeout); | ||
this.startTime = Date.now(); | ||
@@ -140,2 +149,5 @@ this.counter = 0; | ||
start() { | ||
this.counter = 0; | ||
this.total = 0; | ||
this.counterInterval = 1; | ||
this.startTime = Date.now(); | ||
@@ -142,0 +154,0 @@ } |
@@ -25,3 +25,2 @@ "use strict"; | ||
const path = require("path"); | ||
const SemVer = require("semver"); | ||
const vscode_1 = require("vscode"); | ||
@@ -32,2 +31,5 @@ const Is = require("../common/utils/is"); | ||
const node_1 = require("vscode-languageserver-protocol/node"); | ||
// Import SemVer functions individually to avoid circular dependencies in SemVer | ||
const semverParse = require("semver/functions/parse"); | ||
const semverSatisfies = require("semver/functions/satisfies"); | ||
__exportStar(require("vscode-languageserver-protocol/node"), exports); | ||
@@ -120,3 +122,3 @@ __exportStar(require("../common/api"), exports); | ||
checkVersion() { | ||
const codeVersion = SemVer.parse(vscode_1.version); | ||
const codeVersion = semverParse(vscode_1.version); | ||
if (!codeVersion) { | ||
@@ -129,3 +131,3 @@ throw new Error(`No valid VS Code version detected. Version string is: ${vscode_1.version}`); | ||
} | ||
if (!SemVer.satisfies(codeVersion, REQUIRED_VSCODE_VERSION)) { | ||
if (!semverSatisfies(codeVersion, REQUIRED_VSCODE_VERSION)) { | ||
throw new Error(`The language client requires VS Code version ${REQUIRED_VSCODE_VERSION} but received version ${vscode_1.version}`); | ||
@@ -132,0 +134,0 @@ } |
{ | ||
"name": "vscode-languageclient", | ||
"description": "VSCode Language client implementation", | ||
"version": "8.0.2-next.5", | ||
"version": "8.0.2", | ||
"author": "Microsoft Corporation", | ||
@@ -18,4 +18,3 @@ "license": "MIT", | ||
}, | ||
"enabledApiProposals": [ | ||
], | ||
"enabledApiProposals": [], | ||
"main": "./lib/node/main.js", | ||
@@ -35,3 +34,3 @@ "browser": { | ||
"semver": "^7.3.5", | ||
"vscode-languageserver-protocol": "3.17.2-next.6" | ||
"vscode-languageserver-protocol": "3.17.2" | ||
}, | ||
@@ -38,0 +37,0 @@ "scripts": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
640970
12519
1
+ Addedvscode-jsonrpc@8.0.2(transitive)
+ Addedvscode-languageserver-protocol@3.17.2(transitive)
+ Addedvscode-languageserver-types@3.17.2(transitive)
- Removedvscode-jsonrpc@8.0.2-next.1(transitive)
- Removedvscode-languageserver-protocol@3.17.2-next.6(transitive)
- Removedvscode-languageserver-types@3.17.2-next.2(transitive)