Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 1x 1x 7x 98x 136x 16x 16x 7x 9x 11x 11x 98x 98x 31x 67x 1x 22x 22x 22x 22x 22x 22x 22x 22x 22x | import * as vscode from "vscode";
import { DefinitionTreeNode } from "../../definition-tree-node";
import { ConceptClassNode } from "./concept-class-node";
/**
* Node that lists the concepts of a concept scheme, or the concepts that are not displayed below
* any concept scheme if the `inScheme` query option is `null`.
*/
export class ConceptsNode extends ConceptClassNode {
override getContextValue(): string {
return 'concepts';
}
override getIcon(): vscode.ThemeIcon | undefined {
return undefined;
}
override getLabel(): vscode.TreeItemLabel {
return { label: 'Concepts' };
}
/**
* The number of concepts below this node, computed once per node. Counting them traverses the
* whole concept scheme, and the provider recreates all nodes on refresh, so it is safe and
* worthwhile to memoize here — see the note on {@link DefinitionTreeNode.getLabel}.
*/
private _conceptCount: number | undefined;
/**
* Get the URI of the concept scheme whose concepts are displayed below this node.
* @returns The URI of a concept scheme.
*/
private _getSchemeUri(): string {
return this.getQueryOptions().inScheme ?? this.uri;
}
/**
* Indicates whether this node lists the concepts that are not displayed below any concept scheme.
*/
private _isUnscoped(): boolean {
return this.getQueryOptions().inScheme === null;
}
/**
* Get the concepts that can be reached by expanding this node.
* @returns An iterator of concept URIs.
*/
private _getConcepts(): IterableIterator<string> {
const graphs = this.getDocumentGraphs();
if (this._isUnscoped()) {
return this.vocabulary.getUnscopedConcepts(graphs, this.getQueryOptions());
}
return this.vocabulary.getAllConceptsInScheme(graphs, this._getSchemeUri());
}
override getDescription(): string {
// Note: This counts exactly the set of concepts that can be reached by expanding this node.
this._conceptCount ??= [...this._getConcepts()].length;
return this._conceptCount.toString();
}
override *getSubClassIris(): IterableIterator<string> {
const graphs = this.getDocumentGraphs();
if (this._isUnscoped()) {
yield* this.vocabulary.getUnscopedRootConcepts(graphs, this.getQueryOptions());
} else {
yield* this.vocabulary.getNarrowerConcepts(graphs, this._getSchemeUri(), this.getQueryOptions());
}
}
override getTooltip(): vscode.MarkdownString | undefined {
return undefined;
}
override resolveNodeForUri(iri: string): DefinitionTreeNode | undefined {
// Note: Concepts below a concept scheme are not part of the unscoped concepts and vice versa.
Iif (this._isUnscoped() && !new Set(this._getConcepts()).has(iri)) {
return undefined;
}
const graphs = this.getDocumentGraphs();
const path = this.vocabulary.getConceptSchemePath(graphs, iri) ?? [];
// The path contains the broader concepts of the concept, ordered from the closest broader
// concept to the scheme root, so it needs to be reversed. The scheme itself is dropped
// because it is the ConceptSchemeNode parent, not a child here.
const rootToTarget = [...path].reverse();
const schemeUri = this._getSchemeUri();
const schemeIndex = rootToTarget.indexOf(schemeUri);
const walkPath = schemeIndex >= 0
? rootToTarget.slice(schemeIndex + 1)
: rootToTarget;
// The path does not contain the concept itself, which is the node we are looking for.
walkPath.push(iri);
return this.walkHierarchyPath(walkPath);
}
} |