Skip to content

Commit 0fc8f34

Browse files
Add rule to remove function call parentheses
1 parent 00a9aaa commit 0fc8f34

File tree

10 files changed

+145
-3
lines changed

10 files changed

+145
-3
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "darklua"
3-
version = "0.3.3"
3+
version = "0.3.4"
44
authors = ["jeparlefrancais <jeparlefrancais21@gmail.com>"]
55
edition = "2018"
66
readme = "README.md"

RULES.md

+15
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ You can find the available rules and their properties here. The default rule sta
55
- [Convert local functions to assignments](#convert-local-functions-to-assignments)
66
- [Group local assignments](#group-local-assignments)
77
- [Remove empty do statements](#remove-empty-do-statements)
8+
- [Remove function call parens](#remove-function-call-parens)
89
- [Remove method definitions](#remove-method-definitions)
910
- [Remove unused if branch](#remove-unused-if-branch)
1011
- [Remove unused while](#remove-unused-while)
@@ -93,6 +94,20 @@ This rule does not have any properties.
9394

9495
---
9596

97+
## Remove function call parens
98+
```remove_function_call_parens```
99+
100+
This rule will remove parens in a function call when there is only one string or one table as arguments. It does not have any properties.
101+
102+
### Examples
103+
```json5
104+
{
105+
rule: 'remove_function_call_parens',
106+
}
107+
```
108+
109+
---
110+
96111
## Remove method definitions
97112
```remove_method_definition```
98113

src/nodes/expressions/string.rs

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ impl StringExpression {
2424
value.map(|value| Self { value })
2525
}
2626

27+
pub fn empty() -> Self {
28+
Self { value: "".to_owned() }
29+
}
30+
2731
pub fn from_value<T: Into<String>>(value: T) -> Self {
2832
Self { value: value.into() }
2933
}

src/rules/call_parens.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use crate::nodes::{Arguments, Block, Expression, FunctionCall, StringExpression, TableExpression};
2+
use crate::process::{DefaultVisitor, NodeProcessor, NodeVisitor};
3+
use crate::rules::{Rule, RuleConfigurationError, RuleProperties};
4+
5+
use std::mem;
6+
7+
#[derive(Debug, Clone, Default)]
8+
struct Processor {}
9+
10+
impl NodeProcessor for Processor {
11+
fn process_function_call(&mut self, call: &mut FunctionCall) {
12+
let new_arguments = match call.mutate_arguments() {
13+
Arguments::Tuple(expressions) if expressions.len() == 1 => {
14+
let expression = expressions.iter_mut().next().unwrap();
15+
16+
match expression {
17+
Expression::String(string) => {
18+
let mut steal_string = StringExpression::empty();
19+
mem::swap(string, &mut steal_string);
20+
Some(Arguments::String(steal_string))
21+
}
22+
Expression::Table(table) => {
23+
let mut steal_table = TableExpression::default();
24+
mem::swap(table, &mut steal_table);
25+
Some(Arguments::Table(steal_table))
26+
}
27+
_ => None,
28+
}
29+
}
30+
_ => None,
31+
};
32+
33+
if let Some(new_arguments) = new_arguments {
34+
mem::replace(call.mutate_arguments(), new_arguments);
35+
}
36+
}
37+
}
38+
39+
pub const REMOVE_FUNCTION_CALL_PARENS: &'static str = "remove_function_call_parens";
40+
41+
/// A rule that removes parentheses when calling functions with a string or a table.
42+
#[derive(Debug, Default, PartialEq, Eq)]
43+
pub struct RemoveFunctionCallParens {}
44+
45+
impl Rule for RemoveFunctionCallParens {
46+
fn process(&self, block: &mut Block) {
47+
let mut processor = Processor::default();
48+
DefaultVisitor::visit_block(block, &mut processor);
49+
}
50+
51+
fn configure(&mut self, properties: RuleProperties) -> Result<(), RuleConfigurationError> {
52+
for (key, _value) in properties {
53+
return Err(RuleConfigurationError::UnexpectedProperty(key))
54+
}
55+
56+
Ok(())
57+
}
58+
59+
fn get_name(&self) -> &'static str {
60+
REMOVE_FUNCTION_CALL_PARENS
61+
}
62+
63+
fn serialize_to_properties(&self) -> RuleProperties {
64+
RuleProperties::new()
65+
}
66+
}
67+
68+
#[cfg(test)]
69+
mod test {
70+
use super::*;
71+
72+
use insta::assert_json_snapshot;
73+
74+
fn new_rule() -> RemoveFunctionCallParens {
75+
RemoveFunctionCallParens::default()
76+
}
77+
78+
#[test]
79+
fn serialize_default_rule() {
80+
let rule: Box<dyn Rule> = Box::new(new_rule());
81+
82+
assert_json_snapshot!("default_remove_function_call_parens", rule);
83+
}
84+
}

src/rules/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! A module that contains the different rules that mutates a Lua block.
22
33
mod empty_do;
4+
mod call_parens;
45
mod group_local;
56
mod method_def;
67
mod no_local_function;
@@ -9,6 +10,7 @@ mod unused_if_branch;
910
mod unused_while;
1011

1112
pub use empty_do::*;
13+
pub use call_parens::*;
1214
pub use group_local::*;
1315
pub use method_def::*;
1416
pub use no_local_function::*;
@@ -91,6 +93,7 @@ pub fn get_default_rules() -> Vec<Box<dyn Rule>> {
9193
Box::new(ConvertLocalFunctionToAssign::default()),
9294
Box::new(GroupLocalAssignment::default()),
9395
Box::new(RenameVariables::default()),
96+
Box::new(RemoveFunctionCallParens::default()),
9497
]
9598
}
9699

@@ -102,6 +105,7 @@ impl FromStr for Box<dyn Rule> {
102105
CONVERT_LOCAL_FUNCTION_TO_ASSIGN_RULE_NAME => Box::new(ConvertLocalFunctionToAssign::default()),
103106
GROUP_LOCAL_ASSIGNMENT => Box::new(GroupLocalAssignment::default()),
104107
REMOVE_EMPTY_DO_RULE_NAME => Box::new(RemoveEmptyDo::default()),
108+
REMOVE_FUNCTION_CALL_PARENS => Box::new(RemoveFunctionCallParens::default()),
105109
REMOVE_METHOD_DEFINITION_RULE_NAME => Box::new(RemoveMethodDefinition::default()),
106110
REMOVE_UNUSED_IF_BRANCH_RULE_NAME => Box::new(RemoveUnusedIfBranch::default()),
107111
REMOVE_UNUSED_WHILE_RULE_NAME => Box::new(RemoveUnusedWhile::default()),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/rules/call_parens.rs
3+
expression: rule
4+
---
5+
"remove_function_call_parens"

src/rules/snapshots/test__default_rules.snap

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ expression: rules
99
"remove_method_definition",
1010
"convert_local_function_to_assign",
1111
"group_local_assignment",
12-
"rename_variables"
12+
"rename_variables",
13+
"remove_function_call_parens"
1314
]

tests/rule_tests/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ macro_rules! test_rule_wihout_effects {
4242

4343
mod group_local_assignment;
4444
mod no_local_function;
45+
mod remove_call_parens;
4546
mod remove_empty_do;
4647
mod remove_method_definition;
4748
mod remove_unused_if_branch;
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use darklua_core::rules::{RemoveFunctionCallParens, Rule};
2+
3+
test_rule!(
4+
RemoveFunctionCallParens::default(),
5+
call_statement_with_empty_string("foo('')") => "foo''",
6+
call_statement_with_empty_table("foo({})") => "foo{}",
7+
call_expression_with_empty_string("return foo('')") => "return foo''",
8+
call_expression_with_empty_table("return foo({})") => "return foo{}"
9+
);
10+
11+
test_rule_wihout_effects!(
12+
RemoveFunctionCallParens::default(),
13+
two_strings("foo('bar', 'baz')"),
14+
two_tables("foo({}, {})"),
15+
variable_parameter("foo(bar)")
16+
);
17+
18+
#[test]
19+
fn deserialize_from_object_notation() {
20+
json5::from_str::<Box<dyn Rule>>(r#"{
21+
rule: 'remove_function_call_parens',
22+
}"#).unwrap();
23+
}
24+
25+
#[test]
26+
fn deserialize_from_string() {
27+
json5::from_str::<Box<dyn Rule>>("'remove_function_call_parens'").unwrap();
28+
}

0 commit comments

Comments
 (0)