mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 21:55:38 +00:00
Re-validate md files when a linked to file is created or deleted (#152520)
This commit is contained in:
parent
4878dfa5a1
commit
be1ee5d9f1
|
@ -324,12 +324,18 @@ export class DiagnosticManager extends Disposable {
|
||||||
|
|
||||||
this._register(workspaceContents.onDidCreateMarkdownDocument(doc => {
|
this._register(workspaceContents.onDidCreateMarkdownDocument(doc => {
|
||||||
this.triggerDiagnostics(doc.uri);
|
this.triggerDiagnostics(doc.uri);
|
||||||
|
// Links in other files may have become valid
|
||||||
|
this.triggerForReferencingFiles(doc.uri);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._register(workspaceContents.onDidChangeMarkdownDocument(doc => {
|
this._register(workspaceContents.onDidChangeMarkdownDocument(doc => {
|
||||||
this.triggerDiagnostics(doc.uri);
|
this.triggerDiagnostics(doc.uri);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._register(workspaceContents.onDidDeleteMarkdownDocument(uri => {
|
||||||
|
this.triggerForReferencingFiles(uri);
|
||||||
|
}));
|
||||||
|
|
||||||
this._register(vscode.workspace.onDidCloseTextDocument(({ uri }) => {
|
this._register(vscode.workspace.onDidCloseTextDocument(({ uri }) => {
|
||||||
this.pendingDiagnostics.delete(uri);
|
this.pendingDiagnostics.delete(uri);
|
||||||
this.inFlightDiagnostics.cancel(uri);
|
this.inFlightDiagnostics.cancel(uri);
|
||||||
|
@ -337,7 +343,6 @@ export class DiagnosticManager extends Disposable {
|
||||||
this.reporter.delete(uri);
|
this.reporter.delete(uri);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
this._register(this.linkWatcher.onDidChangeLinkedToFile(changedDocuments => {
|
this._register(this.linkWatcher.onDidChangeLinkedToFile(changedDocuments => {
|
||||||
for (const resource of changedDocuments) {
|
for (const resource of changedDocuments) {
|
||||||
const doc = vscode.workspace.textDocuments.find(doc => doc.uri.toString() === resource.toString());
|
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.tableOfContentsWatcher = this._register(new MdTableOfContentsWatcher(workspaceContents, tocProvider, delay / 2));
|
||||||
this._register(this.tableOfContentsWatcher.onTocChanged(async e => {
|
this._register(this.tableOfContentsWatcher.onTocChanged(e => {
|
||||||
// When the toc of a document changes, revalidate every file that linked to it too
|
return this.triggerForReferencingFiles(e.uri);
|
||||||
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.ready = this.rebuild();
|
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() {
|
public override dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
this.pendingDiagnostics.clear();
|
this.pendingDiagnostics.clear();
|
||||||
|
|
|
@ -40,7 +40,7 @@ async function getComputedDiagnostics(doc: InMemoryDocument, workspace: MdWorksp
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertDiagnosticsEqual(actual: readonly vscode.Diagnostic[], expectedRanges: readonly vscode.Range[]) {
|
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) {
|
for (let i = 0; i < actual.length; ++i) {
|
||||||
assertRangeEqual(actual[i].range, expectedRanges[i], `Range ${i} to be equal`);
|
assertRangeEqual(actual[i].range, expectedRanges[i], `Range ${i} to be equal`);
|
||||||
|
@ -449,7 +449,7 @@ suite('Markdown: Diagnostics manager', () => {
|
||||||
tocProvider,
|
tocProvider,
|
||||||
nulLogger,
|
nulLogger,
|
||||||
0);
|
0);
|
||||||
_disposables.push(manager, referencesProvider);
|
_disposables.push(linkProvider, tocProvider, referencesProvider, manager);
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,4 +554,40 @@ suite('Markdown: Diagnostics manager', () => {
|
||||||
new vscode.Range(2, 7, 2, 17),
|
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), []);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { MdTableOfContentsProvider, TableOfContents } from '../tableOfContents';
|
import { MdTableOfContentsProvider, TableOfContents } from '../tableOfContents';
|
||||||
|
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
|
||||||
import { equals } from './arrays';
|
import { equals } from './arrays';
|
||||||
|
import { Delayer } from './async';
|
||||||
import { Disposable } from './dispose';
|
import { Disposable } from './dispose';
|
||||||
import { ResourceMap } from './resourceMap';
|
import { ResourceMap } from './resourceMap';
|
||||||
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
|
|
||||||
import { Delayer } from './async';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the items in a table of contents have changed.
|
* Check if the items in a table of contents have changed.
|
||||||
|
|
Loading…
Reference in a new issue