fix instance parameter/port range

This commit is contained in:
light-ly 2024-10-26 17:55:23 +08:00
parent 2b3752edba
commit a749580bdb

View File

@ -7,7 +7,7 @@ use log::info;
use regex::Regex;
use ropey::Rope;
use tower_lsp::lsp_types::Url;
use sv_parser::{unwrap_locate, unwrap_node, EventIter, ListOfParamAssignments, ListOfTypeAssignments, Locate, NodeEvent, ParamAssignment, ParameterDeclaration, RefNode, SyntaxTree, TypeAssignment};
use sv_parser::{unwrap_locate, unwrap_node, EventIter, ListOfParamAssignments, Locate, NodeEvent, ParamAssignment, ParameterDeclaration, RefNode, SyntaxTree};
use crate::sources::recovery_sv_parse_with_retry;
use crate::utils::to_escape_path;
@ -303,28 +303,22 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re
let inst_type = syntax_tree.get_str(&id).unwrap();
if let Some(id) = unwrap_node!(x, HierarchicalInstance) {
let hier_node = id.clone();
let id = get_identifier(id).unwrap();
let name = syntax_tree.get_str(&id).unwrap();
let (line, character) = (id.line, get_column_by_offset(&content, id.offset) as u32);
let end_character = character + id.len as u32;
let (param_start_line, param_start_character,
param_end_line, param_end_character) = match unwrap_node!(x, ListOfParameterAssignments) {
Some(RefNode::ListOfParameterAssignments(x)) => {
let param_assignments = sv_parser::NeedGetLocate::ParamAssignments(x.clone());
get_port_parameter_range(&content, &param_assignments)
param_end_line, param_end_character) = match unwrap_node!(x, ParameterValueAssignment) {
Some(inst_node) => {
get_port_parameter_range(&content, inst_node)
}
_ => (0, 0, 0, 0)
};
let (port_start_line, port_start_character,
port_end_line, port_end_character) = match unwrap_node!(x, ListOfPortConnections) {
Some(RefNode::ListOfPortConnections(x)) => {
let param_assignments = sv_parser::NeedGetLocate::PortConnections(x.clone());
get_port_parameter_range(&content, &param_assignments)
}
_ => (0, 0, 0, 0)
};
port_end_line, port_end_character) = get_port_parameter_range(&content, hier_node);
hdlparam.add_instance(name, inst_type, line, character, end_character,
param_start_line, param_start_character, param_end_line, param_end_character,
@ -340,16 +334,16 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re
match unwrap_node!(x, NInputGateInstance, NOutputGateInstance) {
Some(id) => {
let gate_node = id.clone();
let id = get_identifier(id).unwrap();
let name = syntax_tree.get_str(&id).unwrap();
let (line, character) = (id.line, get_column_by_offset(&content, id.offset) as u32);
let end_character = character + id.len as u32;
let gate_instance = sv_parser::NeedGetLocate::GateInstantiation(x.clone());
let (param_start_line, param_start_character, param_end_line, param_end_character) = (0, 0, 0, 0);
let (port_start_line, port_start_character,
port_end_line, port_end_character) = get_port_parameter_range(&content, &gate_instance);
port_end_line, port_end_character) = get_port_parameter_range(&content, gate_node);
hdlparam.add_instance(name, inst_type, 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
@ -367,8 +361,8 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re
Ok(hdlparam)
}
fn get_port_parameter_range(content: &[String], x: &sv_parser::NeedGetLocate) -> (u32, u32, u32, u32) {
let locate = get_first_last_locate(&x);
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 {
@ -379,120 +373,25 @@ fn get_port_parameter_range(content: &[String], x: &sv_parser::NeedGetLocate) ->
}
}
fn get_first_last_locate(x: &sv_parser::NeedGetLocate) -> Option<(Locate, Locate)> {
fn get_first_last_locate(node: RefNode) -> Option<(Locate, Locate)> {
let mut first_locate = Locate { offset: 0, line: 0, len: 0 };
let mut last_locate = Locate { offset: 0, line: 0, len: 0 };
match x {
sv_parser::NeedGetLocate::GateInstantiation(gate) => {
for node in gate {
match unwrap_node!(node, InputTerminal, OutputTerminal) {
Some(RefNode::InputTerminal(x)) => {
if let Some(id) = unwrap_node!(x, Identifier) {
let locate = get_identifier(id).unwrap();
if locate != last_locate { last_locate = locate; }
if first_locate.offset == 0 { first_locate = locate; };
} else if let Some(RefNode::Expression(x)) = unwrap_node!(x, Expression) {
let exp = sv_parser::NeedParseExpression::Expression(x.clone());
if let Some(locate) = parse_expression_only_locate(&exp) {
if locate != last_locate { last_locate = locate; }
if first_locate.offset == 0 { first_locate = locate; };
}
}
}
Some(RefNode::OutputTerminal(x)) => {
if let Some(id) = unwrap_node!(x, Identifier) {
let locate = get_identifier(id).unwrap();
if locate != last_locate { last_locate = locate; }
if first_locate.offset == 0 { first_locate = locate; };
} else if let Some(RefNode::Expression(x)) = unwrap_node!(x, Expression) {
let exp = sv_parser::NeedParseExpression::Expression(x.clone());
if let Some(locate) = parse_expression_only_locate(&exp) {
if locate != last_locate { last_locate = locate; }
if first_locate.offset == 0 { first_locate = locate; };
}
}
}
_ => ()
}
}
}
_ => {
for node in x {
match unwrap_node!(node, SimpleIdentifier, Symbol) {
Some(RefNode::SimpleIdentifier(x)) => {
let locate = x.nodes.0;
if locate != last_locate { last_locate = locate; }
if first_locate.offset == 0 { first_locate = locate; };
}
Some(RefNode::Symbol(x)) => {
let locate = x.nodes.0;
if locate != last_locate { last_locate = locate; }
if first_locate.offset == 0 { first_locate = locate; };
}
_ => ()
}
}
}
}
if last_locate.offset == 0 {
None
} else {
Some((first_locate, last_locate))
}
}
fn parse_expression_only_locate(x: &sv_parser::NeedParseExpression) -> Option<Locate> {
let mut last_locate = Locate { offset: 0, line: 0, len: 0 };
for node in x {
// println!("parse expression::node {:#?}", node);
match unwrap_node!(node, SimpleIdentifier, Symbol, UnsignedNumber, HexNumber, OctalNumber, BinaryNumber) {
Some(RefNode::SimpleIdentifier(x)) => {
for n in node {
match n {
RefNode::Symbol(x) => {
let locate = x.nodes.0;
if locate != last_locate {
last_locate = locate;
}
}
Some(RefNode::Symbol(x)) => {
let locate = x.nodes.0;
if locate != last_locate {
last_locate = locate;
}
}
Some(RefNode::UnsignedNumber(x)) => {
let locate = x.nodes.0;
if locate != last_locate {
last_locate = locate;
}
}
Some(RefNode::HexNumber(x)) => {
let locate = x.nodes.1.nodes.0;
if locate != last_locate {
last_locate = locate;
}
}
Some(RefNode::OctalNumber(x)) => {
let locate = x.nodes.1.nodes.0;
if locate != last_locate {
last_locate = locate;
}
}
Some(RefNode::BinaryNumber(x)) => {
let locate = x.nodes.1.nodes.0;
if locate != last_locate {
last_locate = locate;
}
if locate != last_locate { last_locate = locate; }
if first_locate.offset == 0 { first_locate = locate; };
}
_ => ()
}
}
if last_locate.offset == 0 {
Some(last_locate)
} else {
None
} else {
Some((first_locate, last_locate))
}
}