'use strict';

var levn = require('levn');

/**
 * @fileoverview Config Comment Parser
 * @author Nicholas C. Zakas
 */


//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/** @import * as $eslintcore from "@eslint/core"; */
/** @typedef {$eslintcore.RuleConfig} RuleConfig */
/** @typedef {$eslintcore.RulesConfig} RulesConfig */
/** @import * as $typests from "./types.ts"; */
/** @typedef {$typests.StringConfig} StringConfig */
/** @typedef {$typests.BooleanConfig} BooleanConfig */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

const directivesPattern = /^([a-z]+(?:-[a-z]+)*)(?:\s|$)/u;
const validSeverities = new Set([0, 1, 2, "off", "warn", "error"]);

/**
 * Determines if the severity in the rule configuration is valid.
 * @param {RuleConfig} ruleConfig A rule's configuration.
 * @returns {boolean} `true` if the severity is valid, otherwise `false`.
 */
function isSeverityValid(ruleConfig) {
	const severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
	return validSeverities.has(severity);
}

/**
 * Determines if all severities in the rules configuration are valid.
 * @param {RulesConfig} rulesConfig The rules configuration to check.
 * @returns {boolean} `true` if all severities are valid, otherwise `false`.
 */
function isEverySeverityValid(rulesConfig) {
	return Object.values(rulesConfig).every(isSeverityValid);
}

/**
 * Represents a directive comment.
 */
class DirectiveComment {
	/**
	 * The label of the directive, such as "eslint", "eslint-disable", etc.
	 * @type {string}
	 */
	label = "";

	/**
	 * The value of the directive (the string after the label).
	 * @type {string}
	 */
	value = "";

	/**
	 * The justification of the directive (the string after the --).
	 * @type {string}
	 */
	justification = "";

	/**
	 * Creates a new directive comment.
	 * @param {string} label The label of the directive.
	 * @param {string} value The value of the directive.
	 * @param {string} justification The justification of the directive.
	 */
	constructor(label, value, justification) {
		this.label = label;
		this.value = value;
		this.justification = justification;
	}
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

/**
 * Object to parse ESLint configuration comments.
 */
class ConfigCommentParser {
	/**
	 * Parses a list of "name:string_value" or/and "name" options divided by comma or
	 * whitespace. Used for "global" comments.
	 * @param {string} string The string to parse.
	 * @returns {StringConfig} Result map object of names and string values, or null values if no value was provided.
	 */
	parseStringConfig(string) {
		const items = /** @type {StringConfig} */ ({});

		// Collapse whitespace around `:` and `,` to make parsing easier
		const trimmedString = string
			.trim()
			.replace(/(?<!\s)\s*([:,])\s*/gu, "$1");

		trimmedString.split(/\s|,+/u).forEach(name => {
			if (!name) {
				return;
			}

			// value defaults to null (if not provided), e.g: "foo" => ["foo", null]
			const [key, value = null] = name.split(":");

			items[key] = value;
		});

		return items;
	}

