*_iterateFilesRecursive(directoryPath, options) {
		debug(`Enter the directory: ${directoryPath}`);
		const { configArrayFactory } = internalSlotsMap.get(this);

		/** @type {ConfigArray|null} */
		let config = null;

		// Enumerate the files of this directory.
		for (const entry of readdirSafeSync(directoryPath)) {
			const filePath = path.join(directoryPath, entry.name);
			const fileInfo = entry.isSymbolicLink()
				? statSafeSync(filePath)
				: entry;

			if (!fileInfo) {
				continue;
			}

			// Check if the file is matched.
			if (fileInfo.isFile()) {
				if (!config) {
					config = configArrayFactory.getConfigArrayForFile(
						filePath,

						/*
						 * We must ignore `ConfigurationNotFoundError` at this
						 * point because we don't know if target files exist in
						 * this directory.
						 */
						{ ignoreNotFoundError: true },
					);
				}
				const matched = options.selector
					? // Started with a glob pattern; choose by the pattern.
						options.selector.match(filePath)
					: // Started with a directory path; choose by file extensions.
						this.isTargetPath(filePath, config);

				if (matched) {
					const ignored = this._isIgnoredFile(filePath, {
						...options,
						config,
					});
					const flag = ignored ? IGNORED_SILENTLY : NONE;

					debug(
						`Yield: ${entry.name}${ignored ? " but ignored" : ""}`,
					);
					yield {
						config: configArrayFactory.getConfigArrayForFile(
							filePath,
						),
						filePath,
						flag,
					};
				} else {
					debug(`Didn't match: ${entry.name}`);
				}

				// Dive into the sub directory.
			} else if (options.recursive && fileInfo.isDirectory()) {
				if (!config) {
					config = configArrayFactory.getConfigArrayForFile(
						filePath,
						{ ignoreNotFoundError: true },
					);
				}
				const ignored = this._isIgnoredFile(filePath + path.sep, {
					...options,
					config,
				});

				if (!ignored) {
					yield* this._iterateFilesRecursive(filePath, options);
				}
			}
		}

		debug(`Leave the directory: ${directoryPath}`);
	}
Iterate files in a given path.
@param {string} directoryPath The path to the target directory.
@param {Object} options The options to iterate files.
@param {boolean} [options.dotfiles] If `true` then it doesn't skip dot files by default.
@param {boolean} [options.recursive] If `true` then it dives into sub directories.
@param {InstanceType<Minimatch>} [options.selector] The matcher to choose files.
@returns {IterableIterator<FileEntry>} The found files.
@private