Re-validate md files when a linked to file is created or deleted (#152520)

This commit is contained in:
Matt Bierner 2022-06-22 12:02:46 -07:00 committed by GitHub
parent 4878dfa5a1
commit be1ee5d9f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 16 deletions

View file

@ -324,12 +324,18 @@ export class DiagnosticManager extends Disposable {
this._register(workspaceContents.onDidCreateMarkdownDocument(doc => {
this.triggerDiagnostics(doc.uri);
// Links in other files may have become valid
this.triggerForReferencingFiles(doc.uri);
}));
this._register(workspaceContents.onDidChangeMarkdownDocument(doc => {
this.triggerDiagnostics(doc.uri);
}));
this._register(workspaceContents.onDidDeleteMarkdownDocument(uri => {
this.triggerForReferencingFiles(uri);
}));
this._register(vscode.workspace.onDidCloseTextDocument(({ uri }) => {
this.pendingDiagnostics.delete(uri);
this.inFlightDiagnostics.cancel(uri);
@ -337,7 +343,6 @@ export class DiagnosticManager extends Disposable {
this.reporter.delete(uri);
}));
this._register(this.linkWatcher.onDidChangeLinkedToFile(changedDocuments => {
for (const resource of changedDocuments) {
const doc = vscode.workspace.textDocuments.find(doc => doc.uri.toString() === resource.toString());
@ -347,22 +352,28 @@ export class DiagnosticManager extends Disposable {
}
}));
this.tableOfContentsWatcher = this._register(new MdTableOfContentsWatcher(workspaceContents, tocProvider, delay));
this._register(this.tableOfContentsWatcher.onTocChanged(async e => {
// When the toc of a document changes, revalidate every file that linked to it too
const triggered = new ResourceMap<void>();
for (const ref of await this.referencesProvider.getAllReferencesToFile(e.uri, noopToken)) {
const file = ref.location.uri;
if (!triggered.has(file)) {
this.triggerDiagnostics(file);
triggered.set(file);
}
}
this.tableOfContentsWatcher = this._register(new MdTableOfContentsWatcher(workspaceContents, tocProvider, delay / 2));
this._register(this.tableOfContentsWatcher.onTocChanged(e => {
return this.triggerForReferencingFiles(e.uri);
}));
this.ready = this.rebuild();
}
private triggerForReferencingFiles(uri: vscode.Uri): Promise<void> {
return this.reporter.addWorkItem(
(async () => {
const triggered = new ResourceMap<Promise<void>>();
for (const ref of await this.referencesProvider.getAllReferencesToFile(uri, noopToken)) {
const file = ref.location.uri;
if (!triggered.has(file)) {
triggered.set(file, this.triggerDiagnostics(file));
}
}
await Promise.all(triggered.values());
})());
}
public override dispose() {
super.dispose();
this.pendingDiagnostics.clear();

View file

@ -40,7 +40,7 @@ async function getComputedDiagnostics(doc: InMemoryDocument, workspace: MdWorksp
}
function assertDiagnosticsEqual(actual: readonly vscode.Diagnostic[], expectedRanges: readonly vscode.Range[]) {
assert.strictEqual(actual.length, expectedRanges.length);
assert.strictEqual(actual.length, expectedRanges.length, "Diagnostic count equal");
for (let i = 0; i < actual.length; ++i) {
assertRangeEqual(actual[i].range, expectedRanges[i], `Range ${i} to be equal`);
@ -449,7 +449,7 @@ suite('Markdown: Diagnostics manager', () => {
tocProvider,
nulLogger,
0);
_disposables.push(manager, referencesProvider);
_disposables.push(linkProvider, tocProvider, referencesProvider, manager);
return manager;
}
@ -554,4 +554,40 @@ suite('Markdown: Diagnostics manager', () => {
new vscode.Range(2, 7, 2, 17),
]);
});
test('Should revalidate linked files when file is deleted/created', async () => {
const doc1Uri = workspacePath('doc1.md');
const doc1 = new InMemoryDocument(doc1Uri, joinLines(
`[text](/doc2.md)`,
`[text](/doc2.md#header)`,
));
const doc2Uri = workspacePath('doc2.md');
const doc2 = new InMemoryDocument(doc2Uri, joinLines(
`# Header`
));
const workspace = new InMemoryWorkspaceMarkdownDocuments([doc1, doc2]);
const reporter = new MemoryDiagnosticReporter();
const manager = createDiagnosticsManager(workspace, new MemoryDiagnosticConfiguration({}), reporter);
await manager.ready;
// Check initial state
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), []);
// Edit header
workspace.deleteDocument(doc2Uri);
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), [
new vscode.Range(0, 7, 0, 15),
new vscode.Range(1, 7, 1, 22),
]);
// Revert to original file
workspace.createDocument(doc2);
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), []);
});
});

View file

@ -5,11 +5,11 @@
import * as vscode from 'vscode';
import { MdTableOfContentsProvider, TableOfContents } from '../tableOfContents';
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
import { equals } from './arrays';
import { Delayer } from './async';
import { Disposable } from './dispose';
import { ResourceMap } from './resourceMap';
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
import { Delayer } from './async';
/**
* Check if the items in a table of contents have changed.