diff --git a/src/analysis/parsing/expression.rs b/src/analysis/parsing/expression.rs index 1189d01..8588086 100644 --- a/src/analysis/parsing/expression.rs +++ b/src/analysis/parsing/expression.rs @@ -177,6 +177,7 @@ impl TreeElement for ParenExpressionContent { } fn evaluate_rules(&self, acc: &mut Vec, rules: &CurrentRules, _aux: AuxParams) { rules.indent_paren_expr.check(IndentParenExprArgs::from_paren_expression(self), acc); + rules.nsp_inparen.check( NspInparenArgs::from_paren_expression(self), acc); } } diff --git a/src/analysis/parsing/statement.rs b/src/analysis/parsing/statement.rs index fb44fe3..21012c9 100644 --- a/src/analysis/parsing/statement.rs +++ b/src/analysis/parsing/statement.rs @@ -1120,6 +1120,7 @@ impl TreeElement for SwitchContent { { rules.indent_closing_brace.check(IndentClosingBraceArgs::from_switch_content(self, aux.depth), acc); rules.indent_paren_expr.check(IndentParenExprArgs::from_switch(self), acc); + rules.sp_brace.check(SpBracesArgs::from_switch(self), acc); } } diff --git a/src/analysis/parsing/structure.rs b/src/analysis/parsing/structure.rs index eec4969..1894f98 100644 --- a/src/analysis/parsing/structure.rs +++ b/src/analysis/parsing/structure.rs @@ -624,6 +624,10 @@ impl TreeElement for Instantiation { tok, file, ReferenceKind::Template)); accumulator.extend(refs); } + fn evaluate_rules(&self, acc: &mut Vec, rules: &CurrentRules, _aux: AuxParams) { + rules.nsp_inparen.check(NspInparenArgs::from_instantiation(self), acc); + rules.sp_punct.check(SpPunctArgs::from_instantiation(self), acc); + } } fn parse_instantiation(context: &ParseContext, stream: &mut FileParser<'_>, _file_info: &FileInfo) @@ -855,6 +859,9 @@ impl TreeElement for CompositeObjectContent { errors } fn references<'a>(&self, _accumulator: &mut Vec, _file: FileSpec<'a>) {} + fn evaluate_rules(&self, acc: &mut Vec, rules: &CurrentRules, _aux: AuxParams) { + rules.nsp_inparen.check(NspInparenArgs::from_composite_obj_content(self), acc); + } } #[derive(Debug, Clone, PartialEq)] diff --git a/src/lint/rules/spacing.rs b/src/lint/rules/spacing.rs index a87ba73..6bcfd09 100644 --- a/src/lint/rules/spacing.rs +++ b/src/lint/rules/spacing.rs @@ -9,14 +9,23 @@ use crate::lint::{rules::{Rule, RuleType}, DMLStyleError}; use crate::analysis::parsing::tree::{LeafToken, TreeElement, ZeroRange}; use crate::analysis::parsing::expression::{BinaryExpressionContent, - FunctionCallContent, IndexContent, + FunctionCallContent, + IndexContent, + ParenExpressionContent, PostUnaryExpressionContent, TertiaryExpressionContent, UnaryExpressionContent}; -use crate::analysis::parsing::statement::{AfterContent, CompoundContent, ExpressionStmtContent, - ForContent, IfContent, VariableDeclContent, +use crate::analysis::parsing::statement::{AfterContent, + CompoundContent, + ExpressionStmtContent, + ForContent, + IfContent, + SwitchContent, + VariableDeclContent, WhileContent}; -use crate::analysis::parsing::structure::{MethodContent, +use crate::analysis::parsing::structure::{CompositeObjectContent, + Instantiation, + MethodContent, ObjectStatementsContent}; use crate::span::{ZeroIndexed, Range}; @@ -206,6 +215,17 @@ impl SpBracesArgs { rbrace: node.rbrace.range(), }) } + pub fn from_switch(node: &SwitchContent) -> Option { + if node.cases.is_empty() { + return None; + } + Some(SpBracesArgs { + body_start: node.cases.first().unwrap().range(), + body_end: node.cases.last().unwrap().range(), + lbrace: node.lbrace.range(), + rbrace: node.rbrace.range(), + }) + } } impl SpBracesRule { @@ -465,6 +485,34 @@ impl SpPunctArgs { after_range_list, }) } + pub fn from_instantiation(node: &Instantiation) -> Option { + if let Instantiation::Many(_, templates_list, _) = node { + let mut before_range_list = vec![]; + let mut punct_range_list = vec![]; + let mut after_range_list = vec![]; + let mut iterator = templates_list.iter().peekable(); + + while let Some((template_name, comma)) = iterator.next() { + if let Some(comma_token) = comma { + before_range_list.push(template_name.range()); + punct_range_list.push(comma_token.range()); + if let Some((next_template_name, _)) = iterator.peek() { + after_range_list.push(Some(next_template_name.range())); + } else { + after_range_list.push(None); + } + } + } + + Some(SpPunctArgs { + before_range_list, + punct_range_list, + after_range_list, + }) + } else { + None + } + } } impl SpPunctRule { @@ -600,6 +648,41 @@ impl NspInparenArgs { closing: node.rparen.range(), }) } + pub fn from_composite_obj_content(node: &CompositeObjectContent) + -> Option { + if node.dimensions.is_empty() { + return None; + } + let dimension = node.dimensions.first().unwrap(); + Some(NspInparenArgs { + opening: dimension.0.range(), + content_start: dimension.1.range(), + content_end: dimension.3.range(), + closing: dimension.4.range(), + }) + } + pub fn from_instantiation(node: &Instantiation) + -> Option { + if let Instantiation::Many(lparen, templates, rparen) = node { + Some(NspInparenArgs { + opening: lparen.range(), + content_start: templates.range(), + content_end: templates.range(), + closing: rparen.range(), + }) + } else { + None + } + } + pub fn from_paren_expression(node: &ParenExpressionContent) + -> Option { + Some(NspInparenArgs { + opening: node.lparen.range(), + content_start: node.expr.range(), + content_end: node.expr.range(), + closing: node.rparen.range(), + }) + } pub fn from_function_call(node: &FunctionCallContent) -> Option { let content_start_range; diff --git a/src/lint/rules/tests/spacing/nsp_inparen.rs b/src/lint/rules/tests/spacing/nsp_inparen.rs index a5160c4..cb47e1d 100644 --- a/src/lint/rules/tests/spacing/nsp_inparen.rs +++ b/src/lint/rules/tests/spacing/nsp_inparen.rs @@ -2,14 +2,14 @@ use crate::lint::rules::tests::common::{set_up, assert_snippet}; use crate::lint::rules::RuleType; // NSP.inparen immediately inside parentheses or brackets -static NO_SPACE_INPAREN_METHOD_FUNC_INDEX_INCORRECT: &str = " +static METHOD_FUNC_INDEX_INCORRECT: &str = " method this_is_some_method( conf_object_t *dummy_obj ) { if ( !dummy_obj[ 0 ] ) return; } "; #[test] -fn no_space_inparen_method_func_index_incorrect() { +fn method_func_index_incorrect() { let mut rules = set_up(); let expected_errors = define_expected_errors!( RuleType::NspInparen, @@ -20,21 +20,49 @@ fn no_space_inparen_method_func_index_incorrect() { (2, 2, 20, 21), (2, 2, 22, 23), ); - assert_snippet(NO_SPACE_INPAREN_METHOD_FUNC_INDEX_INCORRECT, expected_errors, &rules); + assert_snippet(METHOD_FUNC_INDEX_INCORRECT, expected_errors, &rules); // Test rule disable rules.nsp_inparen.enabled = false; - assert_snippet(NO_SPACE_INPAREN_METHOD_FUNC_INDEX_INCORRECT, vec![], &rules); + assert_snippet(METHOD_FUNC_INDEX_INCORRECT, vec![], &rules); } // NSP.inparen immediately inside parentheses or brackets -static NO_SPACE_INPAREN_METHOD_FUNC_INDEX_CORRECT: &str = " +static METHOD_FUNC_INDEX_CORRECT: &str = " method this_is_some_method(conf_object_t *dummy_obj) { if (!dummy_obj[0]) return; } "; #[test] -fn no_space_inparen_method_func_index_correct() { +fn method_func_index_correct() { let rules = set_up(); - assert_snippet(NO_SPACE_INPAREN_METHOD_FUNC_INDEX_CORRECT, vec![], &rules); -} \ No newline at end of file + assert_snippet(METHOD_FUNC_INDEX_CORRECT, vec![], &rules); +} + + +pub static COMPOSITE_ARRAY_DECLARATION_AND_TEMPLATES_INCORRECT: &str = " +bank some_bank { + group some_group[ i < ( GROUP_COUNT ) ] { + register some_reg is ( some_template, another_template ) { + param desc = \"Register description\"; + } + } +} +"; +#[test] +fn composite_array_declaration_and_templates_incorrect() { + let mut rules = set_up(); + let expected_errors = define_expected_errors!( + RuleType::NspInparen, + (2, 2, 21, 22), + (2, 2, 27, 28), + (2, 2, 39, 40), + (2, 2, 41, 42), + (3, 3, 30, 31), + (3, 3, 62, 63), + ); + assert_snippet(COMPOSITE_ARRAY_DECLARATION_AND_TEMPLATES_INCORRECT, expected_errors, &rules); + // Test rule disable + rules.nsp_inparen.enabled = false; + assert_snippet(COMPOSITE_ARRAY_DECLARATION_AND_TEMPLATES_INCORRECT, vec![], &rules); +} diff --git a/src/lint/rules/tests/spacing/sp_braces.rs b/src/lint/rules/tests/spacing/sp_braces.rs index c8424f9..640e418 100644 --- a/src/lint/rules/tests/spacing/sp_braces.rs +++ b/src/lint/rules/tests/spacing/sp_braces.rs @@ -2,7 +2,7 @@ use crate::lint::rules::tests::common::{set_up, assert_snippet}; use crate::lint::rules::RuleType; // SP.braces around braces ({ and }) -static SPACE_BRACES_METHOD_BANK_REGISTER_FIELD_INCORRECT: &str = " +static METHOD_BANK_REGISTER_FIELD_INCORRECT: &str = " method this_is_some_method() {return 0;} method this_is_empty_method() { } @@ -18,7 +18,7 @@ bank pcie_config {register command {field mem { } "; #[test] -fn space_braces_method_bank_register_field_incorrect() { +fn method_bank_register_field_incorrect() { let mut rules = set_up(); let expected_errors = define_expected_errors!( RuleType::SpBraces, @@ -29,13 +29,13 @@ fn space_braces_method_bank_register_field_incorrect() { (7, 7, 24, 25), (7, 7, 43, 44), ); - assert_snippet(SPACE_BRACES_METHOD_BANK_REGISTER_FIELD_INCORRECT, expected_errors, &rules); + assert_snippet(METHOD_BANK_REGISTER_FIELD_INCORRECT, expected_errors, &rules); // Test rule disable rules.sp_brace.enabled = false; - assert_snippet(SPACE_BRACES_METHOD_BANK_REGISTER_FIELD_INCORRECT, vec![], &rules); + assert_snippet(METHOD_BANK_REGISTER_FIELD_INCORRECT, vec![], &rules); } -static SPACE_BRACES_METHOD_BANK_REGISTER_FIELD_CORRECT: &str = " +static METHOD_BANK_REGISTER_FIELD_CORRECT: &str = " method this_is_some_method() { return 0; } method this_is_empty_method() { } @@ -51,18 +51,18 @@ bank pcie_config { register command { field mem { } "; #[test] -fn space_braces_method_bank_register_field_correct() { +fn method_bank_register_field_correct() { let rules = set_up(); - assert_snippet(SPACE_BRACES_METHOD_BANK_REGISTER_FIELD_CORRECT, vec![], &rules); + assert_snippet(METHOD_BANK_REGISTER_FIELD_CORRECT, vec![], &rules); } -static SPACE_BRACES_STRUCT_LAYOUT_BITF_INCORRECT: &str = " +static STRUCT_LAYOUT_BITF_INCORRECT: &str = " typedef struct {uint16 idx;} hqm_cq_list_release_ctx_t; typedef layout \"little-endian\" {bitfields 1 {uint1 cq @ [0:0];} byte;} q_t; "; #[test] -fn space_braces_struct_layout_bitf_incorrect() { +fn struct_layout_bitf_incorrect() { let mut rules = set_up(); let expected_errors = define_expected_errors!( RuleType::SpBraces, @@ -73,22 +73,59 @@ fn space_braces_struct_layout_bitf_incorrect() { (3, 3, 44, 45), (3, 3, 62, 63), ); - assert_snippet(SPACE_BRACES_STRUCT_LAYOUT_BITF_INCORRECT, expected_errors, &rules); + assert_snippet(STRUCT_LAYOUT_BITF_INCORRECT, expected_errors, &rules); // Test rule disable rules.sp_brace.enabled = false; - assert_snippet(SPACE_BRACES_STRUCT_LAYOUT_BITF_INCORRECT, vec![], &rules); + assert_snippet(STRUCT_LAYOUT_BITF_INCORRECT, vec![], &rules); } -static SPACE_BRACES_STRUCT_LAYOUT_BITF_CORRECT: &str = " +static STRUCT_LAYOUT_BITF_CORRECT: &str = " typedef struct { uint16 idx; } hqm_cq_list_release_ctx_t; typedef layout \"little-endian\" { bitfields 1 { uint1 cq @ [0:0]; } byte; } q_t; "; #[test] -fn space_braces_struct_layout_bitf_correct() { +fn struct_layout_bitf_correct() { let mut rules = set_up(); - assert_snippet(SPACE_BRACES_STRUCT_LAYOUT_BITF_CORRECT, vec![], &rules); + assert_snippet(STRUCT_LAYOUT_BITF_CORRECT, vec![], &rules); // Test rule disable rules.sp_brace.enabled = false; - assert_snippet(SPACE_BRACES_STRUCT_LAYOUT_BITF_CORRECT, vec![], &rules); + assert_snippet(STRUCT_LAYOUT_BITF_CORRECT, vec![], &rules); } + +pub static SWITCHES_INCORRECT: &str = " +method test_switch(int some_var) { + switch (some_var){ + case 1: + print(1); + break; + case extra: + print(\"extra\"); + break; + case 2: + print(2); + break; + case COMPOUND:{ + print(1); + print(2); + break; + } + default: + print(0); + break; + } +} +"; +#[test] +fn switches_incorrect() { + let mut rules = set_up(); + let expected_errors = define_expected_errors!( + RuleType::SpBraces, + (2, 2, 52, 53), + (11, 11, 18, 19), + ); + assert_snippet(SWITCHES_INCORRECT, expected_errors, &rules); + // Test rule disable + rules.sp_brace.enabled = false; + assert_snippet(SWITCHES_INCORRECT, vec![], &rules); +} \ No newline at end of file