use proposed tower lsp

This commit is contained in:
锦恢 2024-10-31 15:35:17 +08:00
parent 9f50823429
commit 2dd7f98d5f
7 changed files with 104 additions and 33 deletions

View File

@ -11,7 +11,7 @@ dirs-next = "2.0"
bincode = "1.3" bincode = "1.3"
percent-encoding = "2.1.0" percent-encoding = "2.1.0"
log = "0.4.19" log = "0.4.19"
tower-lsp = "0.20.0" tower-lsp = { version = "0.20.0", features = ["proposed"]}
flexi_logger = "0.29.0" flexi_logger = "0.29.0"
ropey = "1.6.0" ropey = "1.6.0"
tokio = { version = "1.29.1", features = ["macros", "io-std", "rt-multi-thread"] } tokio = { version = "1.29.1", features = ["macros", "io-std", "rt-multi-thread"] }

View File

@ -170,9 +170,9 @@ pub struct Instance {
#[serde(rename = "type")] #[serde(rename = "type")]
pub inst_type: String, pub inst_type: String,
pub instparams: Option<Range>, pub instparams: Option<Range>,
pub intstparams_assignment: Vec<InstParameter>, pub intstparam_assignments: Vec<InstParameter>,
pub instports: Option<Range>, pub instports: Option<Range>,
pub intstport_assignment: Vec<InstPort>, pub intstport_assignments: Vec<InstPort>,
pub range: Range pub range: Range
} }
@ -334,9 +334,9 @@ impl FastHdlparam {
name: name.to_string(), name: name.to_string(),
inst_type: inst_type.to_string(), inst_type: inst_type.to_string(),
instparams: param_range, instparams: param_range,
intstparams_assignment: params_assign, intstparam_assignments: params_assign,
instports: port_range, instports: port_range,
intstport_assignment: ports_assign, intstport_assignments: ports_assign,
range range
}; };
last_module.instances.push(instance); last_module.instances.push(instance);

View File

