add param assignments
This commit is contained in:
parent
3303b65c3f
commit
0c0ee48ae5
@ -153,7 +153,7 @@ pub enum AssignType {
|
||||
#[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)]
|
||||
pub struct InstPort {
|
||||
pub port: Option<String>,
|
||||
pub assign_name: String,
|
||||
pub assign_val: Option<String>,
|
||||
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<String>,
|
||||
pub assign_name: String,
|
||||
pub assign_val: Option<String>,
|
||||
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<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,
|
||||
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
|
||||
|
@ -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::<InstParameter>::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::<InstParameter>::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<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(¶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<InstPort> {
|
||||
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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user