From 57326487dad37de3c148000a2312a6e254e9f635 Mon Sep 17 00:00:00 2001 From: dbale-altoros Date: Wed, 5 Jul 2023 16:43:01 -0300 Subject: [PATCH 1/5] add: json formatter --- .eslintrc.js | 1 + README.md | 2 +- lib/formatters/README.md | 2 +- lib/formatters/json.js | 42 +++++++++++++++++++++++++++++++++++++++ lib/formatters/stylish.js | 5 +++-- lib/formatters/table.js | 5 +++-- lib/formatters/tap.js | 5 +++-- lib/formatters/unix.js | 5 +++-- solhint.js | 3 ++- 9 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 lib/formatters/json.js diff --git a/.eslintrc.js b/.eslintrc.js index c9533359..a5348ee0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -27,6 +27,7 @@ module.exports = { 'no-use-before-define': ['error', { classes: false, functions: false }], 'prefer-destructuring': 'off', 'prefer-template': 'off', + "experimentalObjectRestSpread": true, // this rules were disabled to make it easier to add airbnb-base, but they are good ones; we should re-enable them // at some point diff --git a/README.md b/README.md index c734a921..35249144 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 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..e47d9a7c --- /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) { + let 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/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]) From acb6a7bd437949c8654be87c87728c764d5553fe Mon Sep 17 00:00:00 2001 From: dbale-altoros Date: Wed, 5 Jul 2023 16:49:36 -0300 Subject: [PATCH 2/5] fix: eslint config --- .eslintrc.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index a5348ee0..11198739 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -27,7 +27,9 @@ module.exports = { 'no-use-before-define': ['error', { classes: false, functions: false }], 'prefer-destructuring': 'off', 'prefer-template': 'off', - "experimentalObjectRestSpread": true, + "parserOptions": { + "ecmaVersion": 2018 + }, // this rules were disabled to make it easier to add airbnb-base, but they are good ones; we should re-enable them // at some point From e0b4c0173b7eee0f40886a3711b14eb8e3f9b5cf Mon Sep 17 00:00:00 2001 From: dbale-altoros Date: Wed, 5 Jul 2023 17:13:41 -0300 Subject: [PATCH 3/5] fix: eslint config v2 --- .eslintrc.js | 5 +---- lib/formatters/json.js | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 11198739..9bf4200c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,6 @@ module.exports = { parserOptions: { - ecmaVersion: 8, + ecmaVersion: 2020, }, env: { browser: false, @@ -27,9 +27,6 @@ module.exports = { 'no-use-before-define': ['error', { classes: false, functions: false }], 'prefer-destructuring': 'off', 'prefer-template': 'off', - "parserOptions": { - "ecmaVersion": 2018 - }, // this rules were disabled to make it easier to add airbnb-base, but they are good ones; we should re-enable them // at some point diff --git a/lib/formatters/json.js b/lib/formatters/json.js index e47d9a7c..d46c7ed8 100644 --- a/lib/formatters/json.js +++ b/lib/formatters/json.js @@ -26,7 +26,7 @@ function getMessageType(message) { // eslint-disable-next-line func-names module.exports = function (results) { - let allMessages = [] + const allMessages = [] results.forEach((result) => { const messages = result.messages From 74f670713787428231e43e5ffdaa804d37bb816c Mon Sep 17 00:00:00 2001 From: dbale-altoros Date: Thu, 6 Jul 2023 13:55:10 -0300 Subject: [PATCH 4/5] added notes and fixed avoid-throw fix command --- README.md | 2 ++ lib/rules/security/avoid-throw.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 35249144..b5a12a4d 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ Commands: stdin [options] linting of source code data provided to STDIN ``` +### Note +`--fix` option currently works only on "avoid-throw" and "avoid-sha3" rules ## Configuration 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();') ) } } From a18f72eec7dad4f6ede9c45919641698684ae426 Mon Sep 17 00:00:00 2001 From: dbale-altoros Date: Thu, 6 Jul 2023 19:07:59 -0300 Subject: [PATCH 5/5] fixed quotes rule and added docs --- README.md | 8 +++- docs/rules.md | 3 +- docs/rules/best-practises/no-unused-import.md | 39 +++++++++++++++++++ docs/rules/miscellaneous/quotes.md | 2 +- lib/rules/miscellaneous/quotes.js | 2 +- 5 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 docs/rules/best-practises/no-unused-import.md diff --git a/README.md b/README.md index b5a12a4d..507c31e8 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,8 @@ Commands: stdin [options] linting of source code data provided to STDIN ``` ### Note -`--fix` option currently works only on "avoid-throw" and "avoid-sha3" rules - +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. @@ -88,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/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,