constructor(node, ancestors, ctx) {
		if (node && ctx.paths.has(node)) {
			return ctx.paths.get(node);
		}

		/** @type {Node} */
		this.node = node;
		this.ancestors = ancestors;
		this.ctx = ctx;
		this.shouldStop = false;
		this.shouldSkip = false;
		def(this, 'ancestors', ancestors);
		def(this, 'ctx', ctx);
		def(this, 'shouldStop', false);

		this.start = node && node.start;
		this.end = node && node.end;

		/** @type {string | number} */
		this.key = null;
		/** @type {string} */
		this.parentKey = this.listKey = null;
		this.inList = false;
		if (node) {
			const parent = this.parent;
			for (const key in parent) {
				const entry = parent[key];
				if (entry === node) {
					this.key = this.parentKey = key;
				} else if (Array.isArray(entry)) {
					const index = entry.indexOf(node);
					if (index !== -1) {
						this.inList = true;
						this.listKey = this.parentKey = key;
						this.key = index;
					}
				}
			}

			ctx.paths.set(node, this);
		}
	}
@param {Node} node
@param {Node[]} ancestors
@param {ReturnType<typeof createContext>} ctx