	/**
	 * Parses a JSON-like config.
	 * @param {string} string The string to parse.
	 * @returns {({ok: true, config: RulesConfig}|{ok: false, error: {message: string}})} Result map object
	 */
	parseJSONLikeConfig(string) {
		// Parses a JSON-like comment by the same way as parsing CLI option.
		try {
			const items =
				/** @type {RulesConfig} */ (levn.parse("Object", string)) || {};

			/*
			 * When the configuration has any invalid severities, it should be completely
			 * ignored. This is because the configuration is not valid and should not be
			 * applied.
			 *
			 * For example, the following configuration is invalid:
			 *
			 *    "no-alert: 2 no-console: 2"
			 *
			 * This results in a configuration of { "no-alert": "2 no-console: 2" }, which is
			 * not valid. In this case, the configuration should be ignored.
			 */
			if (isEverySeverityValid(items)) {
				return {
					ok: true,
					config: items,
				};
			}
		} catch {
			// levn parsing error: ignore to parse the string by a fallback.
		}

		/*
		 * Optionator cannot parse commaless notations.
		 * But we are supporting that. So this is a fallback for that.
		 */
		const normalizedString = string
			.replace(/(?<![-a-zA-Z0-9/])([-a-zA-Z0-9/]+):/gu, '"$1":')
			.replace(/([\]0-9])\s+(?=")/u, "$1,");

		try {
			const items = JSON.parse(`{${normalizedString}}`);

			return {
				ok: true,
				config: items,
			};
		} catch (ex) {
			const errorMessage = ex instanceof Error ? ex.message : String(ex);

			return {
				ok: false,
				error: {
					message: `Failed to parse JSON from '${normalizedString}': ${errorMessage}`,
				},
			};
		}
	}

	/**
	 * Parses a config of values separated by comma.
	 * @param {string} string The string to parse.
	 * @returns {BooleanConfig} Result map of values and true values
	 */
	parseListConfig(string) {
		const items = /** @type {BooleanConfig} */ ({});

		string.split(",").forEach(name => {
			const trimmedName = name
				.trim()
				.replace(
					/^(?<quote>['"]?)(?<ruleId>.*)\k<quote>$/su,
					"$<ruleId>",
				);

			if (trimmedName) {
				items[trimmedName] = true;
			}
		});

		return items;
	}

	/**
	 * Extract the directive and the justification from a given directive comment and trim them.
	 * @param {string} value The comment text to extract.
	 * @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
	 */
	#extractDirectiveComment(value) {
		const match = /\s-{2,}\s/u.exec(value);

		if (!match) {
			return { directivePart: value.trim(), justificationPart: "" };
		}

		const directive = value.slice(0, match.index).trim();
		const justification = value.slice(match.index + match[0].length).trim();

		return { directivePart: directive, justificationPart: justification };
	}

	/**
	 * Parses a directive comment into directive text and value.
	 * @param {string} string The string with the directive to be parsed.
	 * @returns {DirectiveComment|undefined} The parsed directive or `undefined` if the directive is invalid.
	 */
	parseDirective(string) {
		const { directivePart, justificationPart } =
			this.#extractDirectiveComment(string);
		const match = directivesPattern.exec(directivePart);

		if (!match) {
			return undefined;
		}

		const directiveText = match[1];
		const directiveValue = directivePart.slice(
			match.index + directiveText.length,
		);

		return new DirectiveComment(
			directiveText,
			directiveValue.trim(),
			justificationPart,
		);
	}
}

/**
 * @fileoverview A collection of helper classes for implementing `SourceCode`.
 * @author Nicholas C. Zakas
 */

/* eslint class-methods-use-this: off -- Required to complete interface. */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/** @typedef {$eslintcore.VisitTraversalStep} VisitTraversalStep */
/** @typedef {$eslintcore.CallTraversalStep} CallTraversalStep */
/** @typedef {$eslintcore.TraversalStep} TraversalStep */
/** @typedef {$eslintcore.SourceLocation} SourceLocation */
/** @typedef {$eslintcore.SourceLocationWithOffset} SourceLocationWithOffset */
/** @typedef {$eslintcore.SourceRange} SourceRange */
/** @typedef {$eslintcore.Directive} IDirective */
/** @typedef {$eslintcore.DirectiveType} DirectiveType */
/** @typedef {$eslintcore.SourceCodeBaseTypeOptions} SourceCodeBaseTypeOptions */
/**
 * @typedef {import("@eslint/core").TextSourceCode<Options>} TextSourceCode<Options>
 * @template {SourceCodeBaseTypeOptions} [Options=SourceCodeBaseTypeOptions]
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

/**
 * Determines if a node has ESTree-style loc information.
 * @param {object} node The node to check.
 * @returns {node is {loc:SourceLocation}} `true` if the node has ESTree-style loc information, `false` if not.
 */
function hasESTreeStyleLoc(node) {
	return "loc" in node;
}

/**
 * Determines if a node has position-style loc information.
 * @param {object} node The node to check.
 * @returns {node is {position:SourceLocation}} `true` if the node has position-style range information, `false` if not.
 */
function hasPosStyleLoc(node) {
	return "position" in node;
}

/**
 * Determines if a node has ESTree-style range information.
 * @param {object} node The node to check.
 * @returns {node is {range:SourceRange}} `true` if the node has ESTree-style range information, `false` if not.
 */
function hasESTreeStyleRange(node) {
	return "range" in node;
}

/**
 * Determines if a node has position-style range information.
 * @param {object} node The node to check.
 * @returns {node is {position:SourceLocationWithOffset}} `true` if the node has position-style range information, `false` if not.
 */
function hasPosStyleRange(node) {
	return "position" in node;
}

/**
 * Performs binary search to find the line number containing a given target index.
 * Returns the lower bound - the index of the first element greater than the target.
 * **Please note that the `lineStartIndices` should be sorted in ascending order**.
 * - Time Complexity: O(log n) - Significantly faster than linear search for large files.
 * @param {number[]} lineStartIndices Sorted array of line start indices.
 * @param {number} targetIndex The target index to find the line number for.
 * @returns {number} The line number for the target index.
 */
function findLineNumberBinarySearch(lineStartIndices, targetIndex) {
	let low = 0;
	let high = lineStartIndices.length - 1;

	while (low < high) {
		const mid = ((low + high) / 2) | 0; // Use bitwise OR to floor the division.

		if (targetIndex < lineStartIndices[mid]) {
			high = mid;
		} else {
			low = mid + 1;
		}
	}

	return low;
}

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

/**
 * A class to represent a step in the traversal process where a node is visited.
 * @implements {VisitTraversalStep}
 */
class VisitNodeStep {
	/**
	 * The type of the step.
	 * @type {"visit"}
	 * @readonly
	 */
	type = "visit";

	/**
	 * The kind of the step. Represents the same data as the `type` property
	 * but it's a number for performance.
	 * @type {1}
	 * @readonly
	 */
	kind = 1;

	/**
	 * The target of the step.
	 * @type {object}
	 */
	target;

	/**
	 * The phase of the step.
	 * @type {1|2}
	 */
	phase;

	/**
	 * The arguments of the step.
	 * @type {Array<any>}
	 */
	args;

	/**
	 * Creates a new instance.
	 * @param {Object} options The options for the step.
	 * @param {object} options.target The target of the step.
	 * @param {1|2} options.phase The phase of the step.
	 * @param {Array<any>} options.args The arguments of the step.
	 */
	constructor({ target, phase, args }) {
		this.target = target;
		this.phase = phase;
		this.args = args;
	}
}

/**
 * A class to represent a step in the traversal process where a
 * method is called.
 * @implements {CallTraversalStep}
 */
class CallMethodStep {
	/**
	 * The type of the step.
	 * @type {"call"}
	 * @readonly
	 */
	type = "call";

	/**
	 * The kind of the step. Represents the same data as the `type` property
	 * but it's a number for performance.
	 * @type {2}
	 * @readonly
	 */
	kind = 2;

	/**
	 * The name of the method to call.
	 * @type {string}
	 */
	target;

	/**
	 * The arguments to pass to the method.
	 * @type {Array<any>}
	 */
	args;

	/**
	 * Creates a new instance.
	 * @param {Object} options The options for the step.
	 * @param {string} options.target The target of the step.
	 * @param {Array<any>} options.args The arguments of the step.
	 */
	constructor({ target, args }) {
		this.target = target;
		this.args = args;
	}
}

/**
 * A class to represent a directive comment.
 * @implements {IDirective}
 */
class Directive {
	/**
	 * The type of directive.
	 * @type {DirectiveType}
	 * @readonly
	 */
	type;

	/**
	 * The node representing the directive.
	 * @type {unknown}
	 * @readonly
	 */
	node;

	/**
	 * Everything after the "eslint-disable" portion of the directive,
	 * but before the "--" that indicates the justification.
	 * @type {string}
	 * @readonly
	 */
	value;

	/**
	 * The justification for the directive.
	 * @type {string}
	 * @readonly
	 */
	justification;

	/**
	 * Creates a new instance.
	 * @param {Object} options The options for the directive.
	 * @param {"disable"|"enable"|"disable-next-line"|"disable-line"} options.type The type of directive.
	 * @param {unknown} options.node The node representing the directive.
	 * @param {string} options.value The value of the directive.
	 * @param {string} options.justification The justification for the directive.
	 */
	constructor({ type, node, value, justification }) {
		this.type = type;
		this.node = node;
		this.value = value;
		this.justification = justification;
	}
}

/**
 * Source Code Base Object
 * @template {SourceCodeBaseTypeOptions & {RootNode: object, SyntaxElementWithLoc: object}} [Options=SourceCodeBaseTypeOptions & {RootNode: object, SyntaxElementWithLoc: object}]
 * @implements {TextSourceCode<Options>}
 */
class TextSourceCodeBase {
	/**
	 * The lines of text in the source code.
	 * @type {Array<string>}
	 */
	#lines = [];

	/**
	 * The indices of the start of each line in the source code.
	 * @type {Array<number>}
	 */
	#lineStartIndices = [0];

	/**
	 * The pattern to match lineEndings in the source code.
	 * @type {RegExp}
	 */
	#lineEndingPattern;

	/**
	 * The AST of the source code.
	 * @type {Options['RootNode']}
	 */
	ast;

	/**
	 * The text of the source code.
	 * @type {string}
	 */
	text;

	/**
	 * Creates a new instance.
	 * @param {Object} options The options for the instance.
	 * @param {string} options.text The source code text.
	 * @param {Options['RootNode']} options.ast The root AST node.
	 * @param {RegExp} [options.lineEndingPattern] The pattern to match lineEndings in the source code. Defaults to `/\r?\n/u`.
	 */
	constructor({ text, ast, lineEndingPattern = /\r?\n/u }) {
		this.ast = ast;
		this.text = text;
		// Remove the global(`g`) and sticky(`y`) flags from the `lineEndingPattern` to avoid issues with lastIndex.
		this.#lineEndingPattern = new RegExp(
			lineEndingPattern.source,
			lineEndingPattern.flags.replace(/[gy]/gu, ""),
		);
	}

	/**
	 * Finds the next line in the source text and updates `#lines` and `#lineStartIndices`.
	 * @param {string} text The text to search for the next line.
	 * @returns {boolean} `true` if a next line was found, `false` otherwise.
	 */
	#findNextLine(text) {
		const match = this.#lineEndingPattern.exec(text);

		if (!match) {
			return false;
		}

		this.#lines.push(text.slice(0, match.index));
		this.#lineStartIndices.push(
			(this.#lineStartIndices.at(-1) ?? 0) +
				match.index +
				match[0].length,
		);

		return true;
	}

