.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / cli-engine / formatters / codeframe.js
1 /**
2  * @fileoverview Codeframe reporter
3  * @author Vitor Balocco
4  */
5 "use strict";
6
7 const chalk = require("chalk");
8 const { codeFrameColumns } = require("@babel/code-frame");
9 const path = require("path");
10
11 //------------------------------------------------------------------------------
12 // Helpers
13 //------------------------------------------------------------------------------
14
15 /**
16  * Given a word and a count, append an s if count is not one.
17  * @param   {string} word  A word in its singular form.
18  * @param   {number} count A number controlling whether word should be pluralized.
19  * @returns {string}       The original word with an s on the end if count is not one.
20  */
21 function pluralize(word, count) {
22     return (count === 1 ? word : `${word}s`);
23 }
24
25 /**
26  * Gets a formatted relative file path from an absolute path and a line/column in the file.
27  * @param   {string} filePath The absolute file path to format.
28  * @param   {number} line     The line from the file to use for formatting.
29  * @param   {number} column   The column from the file to use for formatting.
30  * @returns {string}          The formatted file path.
31  */
32 function formatFilePath(filePath, line, column) {
33     let relPath = path.relative(process.cwd(), filePath);
34
35     if (line && column) {
36         relPath += `:${line}:${column}`;
37     }
38
39     return chalk.green(relPath);
40 }
41
42 /**
43  * Gets the formatted output for a given message.
44  * @param   {Object} message      The object that represents this message.
45  * @param   {Object} parentResult The result object that this message belongs to.
46  * @returns {string}              The formatted output.
47  */
48 function formatMessage(message, parentResult) {
49     const type = (message.fatal || message.severity === 2) ? chalk.red("error") : chalk.yellow("warning");
50     const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/u, "$1"))}`;
51     const ruleId = message.fatal ? "" : chalk.dim(`(${message.ruleId})`);
52     const filePath = formatFilePath(parentResult.filePath, message.line, message.column);
53     const sourceCode = parentResult.output ? parentResult.output : parentResult.source;
54
55     const firstLine = [
56         `${type}:`,
57         `${msg}`,
58         ruleId ? `${ruleId}` : "",
59         sourceCode ? `at ${filePath}:` : `at ${filePath}`
60     ].filter(String).join(" ");
61
62     const result = [firstLine];
63
64     if (sourceCode) {
65         result.push(
66             codeFrameColumns(sourceCode, { start: { line: message.line, column: message.column } }, { highlightCode: false })
67         );
68     }
69
70     return result.join("\n");
71 }
72
73 /**
74  * Gets the formatted output summary for a given number of errors and warnings.
75  * @param   {number} errors   The number of errors.
76  * @param   {number} warnings The number of warnings.
77  * @param   {number} fixableErrors The number of fixable errors.
78  * @param   {number} fixableWarnings The number of fixable warnings.
79  * @returns {string}          The formatted output summary.
80  */
81 function formatSummary(errors, warnings, fixableErrors, fixableWarnings) {
82     const summaryColor = errors > 0 ? "red" : "yellow";
83     const summary = [];
84     const fixablesSummary = [];
85
86     if (errors > 0) {
87         summary.push(`${errors} ${pluralize("error", errors)}`);
88     }
89
90     if (warnings > 0) {
91         summary.push(`${warnings} ${pluralize("warning", warnings)}`);
92     }
93
94     if (fixableErrors > 0) {
95         fixablesSummary.push(`${fixableErrors} ${pluralize("error", fixableErrors)}`);
96     }
97
98     if (fixableWarnings > 0) {
99         fixablesSummary.push(`${fixableWarnings} ${pluralize("warning", fixableWarnings)}`);
100     }
101
102     let output = chalk[summaryColor].bold(`${summary.join(" and ")} found.`);
103
104     if (fixableErrors || fixableWarnings) {
105         output += chalk[summaryColor].bold(`\n${fixablesSummary.join(" and ")} potentially fixable with the \`--fix\` option.`);
106     }
107
108     return output;
109 }
110
111 //------------------------------------------------------------------------------
112 // Public Interface
113 //------------------------------------------------------------------------------
114
115 module.exports = function(results) {
116     let errors = 0;
117     let warnings = 0;
118     let fixableErrors = 0;
119     let fixableWarnings = 0;
120
121     const resultsWithMessages = results.filter(result => result.messages.length > 0);
122
123     let output = resultsWithMessages.reduce((resultsOutput, result) => {
124         const messages = result.messages.map(message => `${formatMessage(message, result)}\n\n`);
125
126         errors += result.errorCount;
127         warnings += result.warningCount;
128         fixableErrors += result.fixableErrorCount;
129         fixableWarnings += result.fixableWarningCount;
130
131         return resultsOutput.concat(messages);
132     }, []).join("\n");
133
134     output += "\n";
135     output += formatSummary(errors, warnings, fixableErrors, fixableWarnings);
136
137     return (errors + warnings) > 0 ? output : "";
138 };