Repository: eslint/eslint
File: lib/rules/utils/ast-utils.js (JavaScript)

Code before:
				isReferenceToGlobalVariable(scope, node)
			);

		// no default
	}
	return false;
}

/**
 * Checks whether a node is an ExpressionStatement at the top level of a file or function body.
 * A top-level ExpressionStatement node is a directive if it contains a single unparenthesized
 * string literal and if it occurs either as the first sibling or immediately after another
 * directive.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} Whether or not the node is an ExpressionStatement at the top level of a
 * file or function body.
 */
function isTopLevelExpressionStatement(node) {
	if (node.type !== "ExpressionStatement") {
		return false;
	}
	const parent = node.parent;

	return (
		parent.type === "Program" ||
		(parent.type === "BlockStatement" && isFunction(parent.parent))
	);
}

/**
 * Check whether the given node is a part of a directive prologue or not.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} `true` if the node is a part of directive prologue.
 */
function isDirective(node) {
	return (
		node.type === "ExpressionStatement" &&
		typeof node.directive === "string"
	);
}

/**
 * Tests if a node appears at the beginning of an ancestor ExpressionStatement node.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} Whether the node appears at the beginning of an ancestor ExpressionStatement node.
 */
function isStartOfExpressionStatement(node) {
	const start = node.range[0];
	let ancestor = node;

	while ((ancestor = ancestor.parent) && ancestor.range[0] === start) {

Review comment (suggestion):
I think we should keep this, so that checking TypeScript code works well with `{ "ignoreDirectives": true }`.

Code after:
				isReferenceToGlobalVariable(scope, node)
			);

		// no default
	}
	return false;
}

/**
 * Checks whether a node is an ExpressionStatement at the top level of a file, function body, or TypeScript module block.
 * A top-level ExpressionStatement node is a directive if it contains a single unparenthesized
 * string literal and if it occurs either as the first sibling or immediately after another
 * directive.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} Whether or not the node is an ExpressionStatement at the top level of a
 * file, function body, or TypeScript module block.
 */
function isTopLevelExpressionStatement(node) {
	if (node.type !== "ExpressionStatement") {
		return false;
	}
	const parent = node.parent;

	return (
		parent.type === "Program" ||
		parent.type === "TSModuleBlock" ||
		(parent.type === "BlockStatement" && isFunction(parent.parent))
	);
}

/**
 * Check whether the given node is a part of a directive prologue or not.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} `true` if the node is a part of directive prologue.
 */
function isDirective(node) {
	return (
		node.type === "ExpressionStatement" &&
		typeof node.directive === "string"
	);
}

/**
 * Tests if a node appears at the beginning of an ancestor ExpressionStatement node.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} Whether the node appears at the beginning of an ancestor ExpressionStatement node.
 */
function isStartOfExpressionStatement(node) {
	const start = node.range[0];
	let ancestor = node;