	/**
	 * Ensures `#lines` is lazily calculated from the source text.
	 * @returns {void}
	 */
	#ensureLines() {
		// If `#lines` has already been calculated, do nothing.
		if (this.#lines.length === this.#lineStartIndices.length) {
			return;
		}

		while (
			this.#findNextLine(this.text.slice(this.#lineStartIndices.at(-1)))
		) {
			// Continue parsing until no more matches are found.
		}

		this.#lines.push(this.text.slice(this.#lineStartIndices.at(-1)));

		Object.freeze(this.#lines);
	}

	/**
	 * Ensures `#lineStartIndices` is lazily calculated up to the specified index.
	 * @param {number} index The index of a character in a file.
	 * @returns {void}
	 */
	#ensureLineStartIndicesFromIndex(index) {
		// If we've already parsed up to or beyond this index, do nothing.
		if (index <= (this.#lineStartIndices.at(-1) ?? 0)) {
			return;
		}

		while (
			index > (this.#lineStartIndices.at(-1) ?? 0) &&
			this.#findNextLine(this.text.slice(this.#lineStartIndices.at(-1)))
		) {
			// Continue parsing until no more matches are found.
		}
	}

	/**
	 * Ensures `#lineStartIndices` is lazily calculated up to the specified loc.
	 * @param {Object} loc A line/column location.
	 * @param {number} loc.line The line number of the location. (0 or 1-indexed based on language.)
	 * @param {number} lineStart The line number at which the parser starts counting.
	 * @returns {void}
	 */
	#ensureLineStartIndicesFromLoc(loc, lineStart) {
		// Calculate line indices up to the potentially next line, as it is needed for the follow‑up calculation.
		const nextLocLineIndex = loc.line - lineStart + 1;
		const lastCalculatedLineIndex = this.#lineStartIndices.length - 1;
		let additionalLinesNeeded = nextLocLineIndex - lastCalculatedLineIndex;

		// If we've already parsed up to or beyond this line, do nothing.
		if (additionalLinesNeeded <= 0) {
			return;
		}

		while (
			additionalLinesNeeded > 0 &&
			this.#findNextLine(this.text.slice(this.#lineStartIndices.at(-1)))
		) {
			// Continue parsing until no more matches are found or we have enough lines.
			additionalLinesNeeded -= 1;
		}
	}

