diff --git a/.eslintrc.js b/.eslintrc.js index c9533359..9bf4200c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,6 @@ module.exports = { parserOptions: { - ecmaVersion: 8, + ecmaVersion: 2020, }, env: { browser: false, diff --git a/README.md b/README.md index c734a921..507c31e8 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Linter for Solidity programming language Options: -V, --version output the version number - -f, --formatter [name] report formatter name (stylish, table, tap, unix) + -f, --formatter [name] report formatter name (stylish, table, tap, unix, json) -w, --max-warnings [maxWarningsNumber] number of allowed warnings -c, --config [file_name] file to use as your .solhint.json -q, --quiet report errors only - default: false @@ -68,7 +68,9 @@ Commands: stdin [options] linting of source code data provided to STDIN ``` - +### Note +The `--fix` option currently works only on "avoid-throw" and "avoid-sha3" rules +

## Configuration You can use a `.solhint.json` file to configure Solhint for the whole project. @@ -86,6 +88,10 @@ This file has the following format: "extends": "solhint:default" } ``` +### Note +The `solhint:default` configuration contains only two rules: max-line-length & no-console +

+ ### Sample ```json diff --git a/docs/rules.md b/docs/rules.md index 65aacdf3..4868aab8 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -15,6 +15,7 @@ title: "Rule Index of Solhint" | [no-console](./rules/best-practises/no-console.md) | No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements | ✔️ | | [no-empty-blocks](./rules/best-practises/no-empty-blocks.md) | Code contains empty block. | ✔️ | | [no-global-import](./rules/best-practises/no-global-import.md) | Import statement includes an entire file instead of selected symbols | ✔️ | +| [no-unused-import](./rules/best-practises/no-unused-import.md) | Imported name is not used | ✔️ | | [no-unused-vars](./rules/best-practises/no-unused-vars.md) | Variable "name" is unused. | ✔️ | | [payable-fallback](./rules/best-practises/payable-fallback.md) | When fallback is not payable you will not be able to receive ethers. | ✔️ | | [reason-string](./rules/best-practises/reason-string.md) | Require or revert statement must have a reason string and check that each reason string is at most N characters long. | ✔️ | @@ -26,13 +27,13 @@ title: "Rule Index of Solhint" | Rule Id | Error | Recommended | | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | [comprehensive-interface](./rules/miscellaneous/comprehensive-interface.md) | Check that all public or external functions are override. This is iseful to make sure that the whole API is extracted in an interface. | | +| [quotes](./rules/miscellaneous/quotes.md) | Use double quotes for string literals. Values must be 'single' or 'double'. | ✔️ | ## Style Guide Rules | Rule Id | Error | Recommended | | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ----------- | -| [quotes](./rules/miscellaneous/quotes.md) | Use double quotes for string literals. Values must be 'single' or 'double'. | ✔️ | | [const-name-snakecase](./rules/naming/const-name-snakecase.md) | Constant name must be in capitalized SNAKE_CASE. | ✔️ | | [contract-name-camelcase](./rules/naming/contract-name-camelcase.md) | Contract name must be in CamelCase. | ✔️ | | [event-name-camelcase](./rules/naming/event-name-camelcase.md) | Event name must be in CamelCase. | ✔️ | diff --git a/docs/rules/best-practises/no-unused-import.md b/docs/rules/best-practises/no-unused-import.md new file mode 100644 index 00000000..e03199a1 --- /dev/null +++ b/docs/rules/best-practises/no-unused-import.md @@ -0,0 +1,39 @@ +--- +warning: "This is a dynamically generated file. Do not edit manually." +layout: "default" +title: "no-unused-import | Solhint" +--- + +# no-unused-import +![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen) +![Category Badge](https://img.shields.io/badge/-Best%20Practise%20Rules-informational) +![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow) +> The {"extends": "solhint:recommended"} property in a configuration file enables this rule. + + +## Description +Imported name is not used + +## Options +This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn. + +### Example Config +```json +{ + "rules": { + "no-unused-import": "warn" + } +} +``` + + +## Examples +This rule does not have examples. + +## Version +This rule is introduced in the latest version. + +## Resources +- [Rule source](https://github.com/protofire/solhint/tree/master/lib/rules/best-practises/no-unused-import.js) +- [Document source](https://github.com/protofire/solhint/tree/master/docs/rules/best-practises/no-unused-import.md) +- [Test cases](https://github.com/protofire/solhint/tree/master/test/rules/best-practises/no-unused-import.js) diff --git a/docs/rules/miscellaneous/quotes.md b/docs/rules/miscellaneous/quotes.md index 94cfb3d4..e260f159 100644 --- a/docs/rules/miscellaneous/quotes.md +++ b/docs/rules/miscellaneous/quotes.md @@ -6,7 +6,7 @@ title: "quotes | Solhint" # quotes ![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen) -![Category Badge](https://img.shields.io/badge/-Style%20Guide%20Rules-informational) +![Category Badge](https://img.shields.io/badge/-Miscellaneous-informational) ![Default Severity Badge error](https://img.shields.io/badge/Default%20Severity-error-red) > The {"extends": "solhint:recommended"} property in a configuration file enables this rule. diff --git a/lib/formatters/README.md b/lib/formatters/README.md index 44124326..5c0b4152 100644 --- a/lib/formatters/README.md +++ b/lib/formatters/README.md @@ -6,4 +6,4 @@ files in this directory are pulled from eslint repository: - unix.js: eslint v8.32.0 oshi-shinobu - tap.js: eslint v8.32.0 Jonathan Kingston - stylish.js: eslint v8.32.0 by Sindre Sorhus - +- json.js: eslint v8.32.0 by Artur Lukianov & Diego Bale diff --git a/lib/formatters/json.js b/lib/formatters/json.js new file mode 100644 index 00000000..d46c7ed8 --- /dev/null +++ b/lib/formatters/json.js @@ -0,0 +1,42 @@ +/** + * @fileoverview JSON Style formatter + * @author ArturLukianov + * @collaborator Diego Bale + */ + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +/** + * Returns a canonical error level string based upon the error message passed in. + * @param {Object} message Individual error message provided by eslint + * @returns {string} Error level string + */ +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return 'Error' + } + return 'Warning' +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +// eslint-disable-next-line func-names +module.exports = function (results) { + const allMessages = [] + + results.forEach((result) => { + const messages = result.messages + + messages.forEach((message) => { + const fullObject = { ...message, filePath: result.filePath } + fullObject.severity = getMessageType(fullObject) + allMessages.push(fullObject) + }) + }) + + return JSON.parse(JSON.stringify(allMessages)) +} diff --git a/lib/formatters/stylish.js b/lib/formatters/stylish.js index d3d323f7..02bf8cb3 100644 --- a/lib/formatters/stylish.js +++ b/lib/formatters/stylish.js @@ -1,5 +1,5 @@ /** - * @fileoverview Stylish reporter + * @fileoverview Stylish Style formatter * @author Sindre Sorhus */ @@ -25,7 +25,8 @@ function pluralize(word, count) { // Public Interface //------------------------------------------------------------------------------ -module.exports = function (results) { // eslint-disable-line +// eslint-disable-next-line func-names +module.exports = function (results) { let output = '\n' let errorCount = 0 let warningCount = 0 diff --git a/lib/formatters/table.js b/lib/formatters/table.js index 274b8bee..12bdc45b 100644 --- a/lib/formatters/table.js +++ b/lib/formatters/table.js @@ -1,5 +1,5 @@ /** - * @fileoverview "table reporter. + * @fileoverview Table Style formatter * @author Gajus Kuizinas */ @@ -108,7 +108,8 @@ function drawReport(results) { // Public Interface //------------------------------------------------------------------------------ -module.exports = function (report) { // eslint-disable-line +// eslint-disable-next-line func-names +module.exports = function (report) { let result let errorCount let warningCount diff --git a/lib/formatters/tap.js b/lib/formatters/tap.js index d4933cbb..67f06aa3 100644 --- a/lib/formatters/tap.js +++ b/lib/formatters/tap.js @@ -1,5 +1,5 @@ /** - * @fileoverview TAP reporter + * @fileoverview TAP Style formatter * @author Jonathan Kingston */ @@ -39,7 +39,8 @@ function outputDiagnostics(diagnostic) { // Public Interface //------------------------------------------------------------------------------ -module.exports = function (results) { // eslint-disable-line +// eslint-disable-next-line func-names +module.exports = function (results) { let output = `TAP version 13\n1..${results.length}\n` results.forEach((result, id) => { diff --git a/lib/formatters/unix.js b/lib/formatters/unix.js index 95be0f39..0029088e 100644 --- a/lib/formatters/unix.js +++ b/lib/formatters/unix.js @@ -1,5 +1,5 @@ /** - * @fileoverview unix-style formatter. + * @fileoverview Unix Style formatter * @author oshi-shinobu */ @@ -23,7 +23,8 @@ function getMessageType(message) { // Public Interface //------------------------------------------------------------------------------ -module.exports = function (results) { // eslint-disable-line +// eslint-disable-next-line func-names +module.exports = function (results) { let output = '' let total = 0 diff --git a/lib/rules/miscellaneous/quotes.js b/lib/rules/miscellaneous/quotes.js index b53b2bad..4212ea38 100644 --- a/lib/rules/miscellaneous/quotes.js +++ b/lib/rules/miscellaneous/quotes.js @@ -10,7 +10,7 @@ const meta = { docs: { description: `Use double quotes for string literals. Values must be 'single' or 'double'.`, - category: 'Style Guide Rules', + category: 'Miscellaneous', options: [ { description: severityDescription, diff --git a/lib/rules/security/avoid-throw.js b/lib/rules/security/avoid-throw.js index 5e5bace4..30a942a0 100644 --- a/lib/rules/security/avoid-throw.js +++ b/lib/rules/security/avoid-throw.js @@ -27,7 +27,7 @@ class AvoidThrowChecker extends BaseChecker { // we don't use just `node.range` because ThrowStatement includes the semicolon and the spaces before it // we know that node.range[0] is the 't' of throw // we're also pretty sure that 'throw' has 5 letters - fixer.replaceTextRange([node.range[0], node.range[0] + 5], 'revert()') + fixer.replaceTextRange([node.range[0], node.range[0] + 5], 'revert();') ) } } diff --git a/solhint.js b/solhint.js index 8802402a..225aa94c 100644 --- a/solhint.js +++ b/solhint.js @@ -19,7 +19,7 @@ function init() { program .name('solhint') .usage('[options] [...other_files]') - .option('-f, --formatter [name]', 'report formatter name (stylish, table, tap, unix)') + .option('-f, --formatter [name]', 'report formatter name (stylish, table, tap, unix, json)') .option('-w, --max-warnings [maxWarningsNumber]', 'number of allowed warnings') .option('-c, --config [file_name]', 'file to use as your .solhint.json') .option('-q, --quiet', 'report errors only - default: false') @@ -119,6 +119,7 @@ function processStdin(options) { const report = processStr(stdinBuffer.toString()) report.file = options.filename || 'stdin' const formatterFn = getFormatter() + printReports([report], formatterFn) exitWithCode([report])