mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 05:19:39 +00:00
Clean up link data structure
This commit is contained in:
parent
cfe0b1d480
commit
174924d73c
|
@ -16,31 +16,28 @@ const localize = nls.loadMessageBundle();
|
|||
|
||||
export interface ExternalLinkTarget {
|
||||
readonly kind: 'external';
|
||||
|
||||
readonly uri: vscode.Uri;
|
||||
}
|
||||
|
||||
export interface InternalLinkTarget {
|
||||
readonly kind: 'internal';
|
||||
|
||||
readonly fromResource: vscode.Uri;
|
||||
|
||||
readonly path: vscode.Uri;
|
||||
readonly fragment: string;
|
||||
}
|
||||
|
||||
export interface ReferenceLinkTarget {
|
||||
readonly kind: 'reference';
|
||||
|
||||
readonly fromResource: vscode.Uri;
|
||||
|
||||
readonly ref: string;
|
||||
}
|
||||
|
||||
export interface DefinitionLinkTarget {
|
||||
readonly kind: 'definition';
|
||||
readonly ref: string;
|
||||
readonly target: ExternalLinkTarget | InternalLinkTarget;
|
||||
}
|
||||
|
||||
readonly fromResource: vscode.Uri;
|
||||
export interface DefinitionLinkTarget {
|
||||
readonly kind: 'definition';
|
||||
|
||||
readonly ref: string;
|
||||
readonly target: ExternalLinkTarget | InternalLinkTarget;
|
||||
|
@ -95,7 +92,6 @@ function parseLink(
|
|||
|
||||
return {
|
||||
kind: 'internal',
|
||||
fromResource: document.uri,
|
||||
path: resourceUri,
|
||||
fragment: tempUri.fragment,
|
||||
};
|
||||
|
@ -108,6 +104,7 @@ function getWorkspaceFolder(document: SkinnyTextDocument) {
|
|||
|
||||
export interface LinkData {
|
||||
readonly target: LinkTarget;
|
||||
readonly sourceResource: vscode.Uri;
|
||||
readonly sourceRange: vscode.Range;
|
||||
}
|
||||
|
||||
|
@ -127,6 +124,7 @@ function extractDocumentLink(
|
|||
}
|
||||
return {
|
||||
target: linkTarget,
|
||||
sourceResource: document.uri,
|
||||
sourceRange: new vscode.Range(linkStart, linkEnd)
|
||||
};
|
||||
} catch {
|
||||
|
@ -192,29 +190,29 @@ function isLinkInsideCode(code: CodeInDocument, link: LinkData) {
|
|||
code.inline.some(position => position.intersection(link.sourceRange));
|
||||
}
|
||||
|
||||
function createDocumentLink(sourceRange: vscode.Range, target: LinkTarget, definitionSet: LinkDefinitionSet): vscode.DocumentLink | undefined {
|
||||
switch (target.kind) {
|
||||
function createDocumentLink(link: LinkData, definitionSet: LinkDefinitionSet): vscode.DocumentLink | undefined {
|
||||
switch (link.target.kind) {
|
||||
case 'external': {
|
||||
return new vscode.DocumentLink(sourceRange, target.uri);
|
||||
return new vscode.DocumentLink(link.sourceRange, link.target.uri);
|
||||
}
|
||||
case 'internal': {
|
||||
const uri = OpenDocumentLinkCommand.createCommandUri(target.fromResource, target.path, target.fragment);
|
||||
const documentLink = new vscode.DocumentLink(sourceRange, uri);
|
||||
const uri = OpenDocumentLinkCommand.createCommandUri(link.sourceResource, link.target.path, link.target.fragment);
|
||||
const documentLink = new vscode.DocumentLink(link.sourceRange, uri);
|
||||
documentLink.tooltip = localize('documentLink.tooltip', 'Follow link');
|
||||
return documentLink;
|
||||
}
|
||||
case 'reference': {
|
||||
const def = definitionSet.lookup(target.ref);
|
||||
const def = definitionSet.lookup(link.target.ref);
|
||||
if (def) {
|
||||
return new vscode.DocumentLink(
|
||||
sourceRange,
|
||||
link.sourceRange,
|
||||
vscode.Uri.parse(`command:_markdown.moveCursorToPosition?${encodeURIComponent(JSON.stringify([def.sourceRange.start.line, def.sourceRange.start.character]))}`));
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
case 'definition':
|
||||
return createDocumentLink(sourceRange, target.target, definitionSet);
|
||||
return createDocumentLink({ sourceRange: link.sourceRange, sourceResource: link.sourceResource, target: link.target.target }, definitionSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +233,7 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider {
|
|||
|
||||
const definitionSet = new LinkDefinitionSet(allLinks);
|
||||
return coalesce(allLinks
|
||||
.map(data => createDocumentLink(data.sourceRange, data.target, definitionSet)));
|
||||
.map(data => createDocumentLink(data, definitionSet)));
|
||||
}
|
||||
|
||||
public async getAllLinks(document: SkinnyTextDocument): Promise<LinkData[]> {
|
||||
|
@ -286,9 +284,9 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider {
|
|||
|
||||
yield {
|
||||
sourceRange: new vscode.Range(linkStart, linkEnd),
|
||||
sourceResource: document.uri,
|
||||
target: {
|
||||
kind: 'reference',
|
||||
fromResource: document.uri,
|
||||
ref: reference,
|
||||
}
|
||||
};
|
||||
|
@ -309,10 +307,10 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider {
|
|||
const target = parseLink(document, link.substring(1, link.length - 1));
|
||||
if (target) {
|
||||
yield {
|
||||
sourceResource: document.uri,
|
||||
sourceRange: new vscode.Range(linkStart, linkEnd),
|
||||
target: {
|
||||
kind: 'definition',
|
||||
fromResource: document.uri,
|
||||
ref: reference,
|
||||
target
|
||||
}
|
||||
|
@ -324,10 +322,10 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider {
|
|||
const target = parseLink(document, link);
|
||||
if (target) {
|
||||
yield {
|
||||
sourceResource: document.uri,
|
||||
sourceRange: new vscode.Range(linkStart, linkEnd),
|
||||
target: {
|
||||
kind: 'definition',
|
||||
fromResource: document.uri,
|
||||
ref: reference,
|
||||
target,
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Slugifier } from '../slugify';
|
|||
import { TableOfContents, TocEntry } from '../tableOfContents';
|
||||
import { Disposable } from '../util/dispose';
|
||||
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
|
||||
import { InternalLinkTarget, LinkData, LinkTarget, MdLinkProvider, ReferenceLinkTarget } from './documentLinkProvider';
|
||||
import { InternalLinkTarget, LinkData, LinkTarget, MdLinkProvider } from './documentLinkProvider';
|
||||
import { MdWorkspaceCache } from './workspaceCache';
|
||||
|
||||
|
||||
|
@ -75,12 +75,12 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
|||
if (isLinkToHeader(link.target, header, document.uri, this.slugifier)) {
|
||||
references.push({
|
||||
isDefinition: false,
|
||||
location: new vscode.Location(link.target.fromResource, link.sourceRange)
|
||||
location: new vscode.Location(link.sourceResource, link.sourceRange)
|
||||
});
|
||||
} else if (link.target.kind === 'definition' && isLinkToHeader(link.target.target, header, document.uri, this.slugifier)) {
|
||||
references.push({
|
||||
isDefinition: false,
|
||||
location: new vscode.Location(link.target.target.fromResource, link.sourceRange)
|
||||
location: new vscode.Location(link.sourceResource, link.sourceRange)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
|||
const allLinksInWorkspace = (await this._linkCache.getAll()).flat();
|
||||
|
||||
if (sourceLink.target.kind === 'reference') {
|
||||
return Array.from(this.getReferencesToReferenceLink(allLinksInWorkspace, sourceLink.target));
|
||||
return Array.from(this.getReferencesToReferenceLink(allLinksInWorkspace, sourceLink));
|
||||
}
|
||||
|
||||
if (sourceLink.target.kind !== 'internal') {
|
||||
|
@ -142,13 +142,13 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
|||
|
||||
if (sourceLink.target.fragment) {
|
||||
if (this.slugifier.fromHeading(link.target.fragment).equals(this.slugifier.fromHeading(sourceLink.target.fragment))) {
|
||||
references.push({ isDefinition: false, location: new vscode.Location(link.target.fromResource, link.sourceRange) });
|
||||
references.push({ isDefinition: false, location: new vscode.Location(link.sourceResource, link.sourceRange) });
|
||||
}
|
||||
} else { // Triggered on a link without a fragment so we only require matching the file and ignore fragments
|
||||
|
||||
// But exclude cases where the file is referencing itself
|
||||
if (link.target.fromResource.fsPath !== targetDoc.uri.fsPath) {
|
||||
references.push({ isDefinition: false, location: new vscode.Location(link.target.fromResource, link.sourceRange) });
|
||||
if (link.sourceResource.fsPath !== targetDoc.uri.fsPath) {
|
||||
references.push({ isDefinition: false, location: new vscode.Location(link.sourceResource, link.sourceRange) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,13 +156,16 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
|||
return references;
|
||||
}
|
||||
|
||||
private *getReferencesToReferenceLink(allLinks: Iterable<LinkData>, sourceLink: ReferenceLinkTarget): Iterable<MdReference> {
|
||||
private *getReferencesToReferenceLink(allLinks: Iterable<LinkData>, sourceLink: LinkData): Iterable<MdReference> {
|
||||
if (sourceLink.target.kind !== 'reference') {
|
||||
return;
|
||||
}
|
||||
for (const link of allLinks) {
|
||||
if (link.target.kind === 'reference' || link.target.kind === 'definition') {
|
||||
if (link.target.ref === sourceLink.ref && link.target.fromResource.fsPath === sourceLink.fromResource.fsPath) {
|
||||
if (link.target.ref === sourceLink.target.ref && link.sourceResource.fsPath === sourceLink.sourceResource.fsPath) {
|
||||
yield {
|
||||
isDefinition: false,
|
||||
location: new vscode.Location(sourceLink.fromResource, link.sourceRange)
|
||||
location: new vscode.Location(sourceLink.sourceResource, link.sourceRange)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue