add param assignments

This commit is contained in:
light-ly 2024-10-29 22:30:21 +08:00
parent 3303b65c3f
commit 0c0ee48ae5
2 changed files with 94 additions and 33 deletions

View File

@ -153,7 +153,7 @@ pub enum AssignType {
#[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)] #[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)]
pub struct InstPort { pub struct InstPort {
pub port: Option<String>, pub port: Option<String>,
pub assign_name: String, pub assign_val: Option<String>,
pub assign_type: AssignType, pub assign_type: AssignType,
pub range: Range pub range: Range
} }
@ -161,7 +161,7 @@ pub struct InstPort {
#[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)] #[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)]
pub struct InstParameter { pub struct InstParameter {
pub parameter: Option<String>, pub parameter: Option<String>,
pub assign_name: String, pub assign_val: Option<String>,
pub assign_type: AssignType, pub assign_type: AssignType,
pub range: Range pub range: Range
} }
@ -355,7 +355,7 @@ impl FastHdlparam {
} }
} }
pub fn add_instance(&mut self, name: &str, inst_type: &str, port_assign: Vec<InstPort>, line: u32, character: u32, end_character: u32, pub fn add_instance(&mut self, name: &str, inst_type: &str, params_assign: Vec<InstParameter>, ports_assign: Vec<InstPort>, line: u32, character: u32, end_character: u32,
param_start_line: u32, param_start_character: u32, param_end_line: u32, param_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 ) { 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() { 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 { instports: if port_start_line == 0 {
None None
} else { } else {
@ -391,7 +391,7 @@ impl FastHdlparam {
} }
) )
}, },
intstport_assignment: port_assign, intstport_assignment: ports_assign,
range: Range { range: Range {
start: Position { start: Position {
line, character line, character

View File

@ -6,13 +6,13 @@ use log::info;
use regex::Regex; use regex::Regex;
use ropey::Rope; use ropey::Rope;
use tower_lsp::lsp_types::Url; 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::core::hdlparam::{AssignType, Position, Range};
use crate::sources::{recovery_sv_parse_with_retry, LSPSupport}; use crate::sources::{recovery_sv_parse_with_retry, LSPSupport};
use crate::utils::to_escape_path; 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 { macro_rules! advance_until_leave {
($tokens:ident, $tree:ident, $event_iter:ident, $node:path) => {{ ($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, let (param_start_line, param_start_character,
param_end_line, param_end_character) = match unwrap_node!(x, ParameterValueAssignment) { param_end_line, param_end_character) = match unwrap_node!(x, ParameterValueAssignment) {
Some(inst_node) => { Some(inst_node) => {
// get_port_parameter_range(&content, inst_node)
get_pp_range(&doc, inst_node) get_pp_range(&doc, inst_node)
} }
_ => (0, 0, 0, 0) _ => (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::<InstParameter>::new()
};
let inst_port_assignments = get_instance_ports(&syntax_tree, &doc, hier_node.clone()); 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); 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, param_start_line, param_start_character, param_end_line, param_end_character,
port_start_line, port_start_character, port_end_line, port_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 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); 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::<InstParameter>::new(), inst_port_assignments, line, character, end_character,
param_start_line, param_start_character, param_end_line, param_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 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) 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 // 获取 port 或者 param 的 range
/// 返回的四元组:(start_line, start_character, end_line, end_character) /// 返回的四元组:(start_line, start_character, end_line, end_character)
fn get_pp_range(doc: &Rope, node: RefNode) -> (u32, u32, u32, u32) { 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<InstParameter> {
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(&param_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<InstPort> { fn get_instance_ports(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Vec<InstPort> {
let mut ports = Vec::new(); let mut ports = Vec::new();
for list in node { 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 { if let (_, Some(name_expr), _) = ident.nodes.3.clone().unwrap().nodes {
let expr = sv_parser::NeedParseExpression::Expression(name_expr); let expr = sv_parser::NeedParseExpression::Expression(name_expr);
let (expr, _) = parse_expression(syntax_tree, &expr); let (expr, _) = parse_expression(syntax_tree, &expr);
expr Some(expr)
} else { } else {
"".to_string() None
} }
} else { } else {
"".to_string() None
}; };
let port = InstPort { let port = InstPort {
port: Some(port_name.to_string()), port: Some(port_name.to_string()),
assign_name: name, assign_val: name,
assign_type: AssignType::Named, assign_type: AssignType::Named,
range: Range { range: Range {
start: Position { line: start_line, character: start_character }, 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 locate = locate.unwrap_or(start_locate);
let port = InstPort { let port = InstPort {
port: None, port: None,
assign_name: expr, assign_val: Some(expr),
assign_type: AssignType::Ordered, assign_type: AssignType::Ordered,
range: Range { range: Range {
start: get_position(doc, start_locate), 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 locate = locate.unwrap_or(start_locate);
let port = InstPort { let port = InstPort {
port: None, port: None,
assign_name: expr, assign_val: Some(expr),
assign_type: AssignType::Ordered, assign_type: AssignType::Ordered,
range: Range { range: Range {
start: get_position(doc, start_locate), 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 locate = locate.unwrap_or(start_locate);
let port = InstPort { let port = InstPort {
port: None, port: None,
assign_name: expr, assign_val: Some(expr),
assign_type: AssignType::Ordered, assign_type: AssignType::Ordered,
range: Range { range: Range {
start: get_position(doc, start_locate), start: get_position(doc, start_locate),