mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 21:55:38 +00: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:
parent
e8f28ac3ac
commit
3114ee690b
|
@ -15,7 +15,7 @@ import { registerDropIntoEditor } from './languageFeatures/dropIntoEditor';
|
|||
import { registerFindFileReferences } from './languageFeatures/fileReferences';
|
||||
import { MdFoldingProvider } from './languageFeatures/foldingProvider';
|
||||
import { MdPathCompletionProvider } from './languageFeatures/pathCompletions';
|
||||
import { MdReferencesProvider } from './languageFeatures/references';
|
||||
import { MdReferencesComputer, registerReferencesProvider } from './languageFeatures/references';
|
||||
import { MdRenameProvider } from './languageFeatures/rename';
|
||||
import { MdSmartSelect } from './languageFeatures/smartSelect';
|
||||
import { MdWorkspaceSymbolProvider } from './languageFeatures/workspaceSymbolProvider';
|
||||
|
@ -66,22 +66,22 @@ function registerMarkdownLanguageFeatures(
|
|||
const linkComputer = new MdLinkComputer(engine);
|
||||
const workspaceContents = new VsCodeMdWorkspaceContents();
|
||||
|
||||
const referencesProvider = new MdReferencesProvider(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const referencesComputer = new MdReferencesComputer(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
return vscode.Disposable.from(
|
||||
workspaceContents,
|
||||
vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider),
|
||||
vscode.languages.registerFoldingRangeProvider(selector, new MdFoldingProvider(engine)),
|
||||
vscode.languages.registerSelectionRangeProvider(selector, new MdSmartSelect(engine)),
|
||||
vscode.languages.registerWorkspaceSymbolProvider(new MdWorkspaceSymbolProvider(symbolProvider, workspaceContents)),
|
||||
vscode.languages.registerReferenceProvider(selector, referencesProvider),
|
||||
vscode.languages.registerRenameProvider(selector, new MdRenameProvider(referencesProvider, workspaceContents, githubSlugifier)),
|
||||
vscode.languages.registerDefinitionProvider(selector, new MdDefinitionProvider(referencesProvider)),
|
||||
vscode.languages.registerRenameProvider(selector, new MdRenameProvider(referencesComputer, workspaceContents, githubSlugifier)),
|
||||
vscode.languages.registerDefinitionProvider(selector, new MdDefinitionProvider(referencesComputer)),
|
||||
MdPathCompletionProvider.register(selector, engine, linkComputer),
|
||||
registerDocumentLinkProvider(selector, linkComputer),
|
||||
registerDiagnostics(selector, engine, workspaceContents, linkComputer, commandManager, referencesProvider),
|
||||
registerDiagnostics(selector, engine, workspaceContents, linkComputer, commandManager, referencesComputer),
|
||||
registerDropIntoEditor(selector),
|
||||
registerReferencesProvider(selector, referencesComputer),
|
||||
registerPasteProvider(selector),
|
||||
registerFindFileReferences(commandManager, referencesProvider),
|
||||
registerFindFileReferences(commandManager, referencesComputer),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,11 +223,6 @@ 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> {
|
||||
for (const link of allLinksInWorkspace) {
|
||||
if (link.href.kind !== 'internal' || !this.looksLikeLinkToDoc(link.href, resource)) {
|
||||
|
@ -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;
|
||||
|
|
|
@ -8,7 +8,7 @@ import 'mocha';
|
|||
import * as vscode from 'vscode';
|
||||
import { MdDefinitionProvider } from '../languageFeatures/definitionProvider';
|
||||
import { MdLinkComputer } from '../languageFeatures/documentLinkProvider';
|
||||
import { MdReferencesProvider } from '../languageFeatures/references';
|
||||
import { MdReferencesComputer } from '../languageFeatures/references';
|
||||
import { githubSlugifier } from '../slugify';
|
||||
import { noopToken } from '../util/cancellation';
|
||||
import { InMemoryDocument } from '../util/inMemoryDocument';
|
||||
|
@ -21,8 +21,8 @@ import { joinLines, workspacePath } from './util';
|
|||
function getDefinition(doc: InMemoryDocument, pos: vscode.Position, workspaceContents: MdWorkspaceContents) {
|
||||
const engine = createNewMarkdownEngine();
|
||||
const linkComputer = new MdLinkComputer(engine);
|
||||
const referencesProvider = new MdReferencesProvider(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const provider = new MdDefinitionProvider(referencesProvider);
|
||||
const referencesComputer = new MdReferencesComputer(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const provider = new MdDefinitionProvider(referencesComputer);
|
||||
return provider.provideDefinition(doc, pos, noopToken);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import 'mocha';
|
|||
import * as vscode from 'vscode';
|
||||
import { DiagnosticCollectionReporter, DiagnosticComputer, DiagnosticConfiguration, DiagnosticLevel, DiagnosticManager, DiagnosticOptions, DiagnosticReporter } from '../languageFeatures/diagnostics';
|
||||
import { MdLinkComputer } from '../languageFeatures/documentLinkProvider';
|
||||
import { MdReferencesProvider } from '../languageFeatures/references';
|
||||
import { MdReferencesComputer } from '../languageFeatures/references';
|
||||
import { githubSlugifier } from '../slugify';
|
||||
import { noopToken } from '../util/cancellation';
|
||||
import { InMemoryDocument } from '../util/inMemoryDocument';
|
||||
|
@ -42,14 +42,14 @@ function createDiagnosticsManager(
|
|||
) {
|
||||
const engine = createNewMarkdownEngine();
|
||||
const linkComputer = new MdLinkComputer(engine);
|
||||
const referencesProvider = new MdReferencesProvider(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const referencesComputer = new MdReferencesComputer(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
return new DiagnosticManager(
|
||||
engine,
|
||||
workspaceContents,
|
||||
new DiagnosticComputer(engine, workspaceContents, linkComputer),
|
||||
configuration,
|
||||
reporter,
|
||||
referencesProvider,
|
||||
referencesComputer,
|
||||
0);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as assert from 'assert';
|
|||
import 'mocha';
|
||||
import * as vscode from 'vscode';
|
||||
import { MdLinkComputer } from '../languageFeatures/documentLinkProvider';
|
||||
import { MdReference, MdReferencesProvider } from '../languageFeatures/references';
|
||||
import { MdReference, MdReferencesComputer } from '../languageFeatures/references';
|
||||
import { githubSlugifier } from '../slugify';
|
||||
import { noopToken } from '../util/cancellation';
|
||||
import { InMemoryDocument } from '../util/inMemoryDocument';
|
||||
|
@ -20,8 +20,8 @@ import { joinLines, workspacePath } from './util';
|
|||
function getFileReferences(resource: vscode.Uri, workspaceContents: MdWorkspaceContents) {
|
||||
const engine = createNewMarkdownEngine();
|
||||
const linkComputer = new MdLinkComputer(engine);
|
||||
const provider = new MdReferencesProvider(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
return provider.getAllReferencesToFile(resource, noopToken);
|
||||
const computer = new MdReferencesComputer(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
return computer.getAllReferencesToFile(resource, noopToken);
|
||||
}
|
||||
|
||||
function assertReferencesEqual(actualRefs: readonly MdReference[], ...expectedRefs: { uri: vscode.Uri; line: number }[]) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as assert from 'assert';
|
|||
import 'mocha';
|
||||
import * as vscode from 'vscode';
|
||||
import { MdLinkComputer } from '../languageFeatures/documentLinkProvider';
|
||||
import { MdReferencesProvider } from '../languageFeatures/references';
|
||||
import { MdReferencesComputer, MdVsCodeReferencesProvider } from '../languageFeatures/references';
|
||||
import { githubSlugifier } from '../slugify';
|
||||
import { noopToken } from '../util/cancellation';
|
||||
import { InMemoryDocument } from '../util/inMemoryDocument';
|
||||
|
@ -20,7 +20,8 @@ import { joinLines, workspacePath } from './util';
|
|||
function getReferences(doc: InMemoryDocument, pos: vscode.Position, workspaceContents: MdWorkspaceContents) {
|
||||
const engine = createNewMarkdownEngine();
|
||||
const linkComputer = new MdLinkComputer(engine);
|
||||
const provider = new MdReferencesProvider(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const computer = new MdReferencesComputer(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const provider = new MdVsCodeReferencesProvider(computer);
|
||||
return provider.provideReferences(doc, pos, { includeDeclaration: true }, noopToken);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as assert from 'assert';
|
|||
import 'mocha';
|
||||
import * as vscode from 'vscode';
|
||||
import { MdLinkComputer } from '../languageFeatures/documentLinkProvider';
|
||||
import { MdReferencesProvider } from '../languageFeatures/references';
|
||||
import { MdReferencesComputer } from '../languageFeatures/references';
|
||||
import { MdRenameProvider, MdWorkspaceEdit } from '../languageFeatures/rename';
|
||||
import { githubSlugifier } from '../slugify';
|
||||
import { noopToken } from '../util/cancellation';
|
||||
|
@ -24,8 +24,8 @@ import { assertRangeEqual, joinLines, workspacePath } from './util';
|
|||
function prepareRename(doc: InMemoryDocument, pos: vscode.Position, workspaceContents: MdWorkspaceContents): Promise<undefined | { readonly range: vscode.Range; readonly placeholder: string }> {
|
||||
const engine = createNewMarkdownEngine();
|
||||
const linkComputer = new MdLinkComputer(engine);
|
||||
const referencesProvider = new MdReferencesProvider(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const renameProvider = new MdRenameProvider(referencesProvider, workspaceContents, githubSlugifier);
|
||||
const referenceComputer = new MdReferencesComputer(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const renameProvider = new MdRenameProvider(referenceComputer, workspaceContents, githubSlugifier);
|
||||
return renameProvider.prepareRename(doc, pos, noopToken);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ function prepareRename(doc: InMemoryDocument, pos: vscode.Position, workspaceCon
|
|||
function getRenameEdits(doc: InMemoryDocument, pos: vscode.Position, newName: string, workspaceContents: MdWorkspaceContents): Promise<MdWorkspaceEdit | undefined> {
|
||||
const engine = createNewMarkdownEngine();
|
||||
const linkComputer = new MdLinkComputer(engine);
|
||||
const referencesProvider = new MdReferencesProvider(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const referencesProvider = new MdReferencesComputer(linkComputer, workspaceContents, engine, githubSlugifier);
|
||||
const renameProvider = new MdRenameProvider(referencesProvider, workspaceContents, githubSlugifier);
|
||||
return renameProvider.provideRenameEditsImpl(doc, pos, newName, noopToken);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue