Skip to content

Commit a36462e

Browse files
committed
WIP add rule LL6 for funcall broken after left paren
1 parent 9190687 commit a36462e

File tree

4 files changed

+93
-3
lines changed

4 files changed

+93
-3
lines changed

src/analysis/parsing/expression.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::lint::{DMLStyleError,
2525
CurrentRules},
2626
AuxParams};
2727
use crate::lint::rules::indentation::{IndentParenExprArgs};
28+
use crate::lint::rules::linebreaking::FuncCallBreakOnOpeningParenArgs;
2829

2930
#[derive(Debug, Clone, PartialEq)]
3031
pub struct UnaryExpressionContent {
@@ -214,11 +215,13 @@ impl TreeElement for FunctionCallContent {
214215
noderef, ReferenceKind::Callable));
215216
}
216217
}
217-
fn evaluate_rules(&self, acc: &mut Vec<DMLStyleError>, rules: &CurrentRules, _aux: AuxParams) {
218+
fn evaluate_rules(&self, acc: &mut Vec<DMLStyleError>, rules: &CurrentRules, aux: AuxParams) {
218219
rules.nsp_funpar.check(acc, NspFunparArgs::from_function_call(self));
219220
rules.nsp_inparen.check(acc, NspInparenArgs::from_function_call(self));
220221
rules.sp_punct.check(acc, SpPunctArgs::from_function_call(self));
221222
rules.indent_paren_expr.check(acc, IndentParenExprArgs::from_function_call(self));
223+
rules.func_call_break_on_opening_paren
224+
.check(acc, FuncCallBreakOnOpeningParenArgs::from_function_call(self, aux.depth));
222225
}
223226
}
224227

src/lint/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::fmt;
22
use std::fs;
33
use std::path::{Path, PathBuf};
44
use log::{debug, error, trace};
5+
use rules::linebreaking::FuncCallBreakOnOpeningParenArgs;
56
use serde::{Deserialize, Serialize};
67
use rules::{instantiate_rules, CurrentRules, RuleType};
78
use rules::{spacing::{SpBraceOptions, SpPunctOptions, NspFunparOptions,
@@ -73,6 +74,8 @@ pub struct LintCfg {
7374
pub indent_switch_case: Option<IndentSwitchCaseOptions>,
7475
#[serde(default)]
7576
pub indent_empty_loop: Option<IndentEmptyLoopOptions>,
77+
#[serde(default)]
78+
pub func_call_break_on_opening_paren: Option<FuncCallBreakOnOpeningParenOptions>,
7679
}
7780

7881
impl Default for LintCfg {
@@ -92,10 +95,12 @@ impl Default for LintCfg {
9295
indent_paren_expr: Some(IndentParenExprOptions{}),
9396
indent_switch_case: Some(IndentSwitchCaseOptions{indentation_spaces: INDENTATION_LEVEL_DEFAULT}),
9497
indent_empty_loop: Some(IndentEmptyLoopOptions{indentation_spaces: INDENTATION_LEVEL_DEFAULT}),
98+
func_call_break_on_opening_paren: Some(FuncCallBreakOnOpeningParenOptions{}),
9599
}
96100
}
97101
}
98102

103+
99104
#[derive(Debug, Clone)]
100105
pub struct DMLStyleError {
101106
pub error: LocalDMLError,

src/lint/rules/linebreaking.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::analysis::parsing::tree::{ZeroRange, TreeElement};
2+
use crate::analysis::parsing::{expression::{CastContent, FunctionCallContent}};
3+
use crate::lint::{DMLStyleError, LintCfg, RuleType};
4+
use crate::lint::rules::indentation::IndentParenExprArgs;
5+
use super::Rule;
6+
7+
pub struct FuncCallBreakOnOpeningParen {
8+
pub enabled: bool,
9+
}
10+
11+
pub struct FuncCallBreakOnOpeningParenArgs {
12+
pub member_ranges: Vec<ZeroRange>,
13+
pub expected_depth: u32,
14+
}
15+
16+
// pub struct FunctionCallContent {
17+
// pub fun: Expression,
18+
// pub lparen: LeafToken,
19+
// pub arguments: Vec<(SingleInitializer, Option<LeafToken>)>,
20+
// pub rparen: LeafToken,
21+
// }
22+
23+
impl FuncCallBreakOnOpeningParenArgs {
24+
pub fn from_function_call(node: &FunctionCallContent, depth: u32) -> Option<FuncCallBreakOnOpeningParenArgs> {
25+
let mut filtered_member_ranges: Vec<ZeroRange> = vec![];
26+
for (arg, _comma) in node.arguments.iter() {
27+
filtered_member_ranges.append(
28+
&mut IndentParenExprArgs::filter_out_parenthesized_ranges(
29+
arg.tokens()));
30+
}
31+
if filtered_member_ranges.is_empty()
32+
|| ! IndentParenExprArgs::is_broken_after_lparen(
33+
node.lparen.range(),
34+
filtered_member_ranges.first()?.to_owned()) {
35+
return None
36+
}
37+
Some(FuncCallBreakOnOpeningParenArgs {
38+
member_ranges: filtered_member_ranges,
39+
expected_depth: depth,
40+
})
41+
}
42+
}
43+
44+
impl FuncCallBreakOnOpeningParen {
45+
pub fn check(&self, acc: &mut Vec<DMLStyleError>, args: Option<FuncCallBreakOnOpeningParenArgs>) {
46+
if !self.enabled {
47+
return;
48+
}
49+
let Some(args) = args else { return; };
50+
// TODO : enable shared access to indentation_spaces param for all related rules
51+
let expected_line_start = args.expected_depth * 4; // Assuming 4 spaces per indent level
52+
let mut last_row = args.member_ranges.first().unwrap().row_start.0;
53+
54+
for member_range in args.member_ranges {
55+
if member_range.row_start.0 != last_row {
56+
last_row = member_range.row_start.0;
57+
if member_range.col_start.0 != expected_line_start {
58+
acc.push(self.create_err(member_range));
59+
}
60+
}
61+
}
62+
}
63+
}
64+
65+
impl Rule for FuncCallBreakOnOpeningParen {
66+
fn name() -> &'static str {
67+
"FUNC_CALL_BREAK_ON_OPENING_PAREN"
68+
}
69+
fn description() -> &'static str {
70+
"Function or method calls broken right after opening parenthesis should
71+
indent continuation lines one more level."
72+
}
73+
fn get_rule_type() -> RuleType {
74+
RuleType::LL6
75+
}
76+
}
77+

src/lint/rules/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod spacing;
22
pub mod indentation;
3+
pub mod linebreaking;
34

45
#[cfg(test)]
56
pub mod tests;
@@ -8,6 +9,7 @@ use spacing::{SpBracesRule,
89
SpPunctRule, NspFunparRule, NspInparenRule,
910
NspUnaryRule, NspTrailingRule};
1011
use indentation::{LongLinesRule, IndentNoTabRule, IndentCodeBlockRule, IndentClosingBraceRule, IndentParenExprRule, IndentSwitchCaseRule, IndentEmptyLoopRule};
12+
use linebreaking::FuncCallBreakOnOpeningParen;
1113
use crate::lint::{LintCfg, DMLStyleError};
1214
use crate::analysis::{LocalDMLError, parsing::tree::ZeroRange};
1315

@@ -24,7 +26,8 @@ pub struct CurrentRules {
2426
pub indent_closing_brace: IndentClosingBraceRule,
2527
pub indent_paren_expr: IndentParenExprRule,
2628
pub indent_switch_case: IndentSwitchCaseRule,
27-
pub indent_empty_loop: IndentEmptyLoopRule
29+
pub indent_empty_loop: IndentEmptyLoopRule,
30+
pub func_call_break_on_opening_paren: FuncCallBreakOnOpeningParen,
2831
}
2932

3033
pub fn instantiate_rules(cfg: &LintCfg) -> CurrentRules {
@@ -41,7 +44,8 @@ pub fn instantiate_rules(cfg: &LintCfg) -> CurrentRules {
4144
indent_closing_brace: IndentClosingBraceRule::from_options(&cfg.indent_closing_brace),
4245
indent_paren_expr: IndentParenExprRule { enabled: cfg.indent_paren_expr.is_some() },
4346
indent_switch_case: IndentSwitchCaseRule::from_options(&cfg.indent_switch_case),
44-
indent_empty_loop: IndentEmptyLoopRule::from_options(&cfg.indent_empty_loop)
47+
indent_empty_loop: IndentEmptyLoopRule::from_options(&cfg.indent_empty_loop),
48+
func_call_break_on_opening_paren: FuncCallBreakOnOpeningParen { enabled: &cfg.func_call_break_on_opening_paren.is_some() },
4549
}
4650
}
4751

@@ -70,6 +74,7 @@ pub enum RuleType {
7074
NspUnary,
7175
NspTrailing,
7276
LL1,
77+
LL6,
7378
IN2,
7479
IN3,
7580
IN4,

0 commit comments

Comments
 (0)