Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/inlineEdits/vscode-node/parts/verifyTextDocumentChanges.ts
13405 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { EndOfLine, TextDocument, TextDocumentChangeEvent, workspace } from 'vscode';
7
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry';
8
import { Disposable } from '../../../../util/vs/base/common/lifecycle';
9
import { editFromTextDocumentContentChangeEvents } from './common';
10
11
/**
12
* Verifies that VS Code content change API reports consistent document edits.
13
* Tracks document states and verifies that applying reported edits to the previous state
14
* produces the new document state. Reports mismatches via telemetry.
15
*/
16
export class VerifyTextDocumentChanges extends Disposable {
17
private readonly _documentStates = new Map<string, { text: string; linefeed: EndOfLine }>();
18
19
constructor(
20
@ITelemetryService private readonly _telemetryService: ITelemetryService
21
) {
22
super();
23
24
// This comes from telemetry
25
const allowedSchemes = new Set([
26
'file',
27
'vscode-notebook-cell',
28
'untitled',
29
// "vscode-local",
30
// "vscode-chat-code-block",
31
// "chat-editing-text-model",
32
// "embedded-html",
33
// "vscode-userdata",
34
// "vscode-remote",
35
// "git",
36
]);
37
function shouldVerifyDoc(doc: TextDocument): boolean {
38
return allowedSchemes.has(doc.uri.scheme);
39
}
40
41
this._register(workspace.onDidOpenTextDocument(doc => {
42
if (!shouldVerifyDoc(doc)) {
43
return;
44
}
45
const docUri = doc.uri.toString();
46
this._documentStates.set(docUri, { text: doc.getText(), linefeed: doc.eol });
47
}));
48
49
this._register(workspace.onDidCloseTextDocument(doc => {
50
if (!shouldVerifyDoc(doc)) {
51
return;
52
}
53
const docUri = doc.uri.toString();
54
this._documentStates.delete(docUri);
55
}));
56
57
workspace.textDocuments.forEach(doc => {
58
if (!shouldVerifyDoc(doc)) {
59
return;
60
}
61
const docUri = doc.uri.toString();
62
this._documentStates.set(docUri, { text: doc.getText(), linefeed: doc.eol });
63
});
64
65
this._register(workspace.onDidChangeTextDocument(e => {
66
if (!shouldVerifyDoc(e.document)) {
67
return;
68
}
69
this._verifyDocumentStateConsistency(e);
70
}));
71
}
72
73
private _verifyDocumentStateConsistency(e: TextDocumentChangeEvent): void {
74
const docUri = e.document.uri.toString();
75
const currentText = e.document.getText();
76
const previousValue = this._documentStates.get(docUri);
77
78
if (previousValue === undefined) {
79
/* __GDPR__
80
"vscode.contentChangeForUnknownDocument" : {
81
"owner": "hediet",
82
"comment": "Telemetry for verifying VSCode content change API consistency"
83
}
84
*/
85
this._telemetryService.sendMSFTTelemetryEvent('vscode.contentChangeForUnknownDocument', {}, {});
86
return;
87
}
88
89
this._documentStates.set(docUri, { text: currentText, linefeed: e.document.eol });
90
91
const edit = editFromTextDocumentContentChangeEvents(e.contentChanges);
92
const expectedText = edit.apply(previousValue.text);
93
94
if (expectedText !== currentText) {
95
/* __GDPR__
96
"vscode.contentChangeInconsistencyDetected" : {
97
"owner": "hediet",
98
"comment": "Telemetry for verifying VSCode content change API consistency",
99
"languageId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Language of the currently open document." },
100
"sourceOfChange": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Source of the change." },
101
"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Reason for change (1 = undo, 2 = redo).", "isMeasurement": true },
102
"previousLineFeed": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Line feed of the previously open document.", "isMeasurement": true },
103
"currentLineFeed": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Line feed of the currently open document.", "isMeasurement": true },
104
"scheme": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Scheme of the currently open document." }
105
}
106
*/
107
this._telemetryService.sendMSFTTelemetryEvent('vscode.contentChangeInconsistencyDetected', {
108
languageId: e.document.languageId,
109
scheme: e.document.uri.scheme,
110
sourceOfChange: e.detailedReason?.source || '',
111
}, {
112
reason: e.reason,
113
previousLineFeed: previousValue.linefeed,
114
currentLineFeed: e.document.eol,
115
});
116
}
117
}
118
}
119
120