"use strict"; import Expression from "./expression.js"; import NoteSet from "../note_set.js"; import log from "../../log.js"; import becca from "../../../becca/becca.js"; import SearchContext from "../search_context.js"; class AncestorExp extends Expression { private ancestorNoteId: string; private ancestorDepthComparator; ancestorDepth?: string; constructor(ancestorNoteId: string, ancestorDepth?: string) { super(); this.ancestorNoteId = ancestorNoteId; this.ancestorDepth = ancestorDepth; // for DEBUG mode this.ancestorDepthComparator = this.getComparator(ancestorDepth); } execute(inputNoteSet: NoteSet, executionContext: {}, searchContext: SearchContext) { const ancestorNote = becca.notes[this.ancestorNoteId]; if (!ancestorNote) { log.error(`Subtree note '${this.ancestorNoteId}' was not not found.`); return new NoteSet([]); } const subtree = ancestorNote.getSubtree(); const subTreeNoteSet = new NoteSet(subtree.notes).intersection(inputNoteSet); if (!this.ancestorDepthComparator) { return subTreeNoteSet; } const depthConformingNoteSet = new NoteSet([]); for (const note of subTreeNoteSet.notes) { const distance = note.getDistanceToAncestor(ancestorNote.noteId); if (this.ancestorDepthComparator(distance)) { depthConformingNoteSet.add(note); } } return depthConformingNoteSet; } getComparator(depthCondition?: string): ((depth: number) => boolean) | null { if (!depthCondition) { return null; } const comparedDepth = parseInt(depthCondition.substr(2)); if (depthCondition.startsWith("eq")) { return depth => depth === comparedDepth; } else if (depthCondition.startsWith("gt")) { return depth => depth > comparedDepth; } else if (depthCondition.startsWith("lt")) { return depth => depth < comparedDepth; } else { log.error(`Unrecognized depth condition value ${depthCondition}`); return null; } } } export default AncestorExp;