Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/src/common/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,7 @@ export abstract class BaseLanguageClient implements FeatureClient<Middleware, La
const params = this.code2ProtocolConverter.asChangeTextDocumentParams(document);
// We await the send and not the delivery since it is more or less the same for
// notifications.
this._didChangeTextDocumentFeature!.aboutToSendNotification(document, DidChangeTextDocumentNotification.type, params);
await connection.sendNotification(DidChangeTextDocumentNotification.type, params);
this._didChangeTextDocumentFeature!.notificationSent(document, DidChangeTextDocumentNotification.type, params);
}
Expand Down
8 changes: 5 additions & 3 deletions client/src/common/diagnostic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ class DiagnosticRequestor implements Disposable {
return { kind: vsdiag.DocumentDiagnosticReportKind.full, items: [] };
}
if (token.isCancellationRequested) {
throw new CancellationError()
throw new CancellationError();
}
if (result === undefined || result === null) {
return { kind: vsdiag.DocumentDiagnosticReportKind.full, items: [] };
Expand Down Expand Up @@ -1025,9 +1025,11 @@ class DiagnosticFeatureProviderImpl implements DiagnosticProviderShape {
}));
}

// When the document closes clear things up
// When the document closes clear things up. We do that right before the
// close notification is sent to the server so that it is not taken
// from the pull queue in case it is still there.
const closeFeature = client.getFeature(DidCloseTextDocumentNotification.method);
disposables.push(closeFeature.onNotificationSent((event) => {
disposables.push(closeFeature.onAboutToSendNotification((event) => {
this.cleanUpDocument(event.textDocument);
}));
disposables.push(notebookFeature.onCloseNotificationSent((event) => {
Expand Down
39 changes: 32 additions & 7 deletions client/src/common/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,27 @@ interface CreateParamsSignature<E, P> {
(data: E): RequestParam<P>;
}

export interface NotificationSendEvent<P extends { textDocument: TextDocumentIdentifier }> {
interface NotificationEvent<P extends { textDocument: TextDocumentIdentifier }> {
textDocument: TextDocument;
type: ProtocolNotificationType<P, TextDocumentRegistrationOptions>;
params: RequestParam<P>;
}

export interface AboutToSendNotificationEvent<P extends { textDocument: TextDocumentIdentifier }> extends NotificationEvent<P> {
}

export interface NotificationSentEvent<P extends { textDocument: TextDocumentIdentifier }> extends NotificationEvent<P> {
}

/**
* @deprecated Use `NotificationSentEvent` instead.
*/
export interface NotificationSendEvent<P extends { textDocument: TextDocumentIdentifier }> extends NotificationSentEvent<P> {
}

export interface NotifyingFeature<P extends { textDocument: TextDocumentIdentifier }> {
onNotificationSent: VEvent<NotificationSendEvent<P>>;
onAboutToSendNotification: VEvent<AboutToSendNotificationEvent<P>>;
onNotificationSent: VEvent<NotificationSentEvent<P>>;
}

/**
Expand Down Expand Up @@ -340,7 +353,8 @@ export abstract class TextDocumentEventFeature<P extends { textDocument: TextDoc

private _listener: Disposable | undefined;
protected readonly _selectors: Map<string, VDocumentSelector>;
private _onNotificationSent: EventEmitter<NotificationSendEvent<P>>;
private _onAboutToSendNotification: EventEmitter<AboutToSendNotificationEvent<P>>;
private _onNotificationSent: EventEmitter<NotificationSentEvent<P>>;

public static textDocumentFilter(selectors: IterableIterator<VDocumentSelector>, textDocument: TextDocument): boolean {
for (const selector of selectors) {
Expand All @@ -365,7 +379,8 @@ export abstract class TextDocumentEventFeature<P extends { textDocument: TextDoc
this._selectorFilter = selectorFilter;

this._selectors = new Map<string, VDocumentSelector>();
this._onNotificationSent = new EventEmitter<NotificationSendEvent<P>>();
this._onAboutToSendNotification = new EventEmitter<AboutToSendNotificationEvent<P>>();
this._onNotificationSent = new EventEmitter<NotificationSentEvent<P>>();
}

protected getStateInfo(): [IterableIterator<VDocumentSelector>, boolean] {
Expand All @@ -392,9 +407,11 @@ export abstract class TextDocumentEventFeature<P extends { textDocument: TextDoc

protected async callback(data: E): Promise<void> {
const doSend = async (data: E): Promise<void> => {
const textDocument = this.getTextDocument(data);
const params = this._createParams(data);
this.aboutToSendNotification(textDocument, this._type, params);
await this._client.sendNotification(this._type, params);
this.notificationSent(this.getTextDocument(data), this._type, params);
this.notificationSent(textDocument, this._type, params);
};
if (this.matches(data)) {
const middleware = this._middleware();
Expand All @@ -409,7 +426,15 @@ export abstract class TextDocumentEventFeature<P extends { textDocument: TextDoc
return !this._selectorFilter || this._selectorFilter(this._selectors.values(), data);
}

public get onNotificationSent(): VEvent<NotificationSendEvent<P>> {
public get onAboutToSendNotification(): VEvent<AboutToSendNotificationEvent<P>> {
return this._onAboutToSendNotification.event;
}

protected aboutToSendNotification(textDocument: TextDocument, type: ProtocolNotificationType<P, TextDocumentRegistrationOptions>, params: RequestParam<P>): void {
this._onAboutToSendNotification.fire({ textDocument, type, params });
}

public get onNotificationSent(): VEvent<NotificationSentEvent<P>> {
return this._onNotificationSent.event;
}

Expand All @@ -430,7 +455,7 @@ export abstract class TextDocumentEventFeature<P extends { textDocument: TextDoc
public clear(): void {
this._selectors.clear();
this._onNotificationSent.dispose();
this._onNotificationSent = new EventEmitter<NotificationSendEvent<P>>();
this._onNotificationSent = new EventEmitter<NotificationSentEvent<P>>();
if (this._listener) {
this._listener.dispose();
this._listener = undefined;
Expand Down
17 changes: 14 additions & 3 deletions client/src/common/textSynchronization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {

import {
FeatureClient, TextDocumentEventFeature, DynamicFeature, NextSignature, TextDocumentSendFeature, NotifyingFeature, ensure, RegistrationData, DynamicDocumentFeature,
NotificationSendEvent
NotificationSentEvent, AboutToSendNotificationEvent
} from './features';

import * as UUID from './utils/uuid';
Expand Down Expand Up @@ -288,21 +288,27 @@ export class DidChangeTextDocumentFeature extends DynamicDocumentFeature<TextDoc

private _listener: Disposable | undefined;
private readonly _changeData: Map<string, DidChangeTextDocumentData>;
private readonly _onNotificationSent: EventEmitter<NotificationSendEvent<DidChangeTextDocumentParams>>;
private readonly _onAboutToSendNotification: EventEmitter<AboutToSendNotificationEvent<DidChangeTextDocumentParams>>;
private readonly _onNotificationSent: EventEmitter<NotificationSentEvent<DidChangeTextDocumentParams>>;
private readonly _onPendingChangeAdded: EventEmitter<void>;
private readonly _pendingTextDocumentChanges: Map<string, TextDocument>;
private _syncKind: TextDocumentSyncKind;

constructor(client: FeatureClient<TextDocumentSynchronizationMiddleware>, pendingTextDocumentChanges: Map<string, TextDocument>) {
super(client);
this._changeData = new Map<string, DidChangeTextDocumentData>();
this._onAboutToSendNotification = new EventEmitter();
this._onNotificationSent = new EventEmitter();
this._onPendingChangeAdded = new EventEmitter();
this._pendingTextDocumentChanges = pendingTextDocumentChanges;
this._syncKind = TextDocumentSyncKind.None;
}

public get onNotificationSent(): Event<NotificationSendEvent<DidChangeTextDocumentParams>> {
public get onAboutToSendNotification(): Event<AboutToSendNotificationEvent<DidChangeTextDocumentParams>> {
return this._onAboutToSendNotification.event;
}

public get onNotificationSent(): Event<NotificationSentEvent<DidChangeTextDocumentParams>> {
return this._onNotificationSent.event;
}

Expand Down Expand Up @@ -375,6 +381,7 @@ export class DidChangeTextDocumentFeature extends DynamicDocumentFeature<TextDoc
if (changeData.syncKind === TextDocumentSyncKind.Incremental) {
const didChange = async (event: TextDocumentChangeEvent): Promise<void> => {
const params = this._client.code2ProtocolConverter.asChangeTextDocumentParams(event, uri, version);
this.aboutToSendNotification(event.document, DidChangeTextDocumentNotification.type, params);
await this._client.sendNotification(DidChangeTextDocumentNotification.type, params);
this.notificationSent(event.document, DidChangeTextDocumentNotification.type, params);
};
Expand All @@ -395,6 +402,10 @@ export class DidChangeTextDocumentFeature extends DynamicDocumentFeature<TextDoc
});
}

public aboutToSendNotification(textDocument: TextDocument, type: ProtocolNotificationType<DidChangeTextDocumentParams, TextDocumentRegistrationOptions>, params: DidChangeTextDocumentParams): void {
this._onAboutToSendNotification.fire({ textDocument, type, params });
}

public notificationSent(textDocument: TextDocument, type: ProtocolNotificationType<DidChangeTextDocumentParams, TextDocumentRegistrationOptions>, params: DidChangeTextDocumentParams): void {
this._onNotificationSent.fire({ textDocument, type, params });
}
Expand Down