-
Notifications
You must be signed in to change notification settings - Fork 128
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #219 from hbeckeri/master
Rule for visibility before modifiers
- Loading branch information
Showing
8 changed files
with
135 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/** | ||
* @fileoverview Ensure that the visibility modifier for a function should come before any custom modifiers. | ||
* @author Harrison Beckerich <https://github.com/hbeckeri> | ||
*/ | ||
|
||
"use strict"; | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
recommended: true, | ||
type: "warning", | ||
description: "Ensure that the visibility modifier for a function should come before any custom modifiers" | ||
}, | ||
|
||
schema: [] | ||
}, | ||
|
||
create(context) { | ||
// Find index of the first visibility modifier in declaration. | ||
// Find the first non-VM before this first VM found above. | ||
// If non-VM found, report the VM. | ||
function inspectFD(emitted) { | ||
const { node } = emitted, | ||
visibilityModifiers = ["public", "external", "internal", "private"]; | ||
const modifiers = (node.modifiers || []), | ||
firstVisibilityModifierIndex = modifiers.findIndex(m => visibilityModifiers.includes(m.name)); | ||
|
||
// If no visibility modifiers exist in function declaration, exit now | ||
if (emitted.exit || firstVisibilityModifierIndex === -1) { | ||
return; | ||
} | ||
|
||
const firstNonVisModifBeforeFirstVisModif = modifiers.slice(0, firstVisibilityModifierIndex).find(m => !visibilityModifiers.includes(m.name)); | ||
|
||
// TODO: Add fix() for this rule | ||
if (firstNonVisModifBeforeFirstVisModif) { | ||
const issue = { | ||
node: modifiers[firstVisibilityModifierIndex], | ||
message: `Visibility modifier "${modifiers[firstVisibilityModifierIndex].name}" should come before other modifiers.` | ||
}; | ||
context.report(issue); | ||
} | ||
} | ||
|
||
return { | ||
FunctionDeclaration: inspectFD | ||
}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,4 +46,4 @@ module.exports = { | |
return validateOptionsList(options); | ||
} | ||
|
||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* @fileoverview Tests for visibility-first rule. | ||
* @author Harrison Beckerich <https://github.com/hbeckeri> | ||
*/ | ||
|
||
"use strict"; | ||
|
||
const Solium = require("../../../../lib/solium"), | ||
{ toContract } = require("../../../utils/wrappers"); | ||
|
||
const userConfig = { | ||
"rules": { | ||
"visibility-first": "warning" | ||
} | ||
}; | ||
|
||
describe("[RULE] visibility-first: Acceptances", () => { | ||
it("accepts valid contract names", done => { | ||
let code = [ | ||
"function test() public onlyOwner modA modB modC modD private modE {}", | ||
"function test() public onlyOwner {}", | ||
"function test() external onlyOwner {}", | ||
"function test() internal onlyOwner {}", | ||
"function test() private onlyOwner {}", | ||
"function test() onlyOwner {}", | ||
"function test() public {}", | ||
"function test() external {}", | ||
"function test() internal {}", | ||
"function test() private {}", | ||
"function test() {}" | ||
]; | ||
let errors; | ||
|
||
code = code.map(item => toContract(item)); | ||
|
||
code.forEach(snip => { | ||
errors = Solium.lint(snip, userConfig); | ||
errors.should.be.Array(); | ||
errors.should.be.empty(); | ||
}); | ||
|
||
Solium.reset(); | ||
done(); | ||
}); | ||
}); | ||
|
||
|
||
describe("[RULE] visibility-first: Rejections", () => { | ||
it("rejects invalid struct names", done => { | ||
let code = [ | ||
"function test() onlyOwner modA modB modC public {}", | ||
"function test() onlyOwner modA modB modC external modD modE {}", | ||
"function test() onlyOwner modA modB modC internal modD modE private {}", | ||
"function test() onlyOwner public {}", | ||
"function test() onlyOwner external {}", | ||
"function test() onlyOwner internal {}", | ||
"function test() onlyOwner private {}" | ||
]; | ||
let errors; | ||
|
||
code = code.map(item => toContract(item)); | ||
|
||
code.forEach(snip => { | ||
errors = Solium.lint(snip, userConfig); | ||
errors.should.be.Array(); | ||
errors.should.have.size(1); | ||
}); | ||
|
||
Solium.reset(); | ||
done(); | ||
}); | ||
}); |