All files / views/trees/definition-tree/nodes/individuals individuals-node.ts

100% Statements 32/32
100% Branches 10/10
100% Functions 13/13
100% Lines 29/29

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                        1x       1x       1x       1x 1x 1x   1x             53x                 41x 34x     7x               29x       12x 12x   12x 8x         12x       1x       6x   6x   4x 3x   3x 2x 2x   2x 1x         3x       2x    
import * as vscode from "vscode";
import { any } from '@src/utilities';
import { TreeNode, sortByLabel } from "@src/views/trees/tree-node";
import { DefinitionTreeNode } from "../../definition-tree-node";
import { IndividualNode } from "./individual-node";
import { IndividualClassNode } from "./individual-class-node";
 
/**
 * Node of a class instance in the definition tree.
 */
export class IndividualsNode extends IndividualClassNode {
	override getContextValue(): string {
		return 'individuals';
	}
 
	override getIcon() {
		return undefined;
	}
 
	override getLabel(): vscode.TreeItemLabel {
		return { label: 'Individuals' };
	}
 
	override getDescription(): string {
		const graphs = this.getDocumentGraphs();
		const options = this.getQueryOptions();
		const individuals = this.vocabulary.getIndividuals(graphs, undefined, options);
 
		return [...individuals].length.toString();
	}
 
	/**
	 * Indicates whether the individuals are grouped by their types.
	 */
	private _showIndividualTypes(): boolean {
		return this.settings.get('view.showIndividualTypes', true) === true;
	}
 
	/**
	 * Get the IRIs of the resources that are listed below this node: the types of the individuals
	 * if they are grouped by type, or the individuals otherwise.
	 * @returns An iterator of resource IRIs.
	 */
	private _getChildIris(): IterableIterator<string> {
		if (this._showIndividualTypes()) {
			return this.vocabulary.getIndividualTypes(this.getOntologyGraphs(), undefined, this.getQueryOptions());
		}
 
		return this.vocabulary.getIndividuals(this.getDocumentGraphs(), undefined, this.getQueryOptions());
	}
 
	/**
	 * Indicates whether there are individuals or individual types, stopping at the first one.
	 * @returns `true` if the node has children, `false` otherwise.
	 */
	override hasChildren(): boolean {
		return any(this._getChildIris());
	}
 
	override getChildren(): TreeNode[] {
		const result = [];
		const showIndividualTypes = this._showIndividualTypes();
 
		for (const iri of this._getChildIris()) {
			result.push(showIndividualTypes
				? this.createChildNode(IndividualClassNode, iri)
				: this.createChildNode(IndividualNode, iri));
		}
 
		return sortByLabel(result);
	}
 
	override getTooltip(): vscode.MarkdownString | undefined {
		return undefined;
	}
 
	override resolveNodeForUri(iri: string): DefinitionTreeNode | undefined {
		const children = this.getChildren() as DefinitionTreeNode[];
 
		if (this.settings.get('view.showIndividualTypes', true)) {
			// Individuals are grouped by type — find the matching type node, then the individual within it.
			for (const typeIri of this.vocabulary.getIndividualTypes(this.getDocumentGraphs(), iri)) {
				const typeNode = children.find(n => n.uri === typeIri);
 
				if (typeNode) {
					const instances = typeNode.getChildren() as DefinitionTreeNode[];
					const found = instances.find(n => n.uri === iri);
 
					if (found) {
						return found;
					}
				}
			}
 
			return undefined;
		}
 
		// Flat list — direct lookup.
		return children.find(n => n.uri === iri);
	}
}