mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-21 09:08:53 +01:00
Split out VS Code reference provider from markdown reference provider (#152369)
This change renames the main markdown reference provider class to `MdReferenceComputer` and then uses this to implement a `vscode.ReferenceProvider` This more cleanly splits the VS Code part of the logic from the general reference calculation stuff other providers consume
This commit is contained in:
@@ -5,16 +5,18 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable } from '../util/dispose';
|
||||
import { SkinnyTextDocument } from '../workspaceContents';
|
||||
import { MdReferencesProvider } from './references';
|
||||
import { MdReferencesComputer } from './references';
|
||||
|
||||
export class MdDefinitionProvider extends Disposable implements vscode.DefinitionProvider {
|
||||
|
||||
constructor(private readonly referencesProvider: MdReferencesProvider) {
|
||||
constructor(
|
||||
private readonly referencesComputer: MdReferencesComputer
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async provideDefinition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Definition | undefined> {
|
||||
const allRefs = await this.referencesProvider.getAllReferencesAtPosition(document, position, token);
|
||||
const allRefs = await this.referencesComputer.getReferencesAtPosition(document, position, token);
|
||||
|
||||
return allRefs.find(ref => ref.kind === 'link' && ref.isDefinition)?.location;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ResourceMap } from '../util/resourceMap';
|
||||
import { MdTableOfContentsWatcher } from '../test/tableOfContentsWatcher';
|
||||
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
|
||||
import { InternalHref, LinkDefinitionSet, MdLink, MdLinkComputer, MdLinkSource } from './documentLinkProvider';
|
||||
import { MdReferencesProvider, tryFindMdDocumentForLink } from './references';
|
||||
import { MdReferencesComputer, tryFindMdDocumentForLink } from './references';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -311,7 +311,7 @@ export class DiagnosticManager extends Disposable {
|
||||
private readonly computer: DiagnosticComputer,
|
||||
private readonly configuration: DiagnosticConfiguration,
|
||||
private readonly reporter: DiagnosticReporter,
|
||||
private readonly referencesProvider: MdReferencesProvider,
|
||||
private readonly referencesComputer: MdReferencesComputer,
|
||||
delay = 300,
|
||||
) {
|
||||
super();
|
||||
@@ -350,7 +350,7 @@ export class DiagnosticManager extends Disposable {
|
||||
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)) {
|
||||
for (const ref of await this.referencesComputer.getAllReferencesToFile(e.uri, noopToken)) {
|
||||
const file = ref.location.uri;
|
||||
if (!triggered.has(file)) {
|
||||
this.triggerDiagnostics(file);
|
||||
@@ -627,7 +627,7 @@ export function register(
|
||||
workspaceContents: MdWorkspaceContents,
|
||||
linkComputer: MdLinkComputer,
|
||||
commandManager: CommandManager,
|
||||
referenceProvider: MdReferencesProvider,
|
||||
referenceComputer: MdReferencesComputer,
|
||||
): vscode.Disposable {
|
||||
const configuration = new VSCodeDiagnosticConfiguration();
|
||||
const manager = new DiagnosticManager(
|
||||
@@ -636,7 +636,7 @@ export function register(
|
||||
new DiagnosticComputer(engine, workspaceContents, linkComputer),
|
||||
configuration,
|
||||
new DiagnosticCollectionReporter(),
|
||||
referenceProvider);
|
||||
referenceComputer);
|
||||
return vscode.Disposable.from(
|
||||
configuration,
|
||||
manager,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Command, CommandManager } from '../commandManager';
|
||||
import { MdReferencesProvider } from './references';
|
||||
import { MdReferencesComputer } from './references';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -16,7 +16,7 @@ export class FindFileReferencesCommand implements Command {
|
||||
public readonly id = 'markdown.findAllFileReferences';
|
||||
|
||||
constructor(
|
||||
private readonly referencesProvider: MdReferencesProvider,
|
||||
private readonly referencesComputer: MdReferencesComputer,
|
||||
) { }
|
||||
|
||||
public async execute(resource?: vscode.Uri) {
|
||||
@@ -33,7 +33,7 @@ export class FindFileReferencesCommand implements Command {
|
||||
location: vscode.ProgressLocation.Window,
|
||||
title: localize('progress.title', "Finding file references")
|
||||
}, async (_progress, token) => {
|
||||
const references = await this.referencesProvider.getAllReferencesToFile(resource!, token);
|
||||
const references = await this.referencesComputer.getAllReferencesToFile(resource!, token);
|
||||
const locations = references.map(ref => ref.location);
|
||||
|
||||
const config = vscode.workspace.getConfiguration('references');
|
||||
@@ -49,6 +49,6 @@ export class FindFileReferencesCommand implements Command {
|
||||
}
|
||||
}
|
||||
|
||||
export function registerFindFileReferences(commandManager: CommandManager, referencesProvider: MdReferencesProvider): vscode.Disposable {
|
||||
export function registerFindFileReferences(commandManager: CommandManager, referencesProvider: MdReferencesComputer): vscode.Disposable {
|
||||
return commandManager.register(new FindFileReferencesCommand(referencesProvider));
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ export interface MdHeaderReference {
|
||||
|
||||
export type MdReference = MdLinkReference | MdHeaderReference;
|
||||
|
||||
export class MdReferencesProvider extends Disposable implements vscode.ReferenceProvider {
|
||||
export class MdReferencesComputer extends Disposable {
|
||||
|
||||
private readonly _linkCache: MdWorkspaceCache<readonly MdLink[]>;
|
||||
|
||||
@@ -74,15 +74,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||
this._linkCache = this._register(new MdWorkspaceCache(workspaceContents, doc => linkComputer.getAllLinks(doc, noopToken)));
|
||||
}
|
||||
|
||||
async provideReferences(document: SkinnyTextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): Promise<vscode.Location[] | undefined> {
|
||||
const allRefs = await this.getAllReferencesAtPosition(document, position, token);
|
||||
|
||||
return allRefs
|
||||
.filter(ref => context.includeDeclaration || !ref.isDefinition)
|
||||
.map(ref => ref.location);
|
||||
}
|
||||
|
||||
public async getAllReferencesAtPosition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<MdReference[]> {
|
||||
public async getReferencesAtPosition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<MdReference[]> {
|
||||
const toc = await TableOfContents.create(this.engine, document);
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
@@ -96,6 +88,11 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||
}
|
||||
}
|
||||
|
||||
public async getAllReferencesToFile(resource: vscode.Uri, _token: vscode.CancellationToken): Promise<MdReference[]> {
|
||||
const allLinksInWorkspace = (await this._linkCache.values()).flat();
|
||||
return Array.from(this.findAllLinksToFile(resource, allLinksInWorkspace, undefined));
|
||||
}
|
||||
|
||||
private async getReferencesToHeader(document: SkinnyTextDocument, header: TocEntry): Promise<MdReference[]> {
|
||||
const links = (await this._linkCache.values()).flat();
|
||||
|
||||
@@ -226,12 +223,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||
|| uri.Utils.extname(href.path) === '' && href.path.with({ path: href.path.path + '.md' }).fsPath === targetDoc.fsPath;
|
||||
}
|
||||
|
||||
public async getAllReferencesToFile(resource: vscode.Uri, _token: vscode.CancellationToken): Promise<MdReference[]> {
|
||||
const allLinksInWorkspace = (await this._linkCache.values()).flat();
|
||||
return Array.from(this.findAllLinksToFile(resource, allLinksInWorkspace, undefined));
|
||||
}
|
||||
|
||||
private * findAllLinksToFile(resource: vscode.Uri, allLinksInWorkspace: readonly MdLink[], sourceLink: MdLink | undefined): Iterable<MdReference> {
|
||||
private *findAllLinksToFile(resource: vscode.Uri, allLinksInWorkspace: readonly MdLink[], sourceLink: MdLink | undefined): Iterable<MdReference> {
|
||||
for (const link of allLinksInWorkspace) {
|
||||
if (link.href.kind !== 'internal' || !this.looksLikeLinkToDoc(link.href, resource)) {
|
||||
continue;
|
||||
@@ -254,7 +246,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||
}
|
||||
}
|
||||
|
||||
private * getReferencesToLinkReference(allLinks: Iterable<MdLink>, refToFind: string, from: { resource: vscode.Uri; range: vscode.Range }): Iterable<MdReference> {
|
||||
private *getReferencesToLinkReference(allLinks: Iterable<MdLink>, refToFind: string, from: { resource: vscode.Uri; range: vscode.Range }): Iterable<MdReference> {
|
||||
for (const link of allLinks) {
|
||||
let ref: string;
|
||||
if (link.kind === 'definition') {
|
||||
@@ -291,6 +283,30 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export class MdVsCodeReferencesProvider implements vscode.ReferenceProvider {
|
||||
|
||||
public constructor(
|
||||
private readonly referencesComputer: MdReferencesComputer
|
||||
) { }
|
||||
|
||||
async provideReferences(document: SkinnyTextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): Promise<vscode.Location[]> {
|
||||
const allRefs = await this.referencesComputer.getReferencesAtPosition(document, position, token);
|
||||
return allRefs
|
||||
.filter(ref => context.includeDeclaration || !ref.isDefinition)
|
||||
.map(ref => ref.location);
|
||||
}
|
||||
}
|
||||
|
||||
export function registerReferencesProvider(
|
||||
selector: vscode.DocumentSelector,
|
||||
computer: MdReferencesComputer,
|
||||
): vscode.Disposable {
|
||||
return vscode.languages.registerReferenceProvider(selector, new MdVsCodeReferencesProvider(computer));
|
||||
}
|
||||
|
||||
export async function tryFindMdDocumentForLink(href: InternalHref, workspaceContents: MdWorkspaceContents): Promise<SkinnyTextDocument | undefined> {
|
||||
const targetDoc = await workspaceContents.getMarkdownDocument(href.path);
|
||||
if (targetDoc) {
|
||||
@@ -305,4 +321,3 @@ export async function tryFindMdDocumentForLink(href: InternalHref, workspaceCont
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Disposable } from '../util/dispose';
|
||||
import { resolveDocumentLink } from '../util/openDocumentLink';
|
||||
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
|
||||
import { InternalHref } from './documentLinkProvider';
|
||||
import { MdHeaderReference, MdLinkReference, MdReference, MdReferencesProvider, tryFindMdDocumentForLink } from './references';
|
||||
import { MdHeaderReference, MdLinkReference, MdReference, MdReferencesComputer, tryFindMdDocumentForLink } from './references';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -58,7 +58,7 @@ export class MdRenameProvider extends Disposable implements vscode.RenameProvide
|
||||
private readonly renameNotSupportedText = localize('invalidRenameLocation', "Rename not supported at location");
|
||||
|
||||
public constructor(
|
||||
private readonly referencesProvider: MdReferencesProvider,
|
||||
private readonly referencesComputer: MdReferencesComputer,
|
||||
private readonly workspaceContents: MdWorkspaceContents,
|
||||
private readonly slugifier: Slugifier,
|
||||
) {
|
||||
@@ -253,7 +253,7 @@ export class MdRenameProvider extends Disposable implements vscode.RenameProvide
|
||||
return this.cachedRefs;
|
||||
}
|
||||
|
||||
const references = await this.referencesProvider.getAllReferencesAtPosition(document, position, token);
|
||||
const references = await this.referencesComputer.getReferencesAtPosition(document, position, token);
|
||||
const triggerRef = references.find(ref => ref.isTriggerLocation);
|
||||
if (!triggerRef) {
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user