function getDirectiveComments(
	sourceCode,
	ruleMapper,
	warnInlineConfig,
	config,
) {
	const configuredRules = {};
	const enabledGlobals = Object.create(null);
	const exportedVariables = {};
	const problems = [];
	const disableDirectives = [];
	const validator = new ConfigValidator({
		builtInRules: Rules,
	});

	sourceCode
		.getInlineConfigNodes()
		.filter(token => token.type !== "Shebang")
		.forEach(comment => {
			const directive = commentParser.parseDirective(comment.value);

			if (!directive) {
				return;
			}

			const {
				label,
				value,
				justification: justificationPart,
			} = directive;

			const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(
				label,
			);

			if (comment.type === "Line" && !lineCommentSupported) {
				return;
			}

			const loc = sourceCode.getLoc(comment);

			if (warnInlineConfig) {
				const kind =
					comment.type === "Block" ? `/*${label}*/` : `//${label}`;

				problems.push(
					createLintingProblem({
						ruleId: null,
						message: `'${kind}' has no effect because you have 'noInlineConfig' setting in ${warnInlineConfig}.`,
						loc,
						severity: 1,
					}),
				);
				return;
			}

			if (
				label === "eslint-disable-line" &&
				loc.start.line !== loc.end.line
			) {
				const message = `${label} comment should not span multiple lines.`;

				problems.push(
					createLintingProblem({
						ruleId: null,
						message,
						loc,
					}),
				);
				return;
			}

			switch (label) {
				case "eslint-disable":
				case "eslint-enable":
				case "eslint-disable-next-line":
				case "eslint-disable-line": {
					const directiveType = label.slice("eslint-".length);
					const { directives, directiveProblems } =
						createDisableDirectives(
							{
								type: directiveType,
								value,
								justification: justificationPart,
								node: comment,
							},
							ruleMapper,
							jslang,
							sourceCode,
						);

					disableDirectives.push(...directives);
					problems.push(...directiveProblems);
					break;
				}

				case "exported":
					Object.assign(
						exportedVariables,
						commentParser.parseListConfig(value),
					);
					break;

				case "globals":
				case "global":
					for (const [id, idSetting] of Object.entries(
						commentParser.parseStringConfig(value),
					)) {
						let normalizedValue;

						try {
							normalizedValue =
								ConfigOps.normalizeConfigGlobal(idSetting);
						} catch (err) {
							problems.push(
								createLintingProblem({
									ruleId: null,
									loc,
									message: err.message,
								}),
							);
							continue;
						}

						if (enabledGlobals[id]) {
							enabledGlobals[id].comments.push(comment);
							enabledGlobals[id].value = normalizedValue;
						} else {
							enabledGlobals[id] = {
								comments: [comment],
								value: normalizedValue,
							};
						}
					}
					break;

				case "eslint": {
					const parseResult =
						commentParser.parseJSONLikeConfig(value);

					if (parseResult.ok) {
						Object.keys(parseResult.config).forEach(name => {
							const rule = ruleMapper(name);
							const ruleValue = parseResult.config[name];

							if (!rule) {
								problems.push(
									createLintingProblem({ ruleId: name, loc }),
								);
								return;
							}

							if (Object.hasOwn(configuredRules, name)) {
								problems.push(
									createLintingProblem({
										message: `Rule "${name}" is already configured by another configuration comment in the preceding code. This configuration is ignored.`,
										loc,
									}),
								);
								return;
							}

							let ruleOptions = asArray(ruleValue);

							/*
							 * If the rule was already configured, inline rule configuration that
							 * only has severity should retain options from the config and just override the severity.
							 *
							 * Example:
							 *
							 *   {
							 *       rules: {
							 *           curly: ["error", "multi"]
							 *       }
							 *   }
							 *
							 *   /* eslint curly: ["warn"] * /
							 *
							 *   Results in:
							 *
							 *   curly: ["warn", "multi"]
							 */
							if (
								/*
								 * If inline config for the rule has only severity
								 */
								ruleOptions.length === 1 &&
								/*
								 * And the rule was already configured
								 */
								config.rules &&
								Object.hasOwn(config.rules, name)
							) {
								/*
								 * Then use severity from the inline config and options from the provided config
								 */
								ruleOptions = [
									ruleOptions[0], // severity from the inline config
									...asArray(config.rules[name]).slice(1), // options from the provided config
								];
							}

							try {
								validator.validateRuleOptions(
									rule,
									name,
									ruleOptions,
								);
							} catch (err) {
								/*
								 * If the rule has invalid `meta.schema`, throw the error because
								 * this is not an invalid inline configuration but an invalid rule.
								 */
								if (
									err.code ===
									"ESLINT_INVALID_RULE_OPTIONS_SCHEMA"
								) {
									throw err;
								}

								problems.push(
									createLintingProblem({
										ruleId: name,
										message: err.message,
										loc,
									}),
								);

								// do not apply the config, if found invalid options.
								return;
							}

							configuredRules[name] = ruleOptions;
						});
					} else {
						const problem = createLintingProblem({
							ruleId: null,
							loc,
							message: parseResult.error.message,
						});

						problem.fatal = true;
						problems.push(problem);
					}

					break;
				}

				// no default
			}
		});

	return {
		configuredRules,
		enabledGlobals,
		exportedVariables,
		problems,
		disableDirectives,
	};
}
Parses comments in file to extract file-specific config of rules, globals
and environments and merges them with global config; also code blocks
where reporting is disabled or enabled and merges them with reporting config.
@param {SourceCode} sourceCode The SourceCode object to get comments from.
@param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
@param {string|null} warnInlineConfig If a string then it should warn directive comments as disabled. The string value is the config name what the setting came from.
@param {ConfigData} config Provided config.
@returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems: LintMessage[], disableDirectives: DisableDirective[]}}
A collection of the directive comments that were found, along with any problems that occurred when parsing