diff --git a/conf/rulesets/solhint-all.js b/conf/rulesets/solhint-all.js index 06b9fc5a..5c0629e6 100644 --- a/conf/rulesets/solhint-all.js +++ b/conf/rulesets/solhint-all.js @@ -38,8 +38,8 @@ module.exports = Object.freeze({ 'comprehensive-interface': 'warn', quotes: ['error', 'double'], 'const-name-snakecase': 'warn', - 'contract-name-camelcase': 'warn', - 'event-name-camelcase': 'warn', + 'contract-name-capwords': 'warn', + 'event-name-capwords': 'warn', 'foundry-test-functions': ['warn', ['setUp']], 'func-name-mixedcase': 'warn', 'func-named-parameters': ['warn', 4], diff --git a/conf/rulesets/solhint-recommended.js b/conf/rulesets/solhint-recommended.js index 68c7fadf..da7f6095 100644 --- a/conf/rulesets/solhint-recommended.js +++ b/conf/rulesets/solhint-recommended.js @@ -23,8 +23,8 @@ module.exports = Object.freeze({ 'gas-custom-errors': 'warn', quotes: ['error', 'double'], 'const-name-snakecase': 'warn', - 'contract-name-camelcase': 'warn', - 'event-name-camelcase': 'warn', + 'contract-name-capwords': 'warn', + 'event-name-capwords': 'warn', 'func-name-mixedcase': 'warn', 'immutable-vars-naming': [ 'warn', diff --git a/docs/rules.md b/docs/rules.md index aa04fbab..7b108d8a 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -29,8 +29,8 @@ title: "Rule Index of Solhint" | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------ | ----------- | | [interface-starts-with-i](./rules/naming/interface-starts-with-i.md) | Solidity Interfaces names should start with an `I` | | | | [const-name-snakecase](./rules/naming/const-name-snakecase.md) | Constant name must be in capitalized SNAKE_CASE. (Does not check IMMUTABLES, use immutable-vars-naming) | $~~~~~~~~$✔️ | | -| [contract-name-camelcase](./rules/naming/contract-name-camelcase.md) | Contract, Structs and Enums should be in CamelCase. | $~~~~~~~~$✔️ | | -| [event-name-camelcase](./rules/naming/event-name-camelcase.md) | Event name must be in CamelCase. | $~~~~~~~~$✔️ | | +| [contract-name-capwords](./rules/naming/contract-name-capwords.md) | Contract, Structs and Enums should be in CapWords. | $~~~~~~~~$✔️ | | +| [event-name-capwords](./rules/naming/event-name-capwords.md) | Event name must be in CapWords. | $~~~~~~~~$✔️ | | | [foundry-test-functions](./rules/naming/foundry-test-functions.md) | Enforce naming convention on functions for Foundry test cases | | | | [func-name-mixedcase](./rules/naming/func-name-mixedcase.md) | Function name must be in mixedCase. | $~~~~~~~~$✔️ | | | [func-named-parameters](./rules/naming/func-named-parameters.md) | Enforce named parameters for function calls with 4 or more arguments. This rule may have some false positives | | | diff --git a/docs/rules/naming/contract-name-capwords.md b/docs/rules/naming/contract-name-capwords.md new file mode 100644 index 00000000..acdbf7b7 --- /dev/null +++ b/docs/rules/naming/contract-name-capwords.md @@ -0,0 +1,42 @@ +--- +warning: "This is a dynamically generated file. Do not edit manually." +layout: "default" +title: "contract-name-capwords | Solhint" +--- + +# contract-name-capwords +![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen) +![Category Badge](https://img.shields.io/badge/-Style%20Guide%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 +Contract, Structs and Enums should be in CapWords. + +## Options +This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Defaults to warn. + +### Example Config +```json +{ + "rules": { + "contract-name-capwords": "warn" + } +} +``` + +### Notes +- Solhint allows this rule to automatically fix the code with `--fix` option +- The FIX will only change first letter and remove underscores + +## Examples +This rule does not have examples. + +## Version +This rule is introduced in the latest version. + +## Resources +- [Rule source](https://github.com/protofire/solhint/blob/master/lib/rules/naming/contract-name-capwords.js) +- [Document source](https://github.com/protofire/solhint/blob/master/docs/rules/naming/contract-name-capwords.md) +- [Test cases](https://github.com/protofire/solhint/blob/master/test/rules/naming/contract-name-capwords.js) diff --git a/docs/rules/naming/contract-name-pascalcase.md b/docs/rules/naming/contract-name-pascalcase.md new file mode 100644 index 00000000..d5463638 --- /dev/null +++ b/docs/rules/naming/contract-name-pascalcase.md @@ -0,0 +1,42 @@ +--- +warning: "This is a dynamically generated file. Do not edit manually." +layout: "default" +title: "contract-name-pascalcase | Solhint" +--- + +# contract-name-pascalcase +![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen) +![Category Badge](https://img.shields.io/badge/-Style%20Guide%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 +Contract, Structs and Enums should be in PascalCase. + +## Options +This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Defaults to warn. + +### Example Config +```json +{ + "rules": { + "contract-name-pascalcase": "warn" + } +} +``` + +### Notes +- Solhint allows this rule to automatically fix the code with `--fix` option +- The FIX will only change first letter and remove underscores + +## Examples +This rule does not have examples. + +## Version +This rule is introduced in the latest version. + +## Resources +- [Rule source](https://github.com/protofire/solhint/blob/master/lib/rules/naming/contract-name-pascalcase.js) +- [Document source](https://github.com/protofire/solhint/blob/master/docs/rules/naming/contract-name-pascalcase.md) +- [Test cases](https://github.com/protofire/solhint/blob/master/test/rules/naming/contract-name-pascalcase.js) diff --git a/docs/rules/naming/event-name-capwords.md b/docs/rules/naming/event-name-capwords.md new file mode 100644 index 00000000..8eb29be1 --- /dev/null +++ b/docs/rules/naming/event-name-capwords.md @@ -0,0 +1,42 @@ +--- +warning: "This is a dynamically generated file. Do not edit manually." +layout: "default" +title: "event-name-capwords | Solhint" +--- + +# event-name-capwords +![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen) +![Category Badge](https://img.shields.io/badge/-Style%20Guide%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 +Event name must be in CapWords. + +## Options +This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Defaults to warn. + +### Example Config +```json +{ + "rules": { + "event-name-capwords": "warn" + } +} +``` + +### Notes +- Solhint allows this rule to automatically fix the code with `--fix` option +- The FIX will only change first letter and remove underscores + +## Examples +This rule does not have examples. + +## Version +This rule is introduced in the latest version. + +## Resources +- [Rule source](https://github.com/protofire/solhint/blob/master/lib/rules/naming/event-name-capwords.js) +- [Document source](https://github.com/protofire/solhint/blob/master/docs/rules/naming/event-name-capwords.md) +- [Test cases](https://github.com/protofire/solhint/blob/master/test/rules/naming/event-name-capwords.js) diff --git a/docs/rules/naming/event-name-pascalcase.md b/docs/rules/naming/event-name-pascalcase.md new file mode 100644 index 00000000..0b798a8b --- /dev/null +++ b/docs/rules/naming/event-name-pascalcase.md @@ -0,0 +1,42 @@ +--- +warning: "This is a dynamically generated file. Do not edit manually." +layout: "default" +title: "event-name-pascalcase | Solhint" +--- + +# event-name-pascalcase +![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen) +![Category Badge](https://img.shields.io/badge/-Style%20Guide%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 +Event name must be in PascalCase. + +## Options +This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Defaults to warn. + +### Example Config +```json +{ + "rules": { + "event-name-pascalcase": "warn" + } +} +``` + +### Notes +- Solhint allows this rule to automatically fix the code with `--fix` option +- The FIX will only change first letter and remove underscores + +## Examples +This rule does not have examples. + +## Version +This rule is introduced in the latest version. + +## Resources +- [Rule source](https://github.com/protofire/solhint/blob/master/lib/rules/naming/event-name-pascalcase.js) +- [Document source](https://github.com/protofire/solhint/blob/master/docs/rules/naming/event-name-pascalcase.md) +- [Test cases](https://github.com/protofire/solhint/blob/master/test/rules/naming/event-name-pascalcase.js) diff --git a/e2e/08-autofix/contract-name-camelcase/.solhint.json b/e2e/08-autofix/contract-name-camelcase/.solhint.json deleted file mode 100644 index 6da8ad19..00000000 --- a/e2e/08-autofix/contract-name-camelcase/.solhint.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "contract-name-camelcase": "error" - } -} diff --git a/e2e/08-autofix/contract-name-capwords/.solhint.json b/e2e/08-autofix/contract-name-capwords/.solhint.json new file mode 100644 index 00000000..e1789abb --- /dev/null +++ b/e2e/08-autofix/contract-name-capwords/.solhint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "contract-name-capwords": "error" + } +} diff --git a/e2e/08-autofix/contract-name-camelcase/Foo1.sol b/e2e/08-autofix/contract-name-capwords/Foo1.sol similarity index 100% rename from e2e/08-autofix/contract-name-camelcase/Foo1.sol rename to e2e/08-autofix/contract-name-capwords/Foo1.sol diff --git a/e2e/08-autofix/contract-name-camelcase/Foo1AfterFix.sol b/e2e/08-autofix/contract-name-capwords/Foo1AfterFix.sol similarity index 100% rename from e2e/08-autofix/contract-name-camelcase/Foo1AfterFix.sol rename to e2e/08-autofix/contract-name-capwords/Foo1AfterFix.sol diff --git a/e2e/08-autofix/contract-name-camelcase/Foo1BeforeFix.sol b/e2e/08-autofix/contract-name-capwords/Foo1BeforeFix.sol similarity index 100% rename from e2e/08-autofix/contract-name-camelcase/Foo1BeforeFix.sol rename to e2e/08-autofix/contract-name-capwords/Foo1BeforeFix.sol diff --git a/e2e/08-autofix/event-name-camelcase/.solhint.json b/e2e/08-autofix/event-name-camelcase/.solhint.json deleted file mode 100644 index 7f809bb3..00000000 --- a/e2e/08-autofix/event-name-camelcase/.solhint.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "event-name-camelcase": "error" - } -} diff --git a/e2e/08-autofix/event-name-capwords/.solhint.json b/e2e/08-autofix/event-name-capwords/.solhint.json new file mode 100644 index 00000000..22cb73d9 --- /dev/null +++ b/e2e/08-autofix/event-name-capwords/.solhint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "event-name-capwords": "error" + } +} diff --git a/e2e/08-autofix/event-name-camelcase/Foo1.sol b/e2e/08-autofix/event-name-capwords/Foo1.sol similarity index 100% rename from e2e/08-autofix/event-name-camelcase/Foo1.sol rename to e2e/08-autofix/event-name-capwords/Foo1.sol diff --git a/e2e/08-autofix/event-name-camelcase/Foo1AfterFix.sol b/e2e/08-autofix/event-name-capwords/Foo1AfterFix.sol similarity index 100% rename from e2e/08-autofix/event-name-camelcase/Foo1AfterFix.sol rename to e2e/08-autofix/event-name-capwords/Foo1AfterFix.sol diff --git a/e2e/08-autofix/event-name-camelcase/Foo1BeforeFix.sol b/e2e/08-autofix/event-name-capwords/Foo1BeforeFix.sol similarity index 100% rename from e2e/08-autofix/event-name-camelcase/Foo1BeforeFix.sol rename to e2e/08-autofix/event-name-capwords/Foo1BeforeFix.sol diff --git a/e2e/autofix-test.js b/e2e/autofix-test.js index 0b7812ca..f57ae859 100644 --- a/e2e/autofix-test.js +++ b/e2e/autofix-test.js @@ -476,9 +476,9 @@ describe('e2e', function () { }) }) - describe('autofix rule: contract-name-camelcase', () => { + describe('autofix rule: contract-name-capwords', () => { before(function () { - params = retrieveParams('contract-name-camelcase/') + params = retrieveParams('contract-name-capwords/') currentConfig = `${params.path}${params.subpath}.solhint.json` currentFile = `${params.path}${params.subpath}Foo1.sol` beforeFixFile = `${params.path}${params.subpath}Foo1BeforeFix.sol` @@ -522,9 +522,9 @@ describe('e2e', function () { }) }) - describe('autofix rule: event-name-camelcase', () => { + describe('autofix rule: event-name-capwords', () => { before(function () { - params = retrieveParams('event-name-camelcase/') + params = retrieveParams('event-name-capwords/') currentConfig = `${params.path}${params.subpath}.solhint.json` currentFile = `${params.path}${params.subpath}Foo1.sol` beforeFixFile = `${params.path}${params.subpath}Foo1BeforeFix.sol` diff --git a/lib/common/identifier-naming.js b/lib/common/identifier-naming.js index 970bcc71..368490ae 100644 --- a/lib/common/identifier-naming.js +++ b/lib/common/identifier-naming.js @@ -11,12 +11,12 @@ module.exports = { return !this.isMixedCase(text) }, - isCamelCase(text) { + isCapWords(text) { return match(text, /[A-Z$]+[a-zA-Z0-9$]*/) }, - isNotCamelCase(text) { - return !this.isCamelCase(text) + isNotCapWords(text) { + return !this.isCapWords(text) }, isUpperSnakeCase(text) { diff --git a/lib/rules/naming/contract-name-camelcase.js b/lib/rules/naming/contract-name-capwords.js similarity index 84% rename from lib/rules/naming/contract-name-camelcase.js rename to lib/rules/naming/contract-name-capwords.js index d7fd9de1..3b0f2999 100644 --- a/lib/rules/naming/contract-name-camelcase.js +++ b/lib/rules/naming/contract-name-capwords.js @@ -1,12 +1,12 @@ const BaseChecker = require('../base-checker') const naming = require('../../common/identifier-naming') -const ruleId = 'contract-name-camelcase' +const ruleId = 'contract-name-capwords' const meta = { type: 'naming', docs: { - description: 'Contract, Structs and Enums should be in CamelCase.', + description: 'Contract, Structs and Enums should be in CapWords.', category: 'Style Guide Rules', notes: [ { @@ -25,7 +25,7 @@ const meta = { schema: null, } -class ContractNameCamelcaseChecker extends BaseChecker { +class ContractNameCapWordsChecker extends BaseChecker { constructor(reporter) { super(reporter, ruleId, meta) } @@ -43,7 +43,7 @@ class ContractNameCamelcaseChecker extends BaseChecker { } validateName(node, type) { - if (naming.isNotCamelCase(node.name)) { + if (naming.isNotCapWords(node.name)) { this._error(node, type) } } @@ -73,10 +73,10 @@ class ContractNameCamelcaseChecker extends BaseChecker { _error(node, type) { this.error( node, - 'Contract, Structs and Enums should be in CamelCase', + 'Contract, Structs and Enums should be in CapWords', this.fixStatement(node, type) ) } } -module.exports = ContractNameCamelcaseChecker +module.exports = ContractNameCapWordsChecker diff --git a/lib/rules/naming/event-name-camelcase.js b/lib/rules/naming/event-name-capwords.js similarity index 81% rename from lib/rules/naming/event-name-camelcase.js rename to lib/rules/naming/event-name-capwords.js index aecfca95..b0d31c16 100644 --- a/lib/rules/naming/event-name-camelcase.js +++ b/lib/rules/naming/event-name-capwords.js @@ -1,12 +1,12 @@ const BaseChecker = require('../base-checker') const naming = require('../../common/identifier-naming') -const ruleId = 'event-name-camelcase' +const ruleId = 'event-name-capwords' const meta = { type: 'naming', docs: { - description: 'Event name must be in CamelCase.', + description: 'Event name must be in CapWords.', category: 'Style Guide Rules', notes: [ { @@ -25,7 +25,7 @@ const meta = { schema: null, } -class EventNameCamelcaseChecker extends BaseChecker { +class EventNameCapWordsChecker extends BaseChecker { constructor(reporter) { super(reporter, ruleId, meta) } @@ -53,10 +53,10 @@ class EventNameCamelcaseChecker extends BaseChecker { } EventDefinition(node) { - if (naming.isNotCamelCase(node.name)) { - this.error(node, 'Event name must be in CamelCase', this.fixStatement(node)) + if (naming.isNotCapWords(node.name)) { + this.error(node, 'Event name must be in CapWords', this.fixStatement(node)) } } } -module.exports = EventNameCamelcaseChecker +module.exports = EventNameCapWordsChecker diff --git a/lib/rules/naming/index.js b/lib/rules/naming/index.js index 2949ad35..9ca600c9 100644 --- a/lib/rules/naming/index.js +++ b/lib/rules/naming/index.js @@ -1,6 +1,6 @@ const ConstNameSnakecaseChecker = require('./const-name-snakecase') -const ContractNameCamelcaseChecker = require('./contract-name-camelcase') -const EventNameCamelcaseChecker = require('./event-name-camelcase') +const ContractNameCapWordsChecker = require('./contract-name-capwords') +const EventNameCapWordsChecker = require('./event-name-capwords') const FuncNameMixedcaseChecker = require('./func-name-mixedcase') const FuncParamNameMixedcaseChecker = require('./func-param-name-mixedcase') const ModifierNameMixedcaseChecker = require('./modifier-name-mixedcase') @@ -16,8 +16,8 @@ const ImportsOrderChecker = require('./imports-order') module.exports = function checkers(reporter, config) { return [ new ConstNameSnakecaseChecker(reporter), - new ContractNameCamelcaseChecker(reporter), - new EventNameCamelcaseChecker(reporter), + new ContractNameCapWordsChecker(reporter), + new EventNameCapWordsChecker(reporter), new FuncNameMixedcaseChecker(reporter), new FuncParamNameMixedcaseChecker(reporter), new ModifierNameMixedcaseChecker(reporter), diff --git a/test/rules/naming/contract-name-camelcase.js b/test/rules/naming/contract-name-capwords.js similarity index 80% rename from test/rules/naming/contract-name-camelcase.js rename to test/rules/naming/contract-name-capwords.js index 787816c3..7dea13a2 100644 --- a/test/rules/naming/contract-name-camelcase.js +++ b/test/rules/naming/contract-name-capwords.js @@ -2,38 +2,38 @@ const assert = require('assert') const linter = require('../../../lib/index') const contractWith = require('../../common/contract-builder').contractWith -describe('Linter - contract-name-camelcase', () => { +describe('Linter - contract-name-capwords', () => { it('should raise struct name error', () => { const code = contractWith('struct a {}') const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + rules: { 'contract-name-capwords': 'error' }, }) assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('CamelCase')) + assert.ok(report.messages[0].message.includes('CapWords')) }) it('should raise contract name error', () => { const code = 'contract a {}' const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + rules: { 'contract-name-capwords': 'error' }, }) assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('CamelCase')) + assert.ok(report.messages[0].message.includes('CapWords')) }) it('should raise enum name error', () => { const code = contractWith('enum abc {}') const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + rules: { 'contract-name-capwords': 'error' }, }) assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('CamelCase')) + assert.ok(report.messages[0].message.includes('CapWords')) }) describe('Struct name with $ character', () => { @@ -47,7 +47,7 @@ describe('Linter - contract-name-camelcase', () => { for (const [key, code] of Object.entries(WITH_$)) { it(`should not raise contract name error for Structs ${key}`, () => { const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + rules: { 'contract-name-capwords': 'error' }, }) assert.equal(report.errorCount, 0) @@ -66,7 +66,7 @@ describe('Linter - contract-name-camelcase', () => { for (const [key, code] of Object.entries(WITH_$)) { it(`should not raise contract name error for Enums ${key}`, () => { const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + rules: { 'contract-name-capwords': 'error' }, }) assert.equal(report.errorCount, 0) @@ -85,7 +85,7 @@ describe('Linter - contract-name-camelcase', () => { for (const [key, code] of Object.entries(WITH_$)) { it(`should not raise contract name error for Contracts ${key}`, () => { const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + rules: { 'contract-name-capwords': 'error' }, }) assert.equal(report.errorCount, 0) diff --git a/test/rules/naming/event-name-camelcase.js b/test/rules/naming/event-name-capwords.js similarity index 66% rename from test/rules/naming/event-name-camelcase.js rename to test/rules/naming/event-name-capwords.js index 27bcd05c..3c2990ae 100644 --- a/test/rules/naming/event-name-camelcase.js +++ b/test/rules/naming/event-name-capwords.js @@ -2,16 +2,26 @@ const assert = require('assert') const linter = require('../../../lib/index') const contractWith = require('../../common/contract-builder').contractWith -describe('Linter - event-name-camelcase', () => { +describe('Linter - event-name-capwords', () => { + it('should raise event name error for event in mixedCase', () => { + const code = contractWith('event EventCap(uint a);') + + const report = linter.processStr(code, { + rules: { 'event-name-capwords': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + it('should raise event name error for event in mixedCase', () => { const code = contractWith('event event1(uint a);') const report = linter.processStr(code, { - rules: { 'event-name-camelcase': 'error' }, + rules: { 'event-name-capwords': 'error' }, }) assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('CamelCase')) + assert.ok(report.messages[0].message.includes('CapWords')) }) describe('Event name with $ character', () => { @@ -25,7 +35,7 @@ describe('Linter - event-name-camelcase', () => { for (const [key, code] of Object.entries(WITH_$)) { it(`should not raise event name error for Events ${key}`, () => { const report = linter.processStr(code, { - rules: { 'event-name-camelcase': 'error' }, + rules: { 'event-name-capwords': 'error' }, }) assert.equal(report.errorCount, 0)