| /** |
| * @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 |
| }; |