From 0c0ee48ae5284cb9f3591a4863b16219f2fd3aa3 Mon Sep 17 00:00:00 2001 From: light-ly Date: Tue, 29 Oct 2024 22:30:21 +0800 Subject: [PATCH] add param assignments --- src/core/hdlparam.rs | 10 ++-- src/core/sv_parser.rs | 117 ++++++++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 33 deletions(-) diff --git a/src/core/hdlparam.rs b/src/core/hdlparam.rs index ffb1ce3..fc6401e 100644 --- a/src/core/hdlparam.rs +++ b/src/core/hdlparam.rs @@ -153,7 +153,7 @@ pub enum AssignType { #[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)] pub struct InstPort { pub port: Option, - pub assign_name: String, + pub assign_val: Option, pub assign_type: AssignType, pub range: Range } @@ -161,7 +161,7 @@ pub struct InstPort { #[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)] pub struct InstParameter { pub parameter: Option, - pub assign_name: String, + pub assign_val: Option, pub assign_type: AssignType, pub range: Range } @@ -355,7 +355,7 @@ impl FastHdlparam { } } - pub fn add_instance(&mut self, name: &str, inst_type: &str, port_assign: Vec, line: u32, character: u32, end_character: u32, + pub fn add_instance(&mut self, name: &str, inst_type: &str, params_assign: Vec, ports_assign: Vec, line: u32, character: u32, end_character: u32, param_start_line: u32, param_start_character: u32, param_end_line: u32, param_end_character: u32, port_start_line: u32, port_start_character: u32, port_end_line: u32, port_end_character: u32 ) { if let Some(last_module) = self.content.last_mut() { @@ -376,7 +376,7 @@ impl FastHdlparam { } ) }, - intstparams_assignment: Vec::new(), + intstparams_assignment: params_assign, instports: if port_start_line == 0 { None } else { @@ -391,7 +391,7 @@ impl FastHdlparam { } ) }, - intstport_assignment: port_assign, + intstport_assignment: ports_assign, range: Range { start: Position { line, character diff --git a/src/core/sv_parser.rs b/src/core/sv_parser.rs index 7a5fd44..ec88f8f 100644 --- a/src/core/sv_parser.rs +++ b/src/core/sv_parser.rs @@ -6,13 +6,13 @@ use log::info; use regex::Regex; use ropey::Rope; use tower_lsp::lsp_types::Url; -use sv_parser::{unwrap_locate, unwrap_node, EventIter, ListOfParamAssignments, Locate, NodeEvent, ParamAssignment, ParameterDeclaration, RefNode, SyntaxTree}; +use sv_parser::{unwrap_locate, unwrap_node, EventIter, ListOfParamAssignments, Locate, NodeEvent, ParamAssignment, ParameterDeclaration, RefNode, SpecifyBlock, SyntaxTree}; use crate::core::hdlparam::{AssignType, Position, Range}; use crate::sources::{recovery_sv_parse_with_retry, LSPSupport}; use crate::utils::to_escape_path; -use super::hdlparam::{self, FastHdlparam, InstPort, Macro}; +use super::hdlparam::{self, FastHdlparam, InstParameter, InstPort, Macro}; macro_rules! advance_until_leave { ($tokens:ident, $tree:ident, $event_iter:ident, $node:path) => {{ @@ -312,16 +312,21 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re let (param_start_line, param_start_character, param_end_line, param_end_character) = match unwrap_node!(x, ParameterValueAssignment) { Some(inst_node) => { - // get_port_parameter_range(&content, inst_node) get_pp_range(&doc, inst_node) } _ => (0, 0, 0, 0) }; + let inst_param_assignments = if let Some(param_node) = unwrap_node!(x, ParameterValueAssignment) { + get_instance_params(syntax_tree, &doc, param_node) + } else { + Vec::::new() + }; + let inst_port_assignments = get_instance_ports(&syntax_tree, &doc, hier_node.clone()); let (port_start_line, port_start_character, port_end_line, port_end_character) = get_pp_range(&doc, hier_node); - hdlparam.add_instance(name, inst_type, inst_port_assignments, line, character, end_character, + hdlparam.add_instance(name, inst_type, inst_param_assignments, inst_port_assignments, line, character, end_character, param_start_line, param_start_character, param_end_line, param_end_character, port_start_line, port_start_character, port_end_line, port_end_character ); @@ -345,7 +350,7 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re let inst_port_assignments = get_instance_ports(&syntax_tree, &doc, gate_node.clone()); let (port_start_line, port_start_character, port_end_line, port_end_character) = get_pp_range(&doc, gate_node); - hdlparam.add_instance(name, inst_type, inst_port_assignments, line, character, end_character, + hdlparam.add_instance(name, inst_type, Vec::::new(), inst_port_assignments, line, character, end_character, param_start_line, param_start_character, param_end_line, param_end_character, port_start_line, port_start_character, port_end_line, port_end_character ); @@ -362,22 +367,6 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re Ok(hdlparam) } -/// 返回的四元组:(start_line, start_character, end_line, end_character) -fn get_port_parameter_range(content: &[String], node: RefNode) -> (u32, u32, u32, u32) { - let locate = get_first_last_locate(node); - if locate.is_none() { - ( 0, 0, 0, 0 ) - } else { - let locate = locate.unwrap(); - let start_line = locate.0.line; - let start_character = get_column_by_offset(&content, locate.0.offset) as u32; - let end_line = locate.1.line; - let end_character = get_column_by_offset(&content, locate.1.offset + locate.1.len) as u32; - - ( start_line, start_character, end_line, end_character ) - } -} - // 获取 port 或者 param 的 range /// 返回的四元组:(start_line, start_character, end_line, end_character) fn get_pp_range(doc: &Rope, node: RefNode) -> (u32, u32, u32, u32) { @@ -411,6 +400,78 @@ fn get_first_last_locate(node: RefNode) -> Option<(Locate, Locate)> { } } +fn get_instance_params(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Vec { + let mut parameters = Vec::new(); + + for list in node { + match unwrap_node!(list, ListOfParameterAssignmentsNamed, ListOfParameterAssignmentsOrdered) { + Some(RefNode::ListOfParameterAssignmentsNamed(x)) => { + for assign in x { + if let RefNode::NamedParameterAssignment(ident) = assign { + let (start_line, start_character, end_line, end_character) = get_pp_range(doc, assign); + let param_name_locate = get_identifier(RefNode::ParameterIdentifier(&(ident.nodes.1))); + let param_name = syntax_tree.get_str(¶m_name_locate).unwrap(); + let name = if let (_, Some(name_expr), _) = ident.nodes.2.nodes.clone() { + if let Some(RefNode::Expression(name_expr)) = unwrap_node!(name_expr.into_iter(), Expression) { + let expr = sv_parser::NeedParseExpression::Expression(name_expr.clone()); + let (expr, _) = parse_expression(syntax_tree, &expr); + Some(expr) + } else { + None + } + } else { + None + }; + let param = InstParameter { + parameter: Some(param_name.to_string()), + assign_val: name, + assign_type: AssignType::Named, + range: Range { + start: Position { line: start_line, character: start_character }, + end: Position { line: end_line, character: end_character } + } + }; + parameters.push(param); + }; + } + } + Some(RefNode::ListOfParameterAssignmentsOrdered(x)) => { + for assign in x { + if let RefNode::OrderedParameterAssignment(ident) = assign { + let expr = ident.nodes.0.clone(); + if let Some(RefNode::Expression(expr)) = unwrap_node!(expr.into_iter(), Expression) { + let start_locate = get_identifier(RefNode::Expression(expr)); + let expr = sv_parser::NeedParseExpression::Expression(expr.clone()); + let (expr, locate) = parse_expression(syntax_tree, &expr); + let start_locate = start_locate.unwrap_or(Locate { offset: 0, line: 0, len: 0 }); + let locate = locate.unwrap_or(start_locate); + let param = InstParameter { + parameter: None, + assign_val: Some(expr), + assign_type: AssignType::Ordered, + range: Range { + start: get_position(doc, start_locate), + end: get_position(doc, Locate { + offset: locate.offset + locate.len, + line: locate.line, + len: 0 + }) + } + }; + parameters.push(param); + } + } + } + } + _ => {} + } + } + + parameters.sort_by_key(|p| p.range.clone()); + parameters.dedup_by_key(|p| p.range.clone()); + parameters +} + fn get_instance_ports(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Vec { let mut ports = Vec::new(); for list in node { @@ -425,16 +486,16 @@ fn get_instance_ports(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Ve if let (_, Some(name_expr), _) = ident.nodes.3.clone().unwrap().nodes { let expr = sv_parser::NeedParseExpression::Expression(name_expr); let (expr, _) = parse_expression(syntax_tree, &expr); - expr + Some(expr) } else { - "".to_string() + None } } else { - "".to_string() + None }; let port = InstPort { port: Some(port_name.to_string()), - assign_name: name, + assign_val: name, assign_type: AssignType::Named, range: Range { start: Position { line: start_line, character: start_character }, @@ -456,7 +517,7 @@ fn get_instance_ports(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Ve let locate = locate.unwrap_or(start_locate); let port = InstPort { port: None, - assign_name: expr, + assign_val: Some(expr), assign_type: AssignType::Ordered, range: Range { start: get_position(doc, start_locate), @@ -481,7 +542,7 @@ fn get_instance_ports(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Ve let locate = locate.unwrap_or(start_locate); let port = InstPort { port: None, - assign_name: expr, + assign_val: Some(expr), assign_type: AssignType::Ordered, range: Range { start: get_position(doc, start_locate), @@ -503,7 +564,7 @@ fn get_instance_ports(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Ve let locate = locate.unwrap_or(start_locate); let port = InstPort { port: None, - assign_name: expr, + assign_val: Some(expr), assign_type: AssignType::Ordered, range: Range { start: get_position(doc, start_locate),