问题:add 所有权
This commit is contained in:
parent
ce5e1c73bd
commit
8ee9a361f7
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -206,6 +206,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"flexi_logger",
|
"flexi_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"once_cell",
|
||||||
"path-clean",
|
"path-clean",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -6,6 +6,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"}
|
sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"}
|
||||||
|
once_cell = "1.8"
|
||||||
log = "0.4.19"
|
log = "0.4.19"
|
||||||
tower-lsp = "0.20.0"
|
tower-lsp = "0.20.0"
|
||||||
flexi_logger = "0.29.0"
|
flexi_logger = "0.29.0"
|
||||||
|
@ -239,7 +239,7 @@ endmodule
|
|||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
server.did_open(open_params);
|
server.did_open(open_params, None);
|
||||||
let fid = server.srcs.get_id(&uri);
|
let fid = server.srcs.get_id(&uri);
|
||||||
server.srcs.wait_parse_ready(fid, true);
|
server.srcs.wait_parse_ready(fid, true);
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ endmodule
|
|||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
server.did_open(open_params);
|
server.did_open(open_params, None);
|
||||||
let fid = server.srcs.get_id(&uri);
|
let fid = server.srcs.get_id(&uri);
|
||||||
server.srcs.wait_parse_ready(fid, true);
|
server.srcs.wait_parse_ready(fid, true);
|
||||||
|
|
||||||
@ -477,7 +477,7 @@ endmodule
|
|||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
server.did_open(open_params);
|
server.did_open(open_params, None);
|
||||||
let fid = server.srcs.get_id(&uri);
|
let fid = server.srcs.get_id(&uri);
|
||||||
server.srcs.wait_parse_ready(fid, true);
|
server.srcs.wait_parse_ready(fid, true);
|
||||||
let file = server.srcs.get_file(fid).unwrap();
|
let file = server.srcs.get_file(fid).unwrap();
|
||||||
@ -566,7 +566,7 @@ endmodule
|
|||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
server.did_open(open_params);
|
server.did_open(open_params, None);
|
||||||
let fid = server.srcs.get_id(&uri);
|
let fid = server.srcs.get_id(&uri);
|
||||||
server.srcs.wait_parse_ready(fid, true);
|
server.srcs.wait_parse_ready(fid, true);
|
||||||
let file = server.srcs.get_file(fid).unwrap();
|
let file = server.srcs.get_file(fid).unwrap();
|
||||||
@ -738,8 +738,8 @@ endinterface"#;
|
|||||||
text: text2.to_owned(),
|
text: text2.to_owned(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
server.did_open(open_params);
|
server.did_open(open_params, None);
|
||||||
server.did_open(open_params2);
|
server.did_open(open_params2, None);
|
||||||
let fid = server.srcs.get_id(&uri);
|
let fid = server.srcs.get_id(&uri);
|
||||||
let fid2 = server.srcs.get_id(&uri2);
|
let fid2 = server.srcs.get_id(&uri2);
|
||||||
server.srcs.wait_parse_ready(fid, true);
|
server.srcs.wait_parse_ready(fid, true);
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub line: u32,
|
pub line: u32,
|
||||||
pub character: u32
|
pub character: u32
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
pub start: Position,
|
pub start: Position,
|
||||||
pub end: Position
|
pub end: Position
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, PartialEq)]
|
#[derive(Debug, Serialize, PartialEq, Deserialize)]
|
||||||
pub struct Port {
|
pub struct Port {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
pub dir_type: String,
|
pub dir_type: String,
|
||||||
pub net_type: String,
|
pub net_type: String,
|
||||||
pub width: String,
|
pub width: String,
|
||||||
@ -22,7 +23,7 @@ pub struct Port {
|
|||||||
pub range: Range
|
pub range: Range
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, PartialEq)]
|
#[derive(Debug, Serialize, PartialEq, Deserialize)]
|
||||||
pub struct Parameter {
|
pub struct Parameter {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub net_type: String,
|
pub net_type: String,
|
||||||
@ -43,16 +44,17 @@ pub struct Parameter {
|
|||||||
// pub range: Range
|
// pub range: Range
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
pub inst_type: String,
|
pub inst_type: String,
|
||||||
pub instparams: Option<Range>,
|
pub instparams: Option<Range>,
|
||||||
pub instports: Option<Range>,
|
pub instports: Option<Range>,
|
||||||
pub range: Range
|
pub range: Range
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Module {
|
pub struct Module {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub params: Vec<Parameter>,
|
pub params: Vec<Parameter>,
|
||||||
@ -61,13 +63,13 @@ pub struct Module {
|
|||||||
pub range: Range
|
pub range: Range
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct DefineParam {
|
pub struct DefineParam {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub value: String
|
pub value: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Define {
|
pub struct Define {
|
||||||
name: String,
|
name: String,
|
||||||
replacement: String,
|
replacement: String,
|
||||||
@ -75,13 +77,13 @@ pub struct Define {
|
|||||||
params: Vec<DefineParam>
|
params: Vec<DefineParam>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Include {
|
pub struct Include {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
pub range: Range
|
pub range: Range
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
severity: String,
|
severity: String,
|
||||||
message: String,
|
message: String,
|
||||||
@ -91,7 +93,7 @@ pub struct Error {
|
|||||||
running_phase: Option<String>,
|
running_phase: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Macro {
|
pub struct Macro {
|
||||||
pub defines: Vec<Define>,
|
pub defines: Vec<Define>,
|
||||||
pub includes: Vec<Include>,
|
pub includes: Vec<Include>,
|
||||||
@ -99,9 +101,10 @@ pub struct Macro {
|
|||||||
pub invalid: Vec<Range>
|
pub invalid: Vec<Range>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct FastHdlparam {
|
pub struct FastHdlparam {
|
||||||
|
#[serde(rename = "macro")]
|
||||||
pub fast_macro: Macro,
|
pub fast_macro: Macro,
|
||||||
pub content: Vec<Module>
|
pub content: Vec<Module>
|
||||||
}
|
}
|
||||||
@ -227,61 +230,62 @@ impl FastHdlparam {
|
|||||||
last_module.instances.push(instance);
|
last_module.instances.push(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_fast(&self) {
|
// pub fn print_fast(&self) {
|
||||||
if self.content.is_empty() {
|
// if self.content.is_empty() {
|
||||||
println!("none module");
|
// println!("none module");
|
||||||
} else {
|
// } else {
|
||||||
for module in &self.content {
|
// for module in &self.content {
|
||||||
println!("module {}", module.name);
|
// println!("module {}", module.name);
|
||||||
if !module.params.is_empty() {
|
// if !module.params.is_empty() {
|
||||||
println!(" params:");
|
// println!(" params:");
|
||||||
for param in &module.params {
|
// for param in &module.params {
|
||||||
println!(" parameter {} {} {}", param.net_type, param.name, param.init);
|
// println!(" parameter {} {} {}", param.net_type, param.name, param.init);
|
||||||
println!(" range start {} {}", param.range.start.line, param.range.start.character);
|
// println!(" range start {} {}", param.range.start.line, param.range.start.character);
|
||||||
println!(" range end {} {}", param.range.end.line, param.range.end.character);
|
// println!(" range end {} {}", param.range.end.line, param.range.end.character);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if !module.ports.is_empty() {
|
// if !module.ports.is_empty() {
|
||||||
println!(" ports:");
|
// println!(" ports:");
|
||||||
for port in &module.ports {
|
// for port in &module.ports {
|
||||||
if port.width == "1" {
|
// if port.width == "1" {
|
||||||
println!(" {} {} {}", port.dir_type, port.net_type, port.name);
|
// println!(" {} {} {}", port.dir_type, port.net_type, port.name);
|
||||||
} else {
|
// } else {
|
||||||
println!(" {} {} {} {}", port.dir_type, port.net_type, port.width, port.name);
|
// println!(" {} {} {} {}", port.dir_type, port.net_type, port.width, port.name);
|
||||||
}
|
// }
|
||||||
println!(" range start {} {}", port.range.start.line, port.range.start.character);
|
// println!(" range start {} {}", port.range.start.line, port.range.start.character);
|
||||||
println!(" range end {} {}", port.range.end.line, port.range.end.character);
|
// println!(" range end {} {}", port.range.end.line, port.range.end.character);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if !module.instances.is_empty() {
|
// if !module.instances.is_empty() {
|
||||||
println!(" instances:");
|
// println!(" instances:");
|
||||||
for instance in &module.instances {
|
// for instance in &module.instances {
|
||||||
println!(" {} {}", instance.inst_type, instance.name);
|
// println!(" {} {}", instance.inst_type, instance.name);
|
||||||
if instance.instparams.is_none() {
|
// if instance.instparams.is_none() {
|
||||||
println!(" params: {:?}", instance.instparams);
|
// println!(" params: {:?}", instance.instparams);
|
||||||
} else {
|
// } else {
|
||||||
println!(" params:");
|
// println!(" params:");
|
||||||
println!(" range start {} {}", instance.instparams.clone().unwrap().start.line,
|
// println!(" range start {} {}", instance.instparams.clone().unwrap().start.line,
|
||||||
instance.instparams.clone().unwrap().start.character);
|
// instance.instparams.clone().unwrap().start.character);
|
||||||
println!(" range end {} {}", instance.instparams.clone().unwrap().end.line,
|
// println!(" range end {} {}", instance.instparams.clone().unwrap().end.line,
|
||||||
instance.instparams.clone().unwrap().end.character);
|
// instance.instparams.clone().unwrap().end.character);
|
||||||
}
|
// }
|
||||||
if instance.instports.is_none() {
|
// if instance.instports.is_none() {
|
||||||
println!(" ports: {:?}", instance.instports);
|
// println!(" ports: {:?}", instance.instports);
|
||||||
} else {
|
// } else {
|
||||||
println!(" ports:");
|
// println!(" ports:");
|
||||||
println!(" range start {} {}", instance.instports.clone().unwrap().start.line,
|
// println!(" range start {} {}", instance.instports.clone().unwrap().start.line,
|
||||||
instance.instports.clone().unwrap().start.character);
|
// instance.instports.clone().unwrap().start.character);
|
||||||
println!(" range end {} {}", instance.instports.clone().unwrap().end.line,
|
// println!(" range end {} {}", instance.instports.clone().unwrap().end.line,
|
||||||
instance.instports.clone().unwrap().end.character);
|
// instance.instports.clone().unwrap().end.character);
|
||||||
}
|
// }
|
||||||
println!(" range start {} {}", instance.range.start.line, instance.range.start.character);
|
// println!(" range start {} {}", instance.range.start.line, instance.range.start.character);
|
||||||
println!(" range end {} {}", instance.range.end.line, instance.range.end.character);
|
// println!(" range end {} {}", instance.range.end.line, instance.range.end.character);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
println!(" range start {} {}", module.range.start.line, module.range.start.character);
|
// println!(" range start {} {}", module.range.start.line, module.range.start.character);
|
||||||
println!(" range end {} {}", module.range.end.line, module.range.end.character);
|
// println!(" range end {} {}", module.range.end.line, module.range.end.character);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,14 @@ pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
|
|||||||
|
|
||||||
let result = parse_sv(&path, &defines, &includes, false, true);
|
let result = parse_sv(&path, &defines, &includes, false, true);
|
||||||
if let Ok((syntax_tree, _)) = result {
|
if let Ok((syntax_tree, _)) = result {
|
||||||
let hdlparam = make_fast_from_syntaxtree(syntax_tree, path);
|
let hdlparam = make_fast_from_syntaxtree(&syntax_tree, &path);
|
||||||
return Some(hdlparam);
|
return Some(hdlparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree, path: PathBuf) -> FastHdlparam {
|
pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> FastHdlparam {
|
||||||
let mut hdlparam = FastHdlparam {
|
let mut hdlparam = FastHdlparam {
|
||||||
fast_macro: Macro {
|
fast_macro: Macro {
|
||||||
defines: Vec::new(),
|
defines: Vec::new(),
|
||||||
@ -39,7 +39,7 @@ pub fn make_fast_from_syntaxtree(syntax_tree: SyntaxTree, path: PathBuf) -> Fast
|
|||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
// &SyntaxTree is iterable
|
// &SyntaxTree is iterable
|
||||||
for node in &syntax_tree {
|
for node in syntax_tree {
|
||||||
match node {
|
match node {
|
||||||
RefNode::TextMacroDefinition(x) => {
|
RefNode::TextMacroDefinition(x) => {
|
||||||
let start = unwrap_node!(x, TextMacroDefinition).unwrap();
|
let start = unwrap_node!(x, TextMacroDefinition).unwrap();
|
||||||
@ -533,7 +533,7 @@ fn get_identifier(node: RefNode) -> Option<Locate> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_includes(path: PathBuf) -> Vec<crate::core::fast_hdlparam::Include> {
|
fn get_includes(path: &PathBuf) -> Vec<crate::core::fast_hdlparam::Include> {
|
||||||
let mut includes = Vec::new();
|
let mut includes = Vec::new();
|
||||||
|
|
||||||
let file = File::open(path).unwrap();
|
let file = File::open(path).unwrap();
|
||||||
|
@ -3,6 +3,7 @@ use std::path::PathBuf;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use notification::Notification;
|
||||||
use ropey::Rope;
|
use ropey::Rope;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tower_lsp::jsonrpc::Result;
|
use tower_lsp::jsonrpc::Result;
|
||||||
@ -113,7 +114,7 @@ pub fn do_fast(path: String) -> Result<FastHdlparam> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(syntax_tree) = parse_result {
|
if let Some(syntax_tree) = parse_result {
|
||||||
let hdlparam = make_fast_from_syntaxtree(syntax_tree, path_buf);
|
let hdlparam = make_fast_from_syntaxtree(&syntax_tree, &path_buf);
|
||||||
return Ok(hdlparam);
|
return Ok(hdlparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,3 +126,22 @@ pub fn do_fast(path: String) -> Result<FastHdlparam> {
|
|||||||
|
|
||||||
Err(api_error)
|
Err(api_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 下面是服务端发送给客户端的
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct UpdateFastNotification {
|
||||||
|
pub fast: FastHdlparam
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Notification for UpdateFastNotification {
|
||||||
|
const METHOD: &'static str = "update/fast";
|
||||||
|
type Params = Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_fast_to_client(backend: Arc<Option<&Backend>>, fast: FastHdlparam) {
|
||||||
|
let backend = backend.unwrap();
|
||||||
|
let params = UpdateFastNotification { fast };
|
||||||
|
backend.client.send_notification::<UpdateFastNotification>(params);
|
||||||
|
}
|
@ -1,5 +1,3 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use crate::definition::extract_defs::get_ident;
|
use crate::definition::extract_defs::get_ident;
|
||||||
use crate::server::LSPServer;
|
use crate::server::LSPServer;
|
||||||
use crate::sources::LSPSupport;
|
use crate::sources::LSPSupport;
|
||||||
@ -164,20 +162,6 @@ pub fn get_language_id_by_uri(uri: &Url) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_language_id_by_path(path: &PathBuf) -> String {
|
|
||||||
let path = path.as_path();
|
|
||||||
let ext_name = std::path::Path::new(path)
|
|
||||||
.extension()
|
|
||||||
.and_then(std::ffi::OsStr::to_str)
|
|
||||||
.unwrap_or("");
|
|
||||||
|
|
||||||
match ext_name {
|
|
||||||
"vhd" | "vhdl" | "vho" | "vht" => "vhdl".to_string(),
|
|
||||||
"v" | "V" | "vh" | "vl" => "verilog".to_string(),
|
|
||||||
"sv" | "svh" => "systemverilog".to_string(),
|
|
||||||
_ => "plaintext".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ScopesAndDefs = Option<(Vec<Box<dyn Scope>>, Vec<Box<dyn Definition>>)>;
|
type ScopesAndDefs = Option<(Vec<Box<dyn Scope>>, Vec<Box<dyn Definition>>)>;
|
||||||
|
|
||||||
|
@ -885,7 +885,6 @@ pub struct ClassDec {
|
|||||||
pub extends: (Vec<String>, Option<String>),
|
pub extends: (Vec<String>, Option<String>),
|
||||||
// class, package
|
// class, package
|
||||||
pub implements: Vec<(String, Option<String>)>,
|
pub implements: Vec<(String, Option<String>)>,
|
||||||
pub interface: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClassDec {
|
impl ClassDec {
|
||||||
@ -904,7 +903,6 @@ impl ClassDec {
|
|||||||
scopes: Vec::new(),
|
scopes: Vec::new(),
|
||||||
extends: (Vec::new(), None),
|
extends: (Vec::new(), None),
|
||||||
implements: Vec::new(),
|
implements: Vec::new(),
|
||||||
interface: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use std::fs::File;
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
use std::sync::{Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use tower_lsp::jsonrpc::{Error, ErrorCode, Result};
|
use tower_lsp::jsonrpc::{Error, ErrorCode, Result};
|
||||||
use tower_lsp::lsp_types::*;
|
use tower_lsp::lsp_types::*;
|
||||||
use tower_lsp::{Client, LanguageServer};
|
use tower_lsp::{Client, LanguageServer};
|
||||||
@ -38,10 +38,11 @@ impl LSPServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Backend {
|
pub struct Backend {
|
||||||
client: Client,
|
pub client: Client,
|
||||||
server: LSPServer
|
pub server: LSPServer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Backend {
|
impl Backend {
|
||||||
pub fn new(client: Client, log_handle: LoggerHandle) -> Backend {
|
pub fn new(client: Client, log_handle: LoggerHandle) -> Backend {
|
||||||
Backend {
|
Backend {
|
||||||
@ -215,9 +216,7 @@ impl LanguageServer for Backend {
|
|||||||
match read_config(params.root_uri) {
|
match read_config(params.root_uri) {
|
||||||
Ok(conf) => {
|
Ok(conf) => {
|
||||||
inc_dirs.extend(conf.include_dirs.iter().filter_map(|x| absolute_path(x)));
|
inc_dirs.extend(conf.include_dirs.iter().filter_map(|x| absolute_path(x)));
|
||||||
debug!("{:#?}", inc_dirs);
|
|
||||||
src_dirs.extend(conf.source_dirs.iter().filter_map(|x| absolute_path(x)));
|
src_dirs.extend(conf.source_dirs.iter().filter_map(|x| absolute_path(x)));
|
||||||
debug!("{:#?}", src_dirs);
|
|
||||||
let mut log_handle = self.server.log_handle.lock().unwrap();
|
let mut log_handle = self.server.log_handle.lock().unwrap();
|
||||||
let log_handle = log_handle.as_mut();
|
let log_handle = log_handle.as_mut();
|
||||||
if let Some(handle) = log_handle {
|
if let Some(handle) = log_handle {
|
||||||
@ -252,7 +251,7 @@ impl LanguageServer for Backend {
|
|||||||
drop(inc_dirs);
|
drop(inc_dirs);
|
||||||
drop(src_dirs);
|
drop(src_dirs);
|
||||||
// parse all source files found from walking source dirs and include dirs
|
// parse all source files found from walking source dirs and include dirs
|
||||||
self.server.srcs.init();
|
self.server.srcs.init(Some(&self));
|
||||||
Ok(InitializeResult {
|
Ok(InitializeResult {
|
||||||
server_info: None,
|
server_info: None,
|
||||||
capabilities: ServerCapabilities {
|
capabilities: ServerCapabilities {
|
||||||
@ -278,7 +277,7 @@ impl LanguageServer for Backend {
|
|||||||
work_done_progress: None,
|
work_done_progress: None,
|
||||||
},
|
},
|
||||||
all_commit_characters: None,
|
all_commit_characters: None,
|
||||||
//TODO: check if corect
|
// TODO: check if corect
|
||||||
completion_item: None,
|
completion_item: None,
|
||||||
}),
|
}),
|
||||||
definition_provider: Some(OneOf::Left(true)),
|
definition_provider: Some(OneOf::Left(true)),
|
||||||
@ -296,6 +295,7 @@ impl LanguageServer for Backend {
|
|||||||
self.client
|
self.client
|
||||||
.log_message(MessageType::INFO, "digital lsp initialized!")
|
.log_message(MessageType::INFO, "digital lsp initialized!")
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn shutdown(&self) -> Result<()> {
|
async fn shutdown(&self) -> Result<()> {
|
||||||
@ -303,7 +303,7 @@ impl LanguageServer for Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn did_open(&self, params: DidOpenTextDocumentParams) {
|
async fn did_open(&self, params: DidOpenTextDocumentParams) {
|
||||||
let diagnostics = self.server.did_open(params);
|
let diagnostics = self.server.did_open(params, Some(&self));
|
||||||
self.client
|
self.client
|
||||||
.publish_diagnostics(
|
.publish_diagnostics(
|
||||||
diagnostics.uri,
|
diagnostics.uri,
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
use crate::core::sv_parser::make_fast_from_syntaxtree;
|
||||||
|
use crate::custom_request::update_fast_to_client;
|
||||||
|
use crate::custom_request::UpdateFastNotification;
|
||||||
use crate::definition::def_types::*;
|
use crate::definition::def_types::*;
|
||||||
use crate::definition::get_scopes;
|
use crate::definition::get_scopes;
|
||||||
use crate::diagnostics::{get_diagnostics, is_hidden};
|
use crate::diagnostics::{get_diagnostics, is_hidden};
|
||||||
|
use crate::server::Backend;
|
||||||
use crate::server::LSPServer;
|
use crate::server::LSPServer;
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use pathdiff::diff_paths;
|
use pathdiff::diff_paths;
|
||||||
@ -18,11 +22,20 @@ use thread::JoinHandle;
|
|||||||
use tower_lsp::lsp_types::*;
|
use tower_lsp::lsp_types::*;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
macro_rules! unwrap_result {
|
||||||
|
($expr:expr) => {
|
||||||
|
match $expr {
|
||||||
|
Ok(e) => e,
|
||||||
|
Err(_) => return
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl LSPServer {
|
impl LSPServer {
|
||||||
pub fn did_open(&self, params: DidOpenTextDocumentParams) -> PublishDiagnosticsParams {
|
pub fn did_open(&self, params: DidOpenTextDocumentParams, backend: Option<&Backend>) -> PublishDiagnosticsParams {
|
||||||
let document: TextDocumentItem = params.text_document;
|
let document: TextDocumentItem = params.text_document;
|
||||||
let uri = document.uri.clone();
|
let uri = document.uri.clone();
|
||||||
debug!("did_open: {}", &uri);
|
|
||||||
// check if doc is already added
|
// check if doc is already added
|
||||||
if self.srcs.names.read().unwrap().contains_key(&document.uri) {
|
if self.srcs.names.read().unwrap().contains_key(&document.uri) {
|
||||||
// convert to a did_change that replace the entire text
|
// convert to a did_change that replace the entire text
|
||||||
@ -35,7 +48,7 @@ impl LSPServer {
|
|||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.srcs.add(document);
|
self.srcs.add(document, backend);
|
||||||
}
|
}
|
||||||
// diagnostics
|
// diagnostics
|
||||||
let urls = self.srcs.names.read().unwrap().keys().cloned().collect();
|
let urls = self.srcs.names.read().unwrap().keys().cloned().collect();
|
||||||
@ -160,7 +173,7 @@ impl Sources {
|
|||||||
source_dirs: Arc::new(RwLock::new(Vec::new())),
|
source_dirs: Arc::new(RwLock::new(Vec::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn init(&self) {
|
pub fn init(&self, backend: Option<&Backend>) {
|
||||||
let mut paths: Vec<PathBuf> = Vec::new();
|
let mut paths: Vec<PathBuf> = Vec::new();
|
||||||
for path in &*self.include_dirs.read().unwrap() {
|
for path in &*self.include_dirs.read().unwrap() {
|
||||||
paths.push(path.clone());
|
paths.push(path.clone());
|
||||||
@ -172,21 +185,20 @@ impl Sources {
|
|||||||
let src_paths = find_src_paths(&paths);
|
let src_paths = find_src_paths(&paths);
|
||||||
|
|
||||||
for path in src_paths {
|
for path in src_paths {
|
||||||
if let Ok(url) = Url::from_file_path(&path) {
|
let url = unwrap_result!(Url::from_file_path(&path));
|
||||||
if let Ok(text) = fs::read_to_string(&path) {
|
let text = unwrap_result!(fs::read_to_string(&path));
|
||||||
self.add(TextDocumentItem::new(
|
let doc = TextDocumentItem::new(
|
||||||
url,
|
url,
|
||||||
"systemverilog".to_string(),
|
"systemverilog".to_string(),
|
||||||
-1,
|
-1,
|
||||||
text,
|
text,
|
||||||
));
|
);
|
||||||
}
|
self.add(doc, backend);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add a source file, creating a parse thread for that file
|
/// 增加一个 hdl 文件,并为该文件添加单独的解析线程
|
||||||
pub fn add(&self, doc: TextDocumentItem) {
|
pub fn add(&self, doc: TextDocumentItem, backend: Option<&Backend>) {
|
||||||
// use a condvar to synchronize the parse thread
|
// use a condvar to synchronize the parse thread
|
||||||
// the valid bool decides whether or not the file
|
// the valid bool decides whether or not the file
|
||||||
// needs to be re-parsed
|
// needs to be re-parsed
|
||||||
@ -206,6 +218,8 @@ impl Sources {
|
|||||||
let scope_handle = self.scope_tree.clone();
|
let scope_handle = self.scope_tree.clone();
|
||||||
let inc_dirs = self.include_dirs.clone();
|
let inc_dirs = self.include_dirs.clone();
|
||||||
|
|
||||||
|
let backend = Arc::new(backend);
|
||||||
|
|
||||||
// spawn parse thread
|
// spawn parse thread
|
||||||
let parse_handle = thread::spawn(move || {
|
let parse_handle = thread::spawn(move || {
|
||||||
let (lock, cvar) = &*valid_parse2;
|
let (lock, cvar) = &*valid_parse2;
|
||||||
@ -222,6 +236,13 @@ impl Sources {
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 计算 fast
|
||||||
|
if let Some(syntax_tree) = &syntax_tree {
|
||||||
|
let path = PathBuf::from(uri.path().to_string());
|
||||||
|
let fast = make_fast_from_syntaxtree(&syntax_tree, &path);
|
||||||
|
update_fast_to_client(backend.clone(), fast);
|
||||||
|
}
|
||||||
|
|
||||||
let mut file = source_handle.write().unwrap();
|
let mut file = source_handle.write().unwrap();
|
||||||
|
|
||||||
file.syntax_tree = syntax_tree;
|
file.syntax_tree = syntax_tree;
|
||||||
@ -544,7 +565,7 @@ endmodule"#;
|
|||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
server.did_open(open_params);
|
server.did_open(open_params, None);
|
||||||
let fid = server.srcs.get_id(&uri);
|
let fid = server.srcs.get_id(&uri);
|
||||||
let file = server.srcs.get_file(fid).unwrap();
|
let file = server.srcs.get_file(fid).unwrap();
|
||||||
let file = file.read().unwrap();
|
let file = file.read().unwrap();
|
||||||
@ -597,7 +618,7 @@ endmodule"#;
|
|||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
server.did_open(open_params);
|
server.did_open(open_params, None);
|
||||||
let fid = server.srcs.get_id(&uri);
|
let fid = server.srcs.get_id(&uri);
|
||||||
|
|
||||||
server.srcs.wait_parse_ready(fid, true);
|
server.srcs.wait_parse_ready(fid, true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user