	/**
	 * Returns the loc information for the given node or token.
	 * @param {Options['SyntaxElementWithLoc']} nodeOrToken The node or token to get the loc information for.
	 * @returns {SourceLocation} The loc information for the node or token.
	 * @throws {Error} If the node or token does not have loc information.
	 */
	getLoc(nodeOrToken) {
		if (hasESTreeStyleLoc(nodeOrToken)) {
			return nodeOrToken.loc;
		}

		if (hasPosStyleLoc(nodeOrToken)) {
			return nodeOrToken.position;
		}

		throw new Error(
			"Custom getLoc() method must be implemented in the subclass.",
		);
	}

	/**
	 * Converts a source text index into a `{ line: number, column: number }` pair.
	 * @param {number} index The index of a character in a file.
	 * @throws {TypeError|RangeError} If non-numeric index or index out of range.
	 * @returns {{line: number, column: number}} A `{ line: number, column: number }` location object with 0 or 1-indexed line and 0 or 1-indexed column based on language.
	 * @public
	 */
	getLocFromIndex(index) {
		if (typeof index !== "number") {
			throw new TypeError("Expected `index` to be a number.");
		}

		if (index < 0 || index > this.text.length) {
			throw new RangeError(
				`Index out of range (requested index ${index}, but source text has length ${this.text.length}).`,
			);
		}

		const {
			start: { line: lineStart, column: columnStart },
			end: { line: lineEnd, column: columnEnd },
		} = this.getLoc(this.ast);

		// If the index is at the start, return the start location of the root node.
		if (index === 0) {
			return {
				line: lineStart,
				column: columnStart,
			};
		}

		// If the index is `this.text.length`, return the location one "spot" past the last character of the file.
		if (index === this.text.length) {
			return {
				line: lineEnd,
				column: columnEnd,
			};
		}

		// Ensure `#lineStartIndices` are lazily calculated.
		this.#ensureLineStartIndicesFromIndex(index);

		/*
		 * To figure out which line `index` is on, determine the last place at which index could
		 * be inserted into `#lineStartIndices` to keep the list sorted.
		 */
		const lineNumber =
			(index >= (this.#lineStartIndices.at(-1) ?? 0)
				? this.#lineStartIndices.length
				: findLineNumberBinarySearch(this.#lineStartIndices, index)) -
			1 +
			lineStart;

		return {
			line: lineNumber,
			column:
				index -
				this.#lineStartIndices[lineNumber - lineStart] +
				columnStart,
		};
	}

	/**
	 * Converts a `{ line: number, column: number }` pair into a source text index.
	 * @param {Object} loc A line/column location.
	 * @param {number} loc.line The line number of the location. (0 or 1-indexed based on language.)
	 * @param {number} loc.column The column number of the location. (0 or 1-indexed based on language.)
	 * @throws {TypeError|RangeError} If `loc` is not an object with a numeric
	 * `line` and `column`, if the `line` is less than or equal to zero or
	 * the `line` or `column` is out of the expected range.
	 * @returns {number} The index of the line/column location in a file.
	 * @public
	 */
	getIndexFromLoc(loc) {
		if (
			loc === null ||
			typeof loc !== "object" ||
			typeof loc.line !== "number" ||
			typeof loc.column !== "number"
		) {
			throw new TypeError(
				"Expected `loc` to be an object with numeric `line` and `column` properties.",
			);
		}

		const {
			start: { line: lineStart, column: columnStart },
			end: { line: lineEnd, column: columnEnd },
		} = this.getLoc(this.ast);

		if (loc.line < lineStart || lineEnd < loc.line) {
			throw new RangeError(
				`Line number out of range (line ${loc.line} requested). Valid range: ${lineStart}-${lineEnd}`,
			);
		}

		// If the loc is at the start, return the start index of the root node.
		if (loc.line === lineStart && loc.column === columnStart) {
			return 0;
		}

		// If the loc is at the end, return the index one "spot" past the last character of the file.
		if (loc.line === lineEnd && loc.column === columnEnd) {
			return this.text.length;
		}

		// Ensure `#lineStartIndices` are lazily calculated.
		this.#ensureLineStartIndicesFromLoc(loc, lineStart);

		const isLastLine = loc.line === lineEnd;
		const lineStartIndex = this.#lineStartIndices[loc.line - lineStart];
		const lineEndIndex = isLastLine
			? this.text.length
			: this.#lineStartIndices[loc.line - lineStart + 1];
		const positionIndex = lineStartIndex + loc.column - columnStart;

		if (
			loc.column < columnStart ||
			(isLastLine && positionIndex > lineEndIndex) ||
			(!isLastLine && positionIndex >= lineEndIndex)
		) {
			throw new RangeError(
				`Column number out of range (column ${loc.column} requested). Valid range for line ${loc.line}: ${columnStart}-${lineEndIndex - lineStartIndex + columnStart + (isLastLine ? 0 : -1)}`,
			);
		}

		return positionIndex;
	}

	/**
	 * Returns the range information for the given node or token.
	 * @param {Options['SyntaxElementWithLoc']} nodeOrToken The node or token to get the range information for.
	 * @returns {SourceRange} The range information for the node or token.
	 * @throws {Error} If the node or token does not have range information.
	 */
	getRange(nodeOrToken) {
		if (hasESTreeStyleRange(nodeOrToken)) {
			return nodeOrToken.range;
		}

		if (hasPosStyleRange(nodeOrToken)) {
			return [
				nodeOrToken.position.start.offset,
				nodeOrToken.position.end.offset,
			];
		}

		throw new Error(
			"Custom getRange() method must be implemented in the subclass.",
		);
	}

	/* eslint-disable no-unused-vars -- Required to complete interface. */
	/**
	 * Returns the parent of the given node.
	 * @param {Options['SyntaxElementWithLoc']} node The node to get the parent of.
	 * @returns {Options['SyntaxElementWithLoc']|undefined} The parent of the node.
	 * @throws {Error} If the method is not implemented in the subclass.
	 */
	getParent(node) {
		throw new Error("Not implemented.");
	}
	/* eslint-enable no-unused-vars -- Required to complete interface. */

	/**
	 * Gets all the ancestors of a given node
	 * @param {Options['SyntaxElementWithLoc']} node The node
	 * @returns {Array<Options['SyntaxElementWithLoc']>} All the ancestor nodes in the AST, not including the provided node, starting
	 * from the root node at index 0 and going inwards to the parent node.
	 * @throws {TypeError} When `node` is missing.
	 */
	getAncestors(node) {
		if (!node) {
			throw new TypeError("Missing required argument: node.");
		}

		const ancestorsStartingAtParent = [];

		for (
			let ancestor = this.getParent(node);
			ancestor;
			ancestor = this.getParent(ancestor)
		) {
			ancestorsStartingAtParent.push(ancestor);
		}

		return ancestorsStartingAtParent.reverse();
	}

	/**
	 * Gets the source code for the given node.
	 * @param {Options['SyntaxElementWithLoc']} [node] The AST node to get the text for.
	 * @param {number} [beforeCount] The number of characters before the node to retrieve.
	 * @param {number} [afterCount] The number of characters after the node to retrieve.
	 * @returns {string} The text representing the AST node.
	 * @public
	 */
	getText(node, beforeCount, afterCount) {
		if (node) {
			const range = this.getRange(node);
			return this.text.slice(
				Math.max(range[0] - (beforeCount || 0), 0),
				range[1] + (afterCount || 0),
			);
		}
		return this.text;
	}

	/**
	 * Gets the entire source text split into an array of lines.
	 * @returns {Array<string>} The source text as an array of lines.
	 * @public
	 */
	get lines() {
		this.#ensureLines(); // Ensure `#lines` is lazily calculated.

		return this.#lines;
	}

	/**
	 * Traverse the source code and return the steps that were taken.
	 * @returns {Iterable<TraversalStep>} The steps that were taken while traversing the source code.
	 */
	traverse() {
		throw new Error("Not implemented.");
	}
}

exports.CallMethodStep = CallMethodStep;
exports.ConfigCommentParser = ConfigCommentParser;
exports.Directive = Directive;
exports.TextSourceCodeBase = TextSourceCodeBase;
exports.VisitNodeStep = VisitNodeStep;
