修复部分bug

This commit is contained in:
锦恢 2024-09-27 21:18:09 +08:00
parent 5d8eb18042
commit 2298e7d252
11 changed files with 100 additions and 48 deletions

View File

@ -1,15 +1,14 @@
use std::fs::{self, File};
use std::io::BufRead;
use std::{collections::HashMap, io::BufReader};
use std::io::BufReader;
use std::path::PathBuf;
use anyhow::Error;
use percent_encoding::percent_decode_str;
use ropey::Rope;
use tower_lsp::lsp_types::Url;
use std::env::consts::OS;
use sv_parser::{parse_sv, unwrap_node, Locate, RefNode, SyntaxTree};
use sv_parser::{unwrap_node, Locate, RefNode, SyntaxTree};
use crate::sources::recovery_sv_parse;
use crate::utils::to_escape_path;
use super::fast_hdlparam::{FastHdlparam, Macro};
@ -40,19 +39,7 @@ pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Result<FastHdlparam, Error> {
// 对不同操作系统文件路径的支持
let decoded_path = percent_decode_str(path.to_str().unwrap()).decode_utf8_lossy();
let decoded_path_str = decoded_path.as_ref();
let path = match OS {
"windows" => {
// 去掉开头的斜杠
let trimmed_path_str = decoded_path_str.trim_start_matches('/');
PathBuf::from(trimmed_path_str)
},
_ => {
// 其他操作系统(如 Linux保持原样
PathBuf::from(decoded_path_str)
},
};
let path = to_escape_path(path);
let mut hdlparam = FastHdlparam {
fast_macro: Macro {

View File

@ -70,7 +70,6 @@ impl <'a>tower_lsp::jsonrpc::Method<&'a Arc<Backend>, (DoFastApiRequestParams, )
let request_param = _params.0;
let path = request_param.path;
let fut = future::ready(do_fast(path));
info!("get future: {:?}", fut);
fut
}
}
@ -109,8 +108,6 @@ pub fn do_fast(path: String) -> Result<FastHdlparam> {
// fast 解析不需要 include
let includes: Vec<PathBuf> = Vec::new();
info!("before parse {}", path);
let parse_result = recovery_sv_parse(
&text,
@ -121,7 +118,6 @@ pub fn do_fast(path: String) -> Result<FastHdlparam> {
if let Some(syntax_tree) = parse_result {
if let Ok(hdlparam) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) {
info!("after parse {}, get hdlparam", path);
return Ok(hdlparam);
}
}

View File

@ -790,16 +790,6 @@ impl GenericScope {
scopes: Vec::new(),
}
}
#[cfg(test)]
pub fn contains_scope(&self, scope_ident: &str) -> bool {
for scope in &self.scopes {
if scope.starts_with(scope_ident) {
return true;
}
}
false
}
}
impl Definition for GenericScope {

View File

@ -6,7 +6,11 @@ use tower_lsp::lsp_types::*;
pub fn get_ident(tree: &SyntaxTree, node: RefNode) -> (String, usize) {
let loc = unwrap_locate!(node).unwrap();
let ident_str = tree.get_str(loc).unwrap().to_string();
let byte_idx = tree.get_origin(loc).unwrap().1;
let byte_idx = match tree.get_origin(loc) {
Some(origin) => origin.1,
None => 0
};
(ident_str, byte_idx)
}

View File

@ -1,7 +1,10 @@
use std::{path::PathBuf, str::FromStr};
use log::info;
use ropey::RopeSlice;
use tower_lsp::lsp_types::{GotoDefinitionResponse, LocationLink, Position, Range, Url};
use crate::utils::resolve_path;
use crate::utils::{resolve_path, to_escape_path};
/// 跳转到定义
pub fn goto_include_definition(uri: &Url, line: &RopeSlice, pos: Position) -> Option<GotoDefinitionResponse> {
@ -23,7 +26,21 @@ pub fn goto_include_definition(uri: &Url, line: &RopeSlice, pos: Position) -> Op
path_string = &path_string[2 ..];
}
if let Some(abs_path) = resolve_path(uri.path(), path_string) {
// 路径转换
let path = match PathBuf::from_str(uri.path()) {
Ok(path) => path,
Err(error) => {
info!("error happen in <goto_include_definition>: {:?}", error);
return None;
}
};
let escape_path = to_escape_path(&path);
let escape_path = escape_path.to_str().unwrap_or("");
if escape_path.len() == 0 {
return None;
}
if let Some(abs_path) = resolve_path(escape_path, path_string) {
let target_uri = match Url::from_file_path(abs_path.as_path()) {
Ok(uri) => uri,
Err(_) => return None

View File

@ -2,6 +2,7 @@ use crate::{definition::extract_defs::get_ident, utils::get_definition_token};
use crate::server::LSPServer;
use crate::sources::LSPSupport;
#[allow(unused)]
use log::info;
use sv_parser::*;
use tower_lsp::lsp_types::*;
@ -97,6 +98,7 @@ fn all_identifiers(syntax_tree: &SyntaxTree, token: &str) -> Vec<(String, usize)
let mut idents: Vec<(String, usize)> = Vec::new();
for node in syntax_tree {
if let RefNode::Identifier(_) = node {
let (ident, byte_idx) = get_ident(syntax_tree, node);
if ident == token {
idents.push((ident, byte_idx));

View File

@ -1,7 +1,6 @@
use log::info;
use regex::Regex;
use ropey::RopeSlice;
use tower_lsp::lsp_types::{Hover, HoverContents, LanguageString, MarkedString, MarkupContent, Position};
use tower_lsp::lsp_types::{Hover, HoverContents, LanguageString, MarkedString, Position};
use super::get_word_range_at_position;

View File

@ -1,9 +1,11 @@
use std::{fmt::format, sync::RwLockReadGuard};
use std::{path::PathBuf, str::FromStr, sync::RwLockReadGuard};
use crate::definition::*;
use crate::server::LSPServer;
use crate::sources::LSPSupport;
use crate::utils::*;
use log::info;
use regex::Regex;
use ropey::{Rope, RopeSlice};
use tower_lsp::lsp_types::*;
@ -60,10 +62,11 @@ fn get_hover(doc: &Rope, line: usize) -> String {
let mut multiline: bool = false;
let mut valid: bool = true;
let mut current: String = doc.line(line).to_string();
let ltrim: String = " ".repeat(current.len() - current.trim_start().len());
let mut line_idx = line;
// iterate upwards from the definition, and grab the comments
// 寻找周围的注释
while valid {
hover.push(current.clone());
line_idx -= 1;
@ -86,18 +89,31 @@ fn get_hover(doc: &Rope, line: usize) -> String {
}
}
hover.reverse();
info!("hover array: {:?}", hover);
let multi_space_regex = Regex::new(r"\s+").unwrap();
let line_handler = |line: &str| -> String {
let line = multi_space_regex.replace_all(line.trim(), " ");
let line = line.into_owned();
return format!("{}\n", line);
};
let mut result: Vec<String> = Vec::new();
for i in hover {
if let Some(stripped) = i.strip_prefix(&ltrim) {
result.push(stripped.to_owned());
for line in hover {
if let Some(stripped) = line.strip_prefix(&ltrim) {
let line_hover = line_handler(stripped);
result.push(line_hover);
} else {
result.push(i);
let line_hover = line_handler(&line);
result.push(line_hover);
}
}
result.join("").trim_end().to_owned()
}
fn match_include(uri: &Url, line: &RopeSlice, pos: Position, language_id: &String) -> Option<Hover> {
let line_text = line.as_str().unwrap_or("");
if line_text.trim().starts_with("`include") {
@ -116,8 +132,22 @@ fn match_include(uri: &Url, line: &RopeSlice, pos: Position, language_id: &Strin
if path_string.starts_with("./") || path_string.starts_with(".\\") {
path_string = &path_string[2 ..];
}
// 路径转换
let path = match PathBuf::from_str(uri.path()) {
Ok(path) => path,
Err(error) => {
info!("error happen in <goto_include_definition>: {:?}", error);
return None;
}
};
let escape_path = to_escape_path(&path);
let escape_path = escape_path.to_str().unwrap_or("");
if escape_path.len() == 0 {
return None;
}
if let Some(abs_path) = resolve_path(uri.path(), path_string) {
if let Some(abs_path) = resolve_path(escape_path, path_string) {
let content = format!("{:?}", abs_path);
let language_string = LanguageString {
language: language_id.to_string(),

View File

@ -15,7 +15,6 @@ use std::fs;
use std::ops::Deref;
use std::ops::Range as StdRange;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Arc, Condvar, Mutex, RwLock};
use std::thread;
use sv_parser::*;

View File

@ -129,10 +129,9 @@ mod test_fast {
#[cfg(test)]
mod test_svparse {
use std::{collections::HashMap, fs, path::{Path, PathBuf}};
use std::{fs, path::{Path, PathBuf}};
use ropey::Rope;
use sv_parser::parse_sv_str;
use tower_lsp::lsp_types::{Position, Range, Url};
use crate::sources::recovery_sv_parse;

View File

@ -1,5 +1,6 @@
use std::path::{Path, PathBuf};
use std::{env::consts::OS, path::{Path, PathBuf}};
use percent_encoding::percent_decode_str;
use regex::Regex;
use ropey::RopeSlice;
use tower_lsp::lsp_types::*;
@ -90,14 +91,20 @@ pub fn get_language_id_by_uri(uri: &Url) -> String {
}
/// 根据基础路径和给出的 path 路径,计算出绝对路径
///
/// 如果 path 是绝对路径直接返回
/// 会进行存在性检查,不存在的路径直接返回 None
///
/// 例子:
///
/// resolve_path("/home/ubuntu/hello.v", "./control.v") -> Some("/home/ubuntu/control.v")
///
/// resolve_path("/home/ubuntu/hello.v", "/opt/control.v") -> Some("/opt/control.v")
///
pub fn resolve_path(base: &str, path_string: &str) -> Option<PathBuf> {
let path = Path::new(path_string);
let abs_path: PathBuf;
if path.is_absolute() {
abs_path = PathBuf::from(path);
} else {
@ -109,4 +116,26 @@ pub fn resolve_path(base: &str, path_string: &str) -> Option<PathBuf> {
return Some(path);
}
None
}
}
/// 把 uri 路径转换成合法的操作系统文件路径
///
/// windows 中
///
/// /c%3A/Users/MyCpu.v 转换成 c:/Users/MyCpu.v
pub fn to_escape_path(path: &PathBuf) -> PathBuf {
let decoded_path = percent_decode_str(path.to_str().unwrap()).decode_utf8_lossy();
let decoded_path_str = decoded_path.as_ref();
match OS {
"windows" => {
// 去掉开头的斜杠
let trimmed_path_str = decoded_path_str.trim_start_matches('/');
PathBuf::from(trimmed_path_str)
},
_ => {
// 其他操作系统(如 Linux保持原样
PathBuf::from(decoded_path_str)
},
}
}