-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add
no-boolean-literal-for-arguments
rule (#1271)
* feat(src/rules): Adding the no_boolean_literal_for_arguments.rs file that contains the rule in question and its respective implementation. The newly added rule is now imported in the rules.rs file. * feat(src/rules,docs): New test cases were added to the no_boolean_literal_for_arguments.rs file. The documentation for the no_boolean_literal_for_arguments rule was introduced in no_boolean_literal_for_arguments.md. * feat(src/rules,www/static): The new rule was successfully integrated into the rules.rs file. A new docs.json file was generated based on what's specified on the README.md of the project. * fix(src/rules,www/static,docs/rules): The rule was improved in order to consider every amount of boolean literal arguments as an improvement point. The docs.json file was regenerated. The no_boolean_literal_for_arguments.md was improved to match the changes of the rule. * fix(project): The code was formatted using the 'deno run --allow-run tools/format.ts' command. * fix(rules/no_boolean_literal_for_arguments): Adding a simple fix as specified by clippy. * fix(no_boolean_literal_for_arguments): Code was formatted using the appropriate command. * fix: windows line endings --------- Co-authored-by: Marvin Hagemeister <[email protected]>
- Loading branch information
1 parent
79bf1b9
commit df778aa
Showing
4 changed files
with
175 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
Requires all functions called with any amount of `boolean` literals as | ||
parameters to use a self-documenting constant instead. | ||
|
||
Is common to define functions that can take `booleans` as arguments. However, | ||
passing `boolean` literals as parameters can lead to lack of context regarding | ||
the role of the argument inside the function in question. | ||
|
||
A simple fix for the points mentioned above is the use of self documenting | ||
constants that will end up working as "named booleans", that allow for a better | ||
understanding on what the parameters mean in the context of the function call. | ||
|
||
### Invalid | ||
|
||
```typescript | ||
function redraw(allViews: boolean, inline: boolean) { | ||
// redraw logic. | ||
} | ||
redraw(true, true); | ||
|
||
function executeCommand(recursive: boolean, executionMode: EXECUTION_MODES) { | ||
// executeCommand logic. | ||
} | ||
executeCommand(true, EXECUTION_MODES.ONE); | ||
|
||
function enableLogs(enable: boolean) { | ||
// enabledLogs logic. | ||
} | ||
enableLogs(true); | ||
``` | ||
|
||
### Valid | ||
|
||
```typescript | ||
function redraw(allViews: boolean, inline: boolean) { | ||
// redraw logic. | ||
} | ||
const ALL_VIEWS = true, INLINE = true; | ||
redraw(ALL_VIEWS, INLINE); | ||
|
||
function executeCommand(recursive: boolean, executionMode: EXECUTION_MODES) { | ||
// executeCommand logic. | ||
} | ||
const RECURSIVE = true; | ||
executeCommand(RECURSIVE, EXECUTION_MODES.ONE); | ||
|
||
function enableLogs(enable: boolean) { | ||
// enabledLogs logic. | ||
} | ||
const ENABLE = true; | ||
enableLogs(ENABLE); | ||
``` |
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,117 @@ | ||
use super::{Context, LintRule}; | ||
use crate::handler::{Handler, Traverse}; | ||
use crate::Program; | ||
use deno_ast::view::{CallExpr, NodeTrait}; | ||
use deno_ast::SourceRanged; | ||
|
||
#[derive(Debug)] | ||
pub struct NoBooleanLiteralForArguments; | ||
|
||
const CODE: &str = "no-boolean-literal-for-arguments"; | ||
const MESSAGE: &str = "Please create a self-documenting constant instead of \ | ||
passing plain booleans values as arguments"; | ||
const HINT: &str = | ||
"const ARG_ONE = true, ARG_TWO = false;\nyourFunction(ARG_ONE, ARG_TWO)"; | ||
|
||
impl LintRule for NoBooleanLiteralForArguments { | ||
fn lint_program_with_ast_view<'view>( | ||
&self, | ||
context: &mut Context<'view>, | ||
program: Program<'view>, | ||
) { | ||
NoBooleanLiteralForArgumentsVisitor.traverse(program, context); | ||
} | ||
|
||
fn code(&self) -> &'static str { | ||
CODE | ||
} | ||
|
||
fn tags(&self) -> &'static [&'static str] { | ||
&[] | ||
} | ||
|
||
#[cfg(feature = "docs")] | ||
fn docs(&self) -> &'static str { | ||
include_str!("../../docs/rules/no_boolean_literal_for_arguments.md") | ||
} | ||
} | ||
|
||
struct NoBooleanLiteralForArgumentsVisitor; | ||
|
||
impl Handler for NoBooleanLiteralForArgumentsVisitor { | ||
fn call_expr(&mut self, call_expression: &CallExpr, ctx: &mut Context) { | ||
let args = call_expression.args; | ||
let is_boolean_literal = | ||
|text: &str| -> bool { matches!(text, "true" | "false") }; | ||
for arg in args { | ||
if is_boolean_literal(arg.text()) { | ||
ctx.add_diagnostic_with_hint( | ||
call_expression.range(), | ||
CODE, | ||
MESSAGE, | ||
HINT, | ||
); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
||
#[test] | ||
fn no_boolean_literal_for_arguments_valid() { | ||
assert_lint_ok! { | ||
NoBooleanLiteralForArguments, | ||
r#"runCMDCommand(command, executionMode)"#, | ||
r#" | ||
function formatLog(logData: { level: string, text: string }) { | ||
console.log(`[${level}]:${text}`); | ||
} | ||
formatLog({ level: "INFO", text: "Connected to the DB!" }); | ||
"#, | ||
r#" | ||
function displayInformation(display: { renderer: "terminal" | "screen", recursive: boolean }) { | ||
if (display) { | ||
renderInformation(); | ||
} | ||
// TODO! | ||
} | ||
displayInformation({ renderer: "terminal", recursive: true }); | ||
"# | ||
} | ||
} | ||
|
||
#[test] | ||
fn no_boolean_literal_for_arguments_invalid() { | ||
assert_lint_err! { | ||
NoBooleanLiteralForArguments, | ||
r#"test(true,true)"#:[{line: 1, col: 0, message: MESSAGE, hint: HINT}], | ||
r#"test(false,true)"#:[{line: 1, col: 0, message: MESSAGE, hint: HINT}], | ||
r#"test(false,false)"#:[{line: 1, col: 0, message: MESSAGE, hint: HINT}], | ||
r#"invoke(true,remoteServerUrl,true)"#:[{line: 1, col: 0, message: MESSAGE, hint: HINT}], | ||
r#" | ||
function enableLinting(enable: boolean, limitDepth: boolean) { | ||
if (enable) { | ||
linter.run(); | ||
} | ||
} | ||
enableLinting(true,false); | ||
"#:[{line: 7, col: 6, message: MESSAGE, hint: HINT}], | ||
r#" | ||
runCMD(true, CMD.MODE_ONE) | ||
"#:[{line: 2, col: 6, message: MESSAGE, hint: HINT}], | ||
r#" | ||
function displayInformation(display: boolean) { | ||
if (display) { | ||
renderInformation(); | ||
} | ||
// TODO! | ||
} | ||
displayInformation(true); | ||
"#:[{line: 8, col: 6, message: MESSAGE, hint: HINT}], | ||
} | ||
} | ||
} |
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