add port assignment
This commit is contained in:
parent
82a21ccf34
commit
3303b65c3f
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
use tower_lsp::lsp_types::Position as LspPosition;
|
||||
use tower_lsp::lsp_types::Range as LspRange;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize)]
|
||||
pub struct Position {
|
||||
pub line: u32,
|
||||
pub character: u32
|
||||
@ -18,9 +18,13 @@ impl Position {
|
||||
pub fn to_lsp_position(&self) -> LspPosition {
|
||||
LspPosition { line: self.line, character: self.character }
|
||||
}
|
||||
|
||||
pub fn from_lsp_position(pos: &LspPosition) -> Position {
|
||||
Position { line: pos.line, character: pos.character }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize)]
|
||||
pub struct Range {
|
||||
pub start: Position,
|
||||
pub end: Position
|
||||
@ -140,13 +144,37 @@ pub struct Parameter {
|
||||
// pub range: Range
|
||||
// }
|
||||
|
||||
#[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)]
|
||||
pub enum AssignType {
|
||||
Named,
|
||||
Ordered
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)]
|
||||
pub struct InstPort {
|
||||
pub port: Option<String>,
|
||||
pub assign_name: String,
|
||||
pub assign_type: AssignType,
|
||||
pub range: Range
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, PartialEq, PartialOrd, Eq, Ord, Deserialize, Clone)]
|
||||
pub struct InstParameter {
|
||||
pub parameter: Option<String>,
|
||||
pub assign_name: String,
|
||||
pub assign_type: AssignType,
|
||||
pub range: Range
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Instance {
|
||||
pub name: String,
|
||||
#[serde(rename = "type")]
|
||||
pub inst_type: String,
|
||||
pub instparams: Option<Range>,
|
||||
pub intstparams_assignment: Vec<InstParameter>,
|
||||
pub instports: Option<Range>,
|
||||
pub intstport_assignment: Vec<InstPort>,
|
||||
pub range: Range
|
||||
}
|
||||
|
||||
@ -327,7 +355,7 @@ impl FastHdlparam {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_instance(&mut self, name: &str, inst_type: &str, line: u32, character: u32, end_character: u32,
|
||||
pub fn add_instance(&mut self, name: &str, inst_type: &str, port_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() {
|
||||
@ -348,6 +376,7 @@ impl FastHdlparam {
|
||||
}
|
||||
)
|
||||
},
|
||||
intstparams_assignment: Vec::new(),
|
||||
instports: if port_start_line == 0 {
|
||||
None
|
||||
} else {
|
||||
@ -362,6 +391,7 @@ impl FastHdlparam {
|
||||
}
|
||||
)
|
||||
},
|
||||
intstport_assignment: port_assign,
|
||||
range: Range {
|
||||
start: Position {
|
||||
line, character
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::collections::HashSet;
|
||||
use std::fs::{self, File};
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
@ -9,10 +8,11 @@ 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 crate::core::hdlparam::{AssignType, Position, Range};
|
||||
use crate::sources::{recovery_sv_parse_with_retry, LSPSupport};
|
||||
use crate::utils::to_escape_path;
|
||||
|
||||
use super::hdlparam::{FastHdlparam, Macro};
|
||||
use super::hdlparam::{self, FastHdlparam, InstPort, Macro};
|
||||
|
||||
macro_rules! advance_until_leave {
|
||||
($tokens:ident, $tree:ident, $event_iter:ident, $node:path) => {{
|
||||
@ -318,9 +318,10 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re
|
||||
_ => (0, 0, 0, 0)
|
||||
};
|
||||
|
||||
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, line, character, end_character,
|
||||
hdlparam.add_instance(name, inst_type, 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
|
||||
);
|
||||
@ -341,10 +342,10 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re
|
||||
let end_character = character + id.len as u32;
|
||||
|
||||
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_node);
|
||||
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, line, character, end_character,
|
||||
hdlparam.add_instance(name, inst_type, 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
|
||||
);
|
||||
@ -396,13 +397,10 @@ fn get_first_last_locate(node: RefNode) -> Option<(Locate, Locate)> {
|
||||
let mut last_locate = Locate { offset: 0, line: 0, len: 0 };
|
||||
|
||||
for n in node {
|
||||
match n {
|
||||
RefNode::Symbol(x) => {
|
||||
let locate = x.nodes.0;
|
||||
if locate != last_locate { last_locate = locate; }
|
||||
if first_locate.offset == 0 { first_locate = locate; };
|
||||
}
|
||||
_ => ()
|
||||
if let RefNode::Symbol(x) = n {
|
||||
let locate = x.nodes.0;
|
||||
if locate != last_locate { last_locate = locate; }
|
||||
if first_locate.offset == 0 { first_locate = locate; };
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,6 +411,120 @@ fn get_first_last_locate(node: RefNode) -> Option<(Locate, Locate)> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_instance_ports(syntax_tree: &SyntaxTree, doc: &Rope, node: RefNode) -> Vec<InstPort> {
|
||||
let mut ports = Vec::new();
|
||||
for list in node {
|
||||
match unwrap_node!(list, ListOfPortConnectionsNamed, ListOfPortConnectionsOrdered, InputTerminal, OutputTerminal) {
|
||||
Some(RefNode::ListOfPortConnectionsNamed(x)) => {
|
||||
for connect in x {
|
||||
if let RefNode::NamedPortConnectionIdentifier(ident) = connect {
|
||||
let (start_line, start_character, end_line, end_character) = get_pp_range(doc, connect);
|
||||
let port_name_locate = get_identifier(RefNode::PortIdentifier(&(ident.nodes.2)));
|
||||
let port_name = syntax_tree.get_str(&port_name_locate).unwrap();
|
||||
let name = if ident.nodes.3.is_some() {
|
||||
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
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let port = InstPort {
|
||||
port: Some(port_name.to_string()),
|
||||
assign_name: name,
|
||||
assign_type: AssignType::Named,
|
||||
range: Range {
|
||||
start: Position { line: start_line, character: start_character },
|
||||
end: Position { line: end_line, character: end_character }
|
||||
}
|
||||
};
|
||||
ports.push(port);
|
||||
};
|
||||
}
|
||||
}
|
||||
Some(RefNode::ListOfPortConnectionsOrdered(x)) => {
|
||||
for connect in x {
|
||||
if let RefNode::OrderedPortConnection(ident) = connect {
|
||||
if let Some(expr) = ident.nodes.1.clone() {
|
||||
let start_locate = get_identifier(RefNode::Expression(&expr));
|
||||
let expr = sv_parser::NeedParseExpression::Expression(expr);
|
||||
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 port = InstPort {
|
||||
port: None,
|
||||
assign_name: 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
|
||||
})
|
||||
}
|
||||
};
|
||||
ports.push(port);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Some(RefNode::InputTerminal(x)) => {
|
||||
let expr = x.nodes.0.clone();
|
||||
let start_locate = get_identifier(RefNode::Expression(&expr));
|
||||
let expr = sv_parser::NeedParseExpression::Expression(expr);
|
||||
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 port = InstPort {
|
||||
port: None,
|
||||
assign_name: 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
|
||||
})
|
||||
}
|
||||
};
|
||||
ports.push(port);
|
||||
}
|
||||
Some(RefNode::OutputTerminal(x)) => {
|
||||
let expr = x.nodes.0.clone();
|
||||
let start_locate = get_identifier(RefNode::NetLvalue(&expr));
|
||||
let expr = sv_parser::NeedParseExpression::NetValue(expr);
|
||||
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 port = InstPort {
|
||||
port: None,
|
||||
assign_name: 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
|
||||
})
|
||||
}
|
||||
};
|
||||
ports.push(port);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
ports.sort_by_key(|p| p.range.clone());
|
||||
ports.dedup_by_key(|p| p.range.clone());
|
||||
ports
|
||||
}
|
||||
|
||||
fn parse_expression(syntax_tree: &SyntaxTree, x: &sv_parser::NeedParseExpression) -> (String, Option<Locate>) {
|
||||
let mut last_locate = Locate { offset: 0, line: 0, len: 0 };
|
||||
let mut expression = String::new();
|
||||
@ -507,6 +619,12 @@ fn get_identifier(node: RefNode) -> Option<Locate> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_position(doc: &Rope, locate: Locate) -> Position {
|
||||
let byte = locate.offset;
|
||||
let pos = doc.byte_to_pos(byte);
|
||||
hdlparam::Position::from_lsp_position(&pos)
|
||||
}
|
||||
|
||||
fn get_includes(path: &PathBuf) -> Vec<crate::core::hdlparam::Include> {
|
||||
let mut includes = Vec::new();
|
||||
|
||||
|
@ -206,6 +206,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
|
||||
inst_type: get_value(&tokens[i+1]),
|
||||
instports: None,
|
||||
instparams: None,
|
||||
intstport_assignment: Vec::new(),
|
||||
intstparams_assignment: Vec::new(),
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: tokens[i-1].pos.range.start.line + 1,
|
||||
@ -226,6 +228,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
|
||||
inst_type: get_value(&tokens[i+2]),
|
||||
instports: None,
|
||||
instparams: None,
|
||||
intstport_assignment: Vec::new(),
|
||||
intstparams_assignment: Vec::new(),
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: tokens[i-1].pos.range.start.line + 1,
|
||||
@ -257,6 +261,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
|
||||
inst_type,
|
||||
instports: None,
|
||||
instparams: None,
|
||||
intstport_assignment: Vec::new(),
|
||||
intstparams_assignment: Vec::new(),
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: tokens[i-1].pos.range.start.line + 1,
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 21f3e497e88a108d15be75ea7e2f0f1a409c6e1d
|
||||
Subproject commit b6ae8b8a1ff22609e2a837b12dd798226f299f71
|
Loading…
x
Reference in New Issue
Block a user