Skip to content

Commit 82c456c

Browse files
committed
feat: free functions don't need underscore
1 parent 958995d commit 82c456c

7 files changed

+54
-34
lines changed

docs/rules.md

+24-24
Original file line numberDiff line numberDiff line change
@@ -26,30 +26,30 @@ title: "Rule Index of Solhint"
2626

2727
## Style Guide Rules
2828

29-
| Rule Id | Error | Recommended | Deprecated |
30-
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------ | ----------- |
31-
| [interface-starts-with-i](./rules/naming/interface-starts-with-i.md) | Solidity Interfaces names should start with an `I` | | |
32-
| [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) | $~~~~~~~~$✔️ | |
33-
| [contract-name-camelcase](./rules/naming/contract-name-camelcase.md) | Contract, Structs and Enums should be in CamelCase. | $~~~~~~~~$✔️ | |
34-
| [event-name-camelcase](./rules/naming/event-name-camelcase.md) | Event name must be in CamelCase. | $~~~~~~~~$✔️ | |
35-
| [foundry-test-functions](./rules/naming/foundry-test-functions.md) | Enforce naming convention on functions for Foundry test cases | | |
36-
| [func-name-mixedcase](./rules/naming/func-name-mixedcase.md) | Function name must be in mixedCase. | $~~~~~~~~$✔️ | |
37-
| [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 | | |
38-
| [func-param-name-leading-underscore](./rules/naming/func-param-name-leading-underscore.md) | Function param name must start a single underscore | | |
39-
| [func-param-name-mixedcase](./rules/naming/func-param-name-mixedcase.md) | Function param name must be in mixedCase. | | |
40-
| [immutable-vars-naming](./rules/naming/immutable-vars-naming.md) | Check Immutable variables. Capitalized SNAKE_CASE or mixedCase depending on configuration. | $~~~~~~~~$✔️ | |
41-
| [imports-order](./rules/naming/imports-order.md) | Order the imports of the contract to follow a certain hierarchy (read "Notes section") | | |
42-
| [modifier-name-mixedcase](./rules/naming/modifier-name-mixedcase.md) | Modifier name must be in mixedCase. | | |
43-
| [named-parameters-mapping](./rules/naming/named-parameters-mapping.md) | Solidity v0.8.18 introduced named parameters on the mappings definition. | | |
44-
| [private-func-leading-underscore](./rules/naming/private-func-leading-underscore.md) | Private and internal function names must start with a single underscore, unless they are in a library. | | |
45-
| [private-vars-leading-underscore](./rules/naming/private-vars-leading-underscore.md) | Non-external functions and state variables should start with a single underscore. Others, shouldn't | | |
46-
| [private-vars-no-leading-underscore](./rules/naming/private-vars-no-leading-underscore.md) | Private and internal variable names must NOT start with a single underscore. | | |
47-
| [use-forbidden-name](./rules/naming/use-forbidden-name.md) | Avoid to use letters 'I', 'l', 'O' as identifiers. | $~~~~~~~~$✔️ | |
48-
| [var-name-mixedcase](./rules/naming/var-name-mixedcase.md) | Variable name must be in mixedCase. (Does not check IMMUTABLES, use immutable-vars-naming) | $~~~~~~~~$✔️ | |
49-
| [func-order](./rules/order/func-order.md) | Function order is incorrect. | | $~~~~~~~$✔️ |
50-
| [imports-on-top](./rules/order/imports-on-top.md) | Import statements must be on top. | $~~~~~~~~$✔️ | |
51-
| [ordering](./rules/order/ordering.md) | Check order of elements in file and inside each contract, according to the style guide. | | |
52-
| [visibility-modifier-order](./rules/order/visibility-modifier-order.md) | Visibility modifier must be first in list of modifiers. | $~~~~~~~~$✔️ | |
29+
| Rule Id | Error | Recommended | Deprecated |
30+
| ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | ------------ | ----------- |
31+
| [interface-starts-with-i](./rules/naming/interface-starts-with-i.md) | Solidity Interfaces names should start with an `I` | | |
32+
| [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) | $~~~~~~~~$✔️ | |
33+
| [contract-name-camelcase](./rules/naming/contract-name-camelcase.md) | Contract, Structs and Enums should be in CamelCase. | $~~~~~~~~$✔️ | |
34+
| [event-name-camelcase](./rules/naming/event-name-camelcase.md) | Event name must be in CamelCase. | $~~~~~~~~$✔️ | |
35+
| [foundry-test-functions](./rules/naming/foundry-test-functions.md) | Enforce naming convention on functions for Foundry test cases | | |
36+
| [func-name-mixedcase](./rules/naming/func-name-mixedcase.md) | Function name must be in mixedCase. | $~~~~~~~~$✔️ | |
37+
| [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 | | |
38+
| [func-param-name-leading-underscore](./rules/naming/func-param-name-leading-underscore.md) | Function param name must start a single underscore | | |
39+
| [func-param-name-mixedcase](./rules/naming/func-param-name-mixedcase.md) | Function param name must be in mixedCase. | | |
40+
| [immutable-vars-naming](./rules/naming/immutable-vars-naming.md) | Check Immutable variables. Capitalized SNAKE_CASE or mixedCase depending on configuration. | $~~~~~~~~$✔️ | |
41+
| [imports-order](./rules/naming/imports-order.md) | Order the imports of the contract to follow a certain hierarchy (read "Notes section") | | |
42+
| [modifier-name-mixedcase](./rules/naming/modifier-name-mixedcase.md) | Modifier name must be in mixedCase. | | |
43+
| [named-parameters-mapping](./rules/naming/named-parameters-mapping.md) | Solidity v0.8.18 introduced named parameters on the mappings definition. | | |
44+
| [private-func-leading-underscore](./rules/naming/private-func-leading-underscore.md) | Private and internal function names must start with a single underscore, unless they are in a library or free. | | |
45+
| [private-vars-leading-underscore](./rules/naming/private-vars-leading-underscore.md) | Non-external functions and state variables should start with a single underscore. Others, shouldn't | | |
46+
| [private-vars-no-leading-underscore](./rules/naming/private-vars-no-leading-underscore.md) | Private and internal variable names must NOT start with a single underscore. | | |
47+
| [use-forbidden-name](./rules/naming/use-forbidden-name.md) | Avoid to use letters 'I', 'l', 'O' as identifiers. | $~~~~~~~~$✔️ | |
48+
| [var-name-mixedcase](./rules/naming/var-name-mixedcase.md) | Variable name must be in mixedCase. (Does not check IMMUTABLES, use immutable-vars-naming) | $~~~~~~~~$✔️ | |
49+
| [func-order](./rules/order/func-order.md) | Function order is incorrect. | | $~~~~~~~$✔️ |
50+
| [imports-on-top](./rules/order/imports-on-top.md) | Import statements must be on top. | $~~~~~~~~$✔️ | |
51+
| [ordering](./rules/order/ordering.md) | Check order of elements in file and inside each contract, according to the style guide. | | |
52+
| [visibility-modifier-order](./rules/order/visibility-modifier-order.md) | Visibility modifier must be first in list of modifiers. | $~~~~~~~~$✔️ | |
5353
5454

5555
## Best Practice Rules

docs/rules/naming/private-func-leading-underscore.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ title: "private-func-leading-underscore | Solhint"
99
![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow)
1010

1111
## Description
12-
Private and internal function names must start with a single underscore, unless they are in a library.
12+
Private and internal function names must start with a single underscore, unless they are in a library or free.
1313

1414
## Options
1515
This rule accepts an array of options:

lib/rules/naming/private-func-leading-underscore.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const meta = {
1010

1111
docs: {
1212
description:
13-
'Private and internal function names must start with a single underscore, unless they are in a library.',
13+
'Private and internal function names must start with a single underscore, unless they are in a library or free.',
1414
category: 'Style Guide Rules',
1515
options: [
1616
{
@@ -30,16 +30,17 @@ const meta = {
3030
class PrivateFuncLeadingUnderscoreChecker extends BaseChecker {
3131
constructor(reporter) {
3232
super(reporter, ruleId, meta)
33+
this.inContract = false
3334
}
3435

3536
ContractDefinition(node) {
36-
if (node.kind === 'library') {
37-
this.inLibrary = true
37+
if (node.kind === 'contract') {
38+
this.inContract = true
3839
}
3940
}
4041

4142
'ContractDefinition:exit'() {
42-
this.inLibrary = false
43+
this.inContract = false
4344
}
4445

4546
FunctionDefinition(node) {
@@ -49,7 +50,7 @@ class PrivateFuncLeadingUnderscoreChecker extends BaseChecker {
4950

5051
const isPrivate = node.visibility === 'private'
5152
const isInternal = node.visibility === 'internal' || node.visibility === 'default'
52-
const shouldHaveLeadingUnderscore = !this.inLibrary && (isPrivate || isInternal)
53+
const shouldHaveLeadingUnderscore = this.inContract && (isPrivate || isInternal)
5354
this.validateName(node, shouldHaveLeadingUnderscore)
5455
}
5556

test/common/contract-builder.js

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
const { times } = require('lodash')
22

3+
function freeFunction(code) {
4+
return `
5+
pragma solidity 0.4.4;
6+
7+
${code}
8+
`
9+
}
10+
311
function contractWith(code) {
412
return `
513
pragma solidity 0.4.4;
@@ -68,6 +76,7 @@ function repeatLines(line, count) {
6876
module.exports = {
6977
contractWith,
7078
libraryWith,
79+
freeFunction,
7180
funcWith,
7281
modifierWith,
7382
multiLine,

test/rules/gas-consumption/gas-named-return-values.js

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ describe('Linter - gas-named-return-values', () => {
8989
'comprehensive-interface': 'off',
9090
'foundry-test-functions': 'off',
9191
'func-param-name-leading-underscore': 'off',
92+
'strict-override': 'off',
9293
},
9394
})
9495

test/rules/naming/func-param-name-leading-underscore.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { contractWith, libraryWith } = require('../../common/contract-builder')
55
describe('Linter - func-param-name-leading-underscore', () => {
66
const SHOULD_WARN_CASES = [
77
// warn when param names don't start with _
8+
contractWith('struct foo { uint bar; }\nfunction foo(foo memory bar) {}'),
89

910
contractWith('function foo(uint bar) {}'),
1011
contractWith('function foo(uint bar) internal {}'),
@@ -20,9 +21,7 @@ describe('Linter - func-param-name-leading-underscore', () => {
2021
]
2122

2223
const SHOULD_NOT_WARN_CASES = [
23-
// warn when param names start with _
24-
25-
// don't warn when private/internal/default names start with _
24+
contractWith('struct foo { uint bar; }\nfunction foo(foo memory _bar) {}'),
2625

2726
// don't warn when public/external names don't start with _
2827
contractWith('uint public foo;'),

test/rules/naming/private-func-leading-underscore.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const assert = require('assert')
22
const linter = require('../../../lib/index')
3-
const { contractWith, libraryWith } = require('../../common/contract-builder')
3+
const { contractWith, libraryWith, freeFunction } = require('../../common/contract-builder')
44

55
describe('Linter - private-func-leading-underscore', () => {
66
const SHOULD_WARN_CASES = [
@@ -20,6 +20,12 @@ describe('Linter - private-func-leading-underscore', () => {
2020
libraryWith('function _foo() private {}'),
2121
libraryWith('function _foo() public {}'),
2222
libraryWith('function _foo() external {}'),
23+
24+
freeFunction('function _foo() {}'),
25+
freeFunction('function _foo() internal {}'),
26+
freeFunction('function _foo() private {}'),
27+
freeFunction('function _foo() public {}'),
28+
freeFunction('function _foo() external {}'),
2329
]
2430

2531
const SHOULD_NOT_WARN_CASES = [
@@ -38,6 +44,10 @@ describe('Linter - private-func-leading-underscore', () => {
3844
libraryWith('function foo() internal {}'),
3945
libraryWith('function foo() private {}'),
4046

47+
// don't warn when internal/private functions in free functions don't start with _
48+
freeFunction('function foo() internal {}'),
49+
freeFunction('function foo() private {}'),
50+
4151
// don't warn for constructors
4252
contractWith('constructor() public {}'),
4353

0 commit comments

Comments
 (0)