From 152ff6a00cb198b7fed9dc7bf5baab0e3edf3dc3 Mon Sep 17 00:00:00 2001 From: Thomas Heuschling Date: Tue, 16 Sep 2025 15:04:29 +0200 Subject: [PATCH] proposed fix for #309 + added passing test --- MANUAL.md | 10 ++++- src/syntaxrules/parameter_in_package.rs | 38 +++++++++---------- .../syntaxrules/pass/parameter_in_package.sv | 5 +++ 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/MANUAL.md b/MANUAL.md index 6342560c..94f550ff 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -5099,13 +5099,21 @@ Replace `parameter` keyword with `localparam`. In a package, `localparam` properly describes the non-overridable semantics. -### Pass Example (1 of 1) +### Pass Example (1 of 2) ```systemverilog package P; localparam int A = 1; endpackage ``` +### Pass Example (2 of 2) +```systemverilog +package foo; + class bar #( parameter int baz ); + endclass +endpackage +``` + ### Fail Example (1 of 1) ```systemverilog package P; diff --git a/src/syntaxrules/parameter_in_package.rs b/src/syntaxrules/parameter_in_package.rs index 4224efa6..50df3c53 100644 --- a/src/syntaxrules/parameter_in_package.rs +++ b/src/syntaxrules/parameter_in_package.rs @@ -1,9 +1,11 @@ use crate::config::ConfigOption; use crate::linter::{SyntaxRule, SyntaxRuleResult}; -use sv_parser::{unwrap_locate, unwrap_node, NodeEvent, RefNode, SyntaxTree}; +use sv_parser::{unwrap_locate, NodeEvent, RefNode, SyntaxTree}; #[derive(Default)] -pub struct ParameterInPackage; +pub struct ParameterInPackage { + inside_param_port_list : bool, +} impl SyntaxRule for ParameterInPackage { fn check( @@ -12,24 +14,22 @@ impl SyntaxRule for ParameterInPackage { event: &NodeEvent, _option: &ConfigOption, ) -> SyntaxRuleResult { - let node = match event { - NodeEvent::Enter(x) => x, - NodeEvent::Leave(_) => { - return SyntaxRuleResult::Pass; - } - }; - match node { - RefNode::PackageDeclaration(x) => { - let param = unwrap_node!(*x, ParameterDeclaration); - if let Some(param) = param { - let param_locate = unwrap_locate!(param).unwrap(); - SyntaxRuleResult::FailLocate(*param_locate) - } else { - SyntaxRuleResult::Pass + match event { + NodeEvent::Enter(RefNode::ParameterPortList(_)) => { + self.inside_param_port_list = true; + }, + NodeEvent::Leave(RefNode::ParameterPortList(_)) => { + self.inside_param_port_list = false; + }, + NodeEvent::Enter(RefNode::ParameterDeclaration(&ref x)) => { + if !self.inside_param_port_list { + let param_locate = unwrap_locate!(x).unwrap(); + return SyntaxRuleResult::FailLocate(*param_locate) } - } - _ => SyntaxRuleResult::Pass, - } + }, + _ => {} + }; + return SyntaxRuleResult::Pass } fn name(&self) -> String { diff --git a/testcases/syntaxrules/pass/parameter_in_package.sv b/testcases/syntaxrules/pass/parameter_in_package.sv index 35aa8477..25ff40ac 100644 --- a/testcases/syntaxrules/pass/parameter_in_package.sv +++ b/testcases/syntaxrules/pass/parameter_in_package.sv @@ -1,3 +1,8 @@ package P; localparam int A = 1; endpackage +//////////////////////////////////////////////////////////////////////////////// +package foo; + class bar #( parameter int baz ); + endclass +endpackage