@ -206,8 +206,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
inst_type: get_value(&tokens[i+1]), inst_type: get_value(&tokens[i+1]),
instports: None, instports: None,
instparams: None, instparams: None,
intstport_assignment: Vec::new(), intstport_assignments: Vec::new(),
intstparams_assignment: Vec::new(), intstparam_assignments: Vec::new(),
range: Range { range: Range {
start: Position { start: Position {
line: tokens[i-1].pos.range.start.line + 1, line: tokens[i-1].pos.range.start.line + 1,
@ -228,8 +228,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
inst_type: get_value(&tokens[i+2]), inst_type: get_value(&tokens[i+2]),
instports: None, instports: None,
instparams: None, instparams: None,
intstport_assignment: Vec::new(), intstport_assignments: Vec::new(),
intstparams_assignment: Vec::new(), intstparam_assignments: Vec::new(),
range: Range { range: Range {
start: Position { start: Position {
line: tokens[i-1].pos.range.start.line + 1, line: tokens[i-1].pos.range.start.line + 1,
@ -261,8 +261,8 @@ fn parse_tokens(tokens: Vec<Token>) -> Vec<Module> {
inst_type, inst_type,
instports: None, instports: None,
instparams: None, instparams: None,
intstport_assignment: Vec::new(), intstport_assignments: Vec::new(),
intstparams_assignment: Vec::new(), intstparam_assignments: Vec::new(),
range: Range { range: Range {
start: Position { start: Position {
line: tokens[i-1].pos.range.start.line + 1, line: tokens[i-1].pos.range.start.line + 1,

View File

@ -33,18 +33,18 @@ pub fn hover(server: &LSPServer, params: &HoverParams) -> Option<Hover> {
return Some(hover); return Some(hover);
} }
info!("enter hover_position_port_param"); // info!("enter hover_position_port_param");
// match positional port param // match positional port param
if let Some(hover) = hover_position_port_param(server, &line_text, doc, pos, &language_id) { if let Some(hover) = hover_position_port_param(server, &line_text, doc, pos, &language_id) {
return Some(hover); return Some(hover);
} }
info!("enter hover_module_declaration"); // info!("enter hover_module_declaration");
// match module name // match module name
if let Some(hover) = hover_module_declaration(server, &token, &language_id) { if let Some(hover) = hover_module_declaration(server, &token, &language_id) {
info!("[LSPServer] in hover: get module hover"); // info!("[LSPServer] in hover: get module hover");
if hover_for_module(server, pos, doc) { if hover_for_module(server, pos, doc) {
info!("[LSPServer] in hover: it is instance"); // info!("[LSPServer] in hover: it is instance");
return Some(hover); return Some(hover);
} }
} }

View File

@ -14,29 +14,97 @@ pub fn inlay_hint(server: &LSPServer, params: &InlayHintParams) -> Option<Vec<In
let path_string = path.to_str().unwrap(); let path_string = path.to_str().unwrap();
let visible_range = core::hdlparam::Range::from_lsp_range(&params.range); let visible_range = core::hdlparam::Range::from_lsp_range(&params.range);
info!("enter hints");
let fast_map = server.srcs.hdl_param.path_to_hdl_file.read().unwrap(); let fast_map = server.srcs.hdl_param.path_to_hdl_file.read().unwrap();
// 先找到 当前 所在的 hdlfile // 先找到 当前 所在的 hdlfile
if let Some(hdl_file) = &fast_map.get(path_string) { if let Some(hdl_file) = &fast_map.get(path_string) {
info!("enter some");
let fast = &hdl_file.fast; let fast = &hdl_file.fast;
let mut hints = Vec::<InlayHint>::new(); let mut hints = Vec::<InlayHint>::new();
// 制作例化模块的 hint // 制作例化模块的 hint
for module in &fast.content { for module in &fast.content {
for instance in &module.instances { for instance in &module.instances {
if let Some(instport_range) = &instance.instports {
// 根据在可见视图外面的 range 就不管了 // 根据在可见视图外面的 range 就不管了
if instport_range.before(&visible_range) || instport_range.after(&visible_range) { if is_visible_range(&instance.instparams, &visible_range) {
continue; hints.extend(make_instparam_hints(params, instance));
} }
if is_visible_range(&instance.instports, &visible_range) {
hints.extend(make_instport_hints(params, instance));
}
}
} }
} return Some(hints);
}
} }
None None
} }
fn make_instport_hint(params: &InlayHintParams) { fn is_visible_range(
target_range: &Option<core::hdlparam::Range>,
visible_range: &core::hdlparam::Range
) -> bool {
if let Some(target_range) = target_range {
if target_range.before(visible_range) || target_range.after(visible_range) {
return false;
}
return true;
}
false
}
fn make_instparam_hints(
params: &InlayHintParams,
instance: &core::hdlparam::Instance
) -> Vec<InlayHint> {
let mut hints = Vec::<InlayHint>::new();
hints
}
fn make_instport_hints(
params: &InlayHintParams,
instance: &core::hdlparam::Instance
) -> Vec<InlayHint> {
let mut hints = Vec::<InlayHint>::new();
for port_assigment in &instance.intstport_assignments {
let port_desc = MarkupContent {
kind: MarkupKind::Markdown,
value: format!("```verilog\n{:?}\n```", port_assigment.port)
};
let hint = InlayHint {
position: port_assigment.range.to_lsp_range().start,
label: InlayHintLabel::String("start".to_string()),
padding_left: Some(true),
padding_right: Some(true),
kind: Some(InlayHintKind::PARAMETER),
text_edits: None,
tooltip: Some(InlayHintTooltip::MarkupContent(port_desc)),
data: None
};
hints.push(hint);
let port_desc = MarkupContent {
kind: MarkupKind::Markdown,
value: format!("```verilog\n{:?}\n```", port_assigment.port)
};
let hint = InlayHint {
position: port_assigment.range.to_lsp_range().end,
label: InlayHintLabel::String("end".to_string()),
padding_left: Some(true),
padding_right: Some(true),
kind: Some(InlayHintKind::PARAMETER),
text_edits: None,
tooltip: Some(InlayHintTooltip::MarkupContent(port_desc)),
data: None
};
hints.push(hint);
}
hints
} }

View File

@ -34,7 +34,7 @@ async fn main() {
.start() .start()
.unwrap(); .unwrap();
info!("launch Digital LSP"); info!("launch Digital LSP, version: 0.4.0");
let stdin = tokio::io::stdin(); let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout(); let stdout = tokio::io::stdout();

View File

@ -4,7 +4,6 @@ use crate::completion::keyword::*;
use flexi_logger::LoggerHandle; use flexi_logger::LoggerHandle;
#[allow(unused)] #[allow(unused)]
use log::{debug, info, warn}; use log::{debug, info, warn};
use notification::DidDeleteFiles;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::string::ToString; use std::string::ToString;
use std::sync::{Mutex, RwLock}; use std::sync::{Mutex, RwLock};
@ -214,12 +213,13 @@ impl LanguageServer for Backend {
completion_provider: Some(completion_provider), completion_provider: Some(completion_provider),
definition_provider: Some(OneOf::Left(true)), definition_provider: Some(OneOf::Left(true)),
hover_provider: Some(HoverProviderCapability::Simple(true)), hover_provider: Some(HoverProviderCapability::Simple(true)),
// inlay_hint_provider: Some(OneOf::Left(true)),
document_symbol_provider: Some(OneOf::Left(true)), document_symbol_provider: Some(OneOf::Left(true)),
document_highlight_provider: Some(OneOf::Left(true)), document_highlight_provider: Some(OneOf::Left(true)),
..ServerCapabilities::default() ..ServerCapabilities::default()
}; };
Ok(InitializeResult { server_info, capabilities }) Ok(InitializeResult::default())
} }
async fn initialized(&self, _: InitializedParams) { async fn initialized(&self, _: InitializedParams) {
@ -280,13 +280,6 @@ impl LanguageServer for Backend {
Ok(self.server.hover(params)) Ok(self.server.hover(params))
} }
async fn document_symbol(
&self,
params: DocumentSymbolParams,
) -> Result<Option<DocumentSymbolResponse>> {
Ok(self.server.document_symbol(params))
}
async fn formatting(&self, params: DocumentFormattingParams) -> Result<Option<Vec<TextEdit>>> { async fn formatting(&self, params: DocumentFormattingParams) -> Result<Option<Vec<TextEdit>>> {
Ok(self.server.formatting(params)) Ok(self.server.formatting(params))
} }
@ -298,10 +291,19 @@ impl LanguageServer for Backend {
Ok(self.server.range_formatting(params)) Ok(self.server.range_formatting(params))
} }
async fn document_symbol(
&self,
params: DocumentSymbolParams,
) -> Result<Option<DocumentSymbolResponse>> {
info!("enter document");
Ok(self.server.document_symbol(params))
}
async fn document_highlight( async fn document_highlight(
&self, &self,
params: DocumentHighlightParams, params: DocumentHighlightParams,
) -> Result<Option<Vec<DocumentHighlight>>> { ) -> Result<Option<Vec<DocumentHighlight>>> {
info!("enter highlight");
Ok(self.server.document_highlight(params)) Ok(self.server.document_highlight(params))
} }
@ -309,6 +311,7 @@ impl LanguageServer for Backend {
&self, &self,
params: InlayHintParams params: InlayHintParams
) -> Result<Option<Vec<InlayHint>>> { ) -> Result<Option<Vec<InlayHint>>> {
info!("enter inlay_hint");
Ok(self.server.inlay_hint(params)) Ok(self.server.inlay_hint(params))
} }
} }