text: /**
   * @fileoverview Tools for obtaining SourceCode objects.
   * @author Ian VanSchooten
   */
  
  "use strict";
  
  //------------------------------------------------------------------------------
  // Requirements
  //------------------------------------------------------------------------------
  
  const { CLIEngine } = require("../cli-engine");
  
  /*
   * This is used for:
   *
   * 1. Enumerate target file because we have not expose such a API on `CLIEngine`
   *    (https://github.com/eslint/eslint/issues/11222).
   * 2. Create `SourceCode` instances. Because we don't have any function which
   *    instantiate `SourceCode` so it needs to take the created `SourceCode`
   *    instance out after linting.
   *
   * TODO1: Expose the API that enumerates target files.
   * TODO2: Extract the creation logic of `SourceCode` from `Linter` class.
   */
  const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line no-restricted-modules
  
  const debug = require("debug")("eslint:source-code-utils");
  
  //------------------------------------------------------------------------------
  // Helpers
  //------------------------------------------------------------------------------
  
  /**
   * Get the SourceCode object for a single file
   * @param   {string}     filename The fully resolved filename to get SourceCode from.
   * @param   {Object}     engine  A CLIEngine.
   * @returns {Array}               Array of the SourceCode object representing the file
   *                                and fatal error message.
   */
  function getSourceCodeOfFile(filename, engine) {
      debug("getting sourceCode of", filename);
      const results = engine.executeOnFiles([filename]);
  
      if (results && results.results[0] && results.results[0].messages[0] && results.results[0].messages[0].fatal) {
          const msg = results.results[0].messages[0];
  
          throw new Error(`(${filename}:${msg.line}:${msg.column}) ${msg.message}`);
      }
  
      // TODO: extract the logic that creates source code objects to `SourceCode#parse(text, options)` or something like.
      const { linter } = getCLIEngineInternalSlots(engine);
      const sourceCode = linter.getSourceCode();
  
      return sourceCode;
  }
  
  //------------------------------------------------------------------------------
  // Public Interface
  //------------------------------------------------------------------------------
  
  
  /**
   * This callback is used to measure execution status in a progress bar
   * @callback progressCallback
   * @param {number} The total number of times the callback will be called.
   */
  
  /**
   * Gets the SourceCode of a single file, or set of files.
   * @param {string[]|string} patterns A filename, directory name, or glob, or an array of them
   * @param {Object} options A CLIEngine options object. If not provided, the default cli options will be used.
   * @param {progressCallback} callback Callback for reporting execution status
   * @returns {Object} The SourceCode of all processed files.
   */
  function getSourceCodeOfFiles(patterns, options, callback) {
      const sourceCodes = {};
      const globPatternsList = typeof patterns === "string" ? [patterns] : patterns;
      const engine = new CLIEngine({ ...options, rules: {} });
  
      // TODO: make file iteration as a public API and use it.
      const { fileEnumerator } = getCLIEngineInternalSlots(engine);
      const filenames =
          Array.from(fileEnumerator.iterateFiles(globPatternsList))
              .filter(entry => !entry.ignored)
              .map(entry => entry.filePath);
  
      if (filenames.length === 0) {
          debug(`Did not find any files matching pattern(s): ${globPatternsList}`);
      }
  
      filenames.forEach(filename => {
          const sourceCode = getSourceCodeOfFile(filename, engine);
  
          if (sourceCode) {
              debug("got sourceCode of", filename);
              sourceCodes[filename] = sourceCode;
          }
          if (callback) {
              callback(filenames.length); // eslint-disable-line callback-return
          }
      });
  
      return sourceCodes;
  }
  
  module.exports = {
      getSourceCodeOfFiles
  };
  