diff --git a/Cargo.lock b/Cargo.lock index a581889..a86bf14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,6 +50,55 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.72" @@ -174,18 +223,89 @@ dependencies = [ "ansi_term", "atty", "bitflags 1.3.2", - "strsim", + "strsim 0.8.0", "textwrap", "unicode-width", "vec_map", ] +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.10.0", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + [[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "dashmap" version = "5.5.0" @@ -222,16 +342,64 @@ dependencies = [ "tempdir", "tokio", "tower-lsp", + "vhdl_lang", "walkdir", "which", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -245,7 +413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -262,6 +430,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -354,6 +528,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.27.2" @@ -387,6 +572,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -408,7 +599,7 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -460,6 +651,21 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -487,6 +693,16 @@ version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.4.2", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -641,7 +857,7 @@ version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -678,6 +894,31 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pad" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + [[package]] name = "parking_lot_core" version = "0.9.8" @@ -741,6 +982,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pinned_vec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "268ad82d92622fb0a049ff14b01089b0f1bcd5c507fab44724394d328417348a" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -811,6 +1058,26 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -829,6 +1096,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.9.1" @@ -893,7 +1171,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -965,6 +1243,15 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "serde_yaml" version = "0.9.25" @@ -1011,13 +1298,19 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "structopt" version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ - "clap", + "clap 2.34.0", "lazy_static", "structopt-derive", ] @@ -1037,23 +1330,36 @@ dependencies = [ [[package]] name = "strum" -version = "0.26.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] [[package]] name = "strum_macros" -version = "0.26.1" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", "syn 2.0.28", ] +[[package]] +name = "subst" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3c1ba4fd019bc866333a61fe205fc9b686e3cf5971dd8dfc116657d933031c" +dependencies = [ + "memchr", + "unicode-width", +] + [[package]] name = "sv-parser" version = "0.13.3" @@ -1230,6 +1536,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -1373,6 +1713,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "vec_map" version = "0.8.2" @@ -1385,6 +1731,35 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vhdl_lang" +version = "0.83.0" +dependencies = [ + "clap 4.4.18", + "dirs", + "dunce", + "enum-map", + "fnv", + "glob", + "itertools", + "pad", + "parking_lot", + "pinned_vec", + "rayon", + "strum", + "subst", + "toml", + "vhdl_lang_macros", +] + +[[package]] +name = "vhdl_lang_macros" +version = "0.83.0" +dependencies = [ + "quote", + "syn 2.0.28", +] + [[package]] name = "walkdir" version = "2.3.3" @@ -1395,6 +1770,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.87" @@ -1459,7 +1840,7 @@ dependencies = [ "home", "once_cell", "rustix", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1502,6 +1883,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -1631,3 +2021,12 @@ name = "windows_x86_64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] diff --git a/src/completion/mod.rs b/src/completion/mod.rs index d9ebf49..a055bcc 100644 --- a/src/completion/mod.rs +++ b/src/completion/mod.rs @@ -8,6 +8,8 @@ use tower_lsp::lsp_types::*; pub mod keyword; pub mod feature; +pub mod vhdl; + impl LSPServer { pub fn completion(&self, params: CompletionParams) -> Option { let doc = params.text_document_position; diff --git a/src/completion/vhdl.rs b/src/completion/vhdl.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/core/mod.rs b/src/core/mod.rs index ac5d98f..d9427ff 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -4,4 +4,4 @@ pub mod fast_hdlparam; pub mod sv_parser; // pub use sv_parser::*; -// pub mod vhdl_parser; \ No newline at end of file +pub mod vhdl_parser; \ No newline at end of file diff --git a/src/core/vhdl_parser.rs b/src/core/vhdl_parser.rs index 0b6bdad..6a132da 100644 --- a/src/core/vhdl_parser.rs +++ b/src/core/vhdl_parser.rs @@ -1,8 +1,13 @@ -use std::collections::HashSet; +use std::{collections::HashSet, str::FromStr}; use std::path::PathBuf; +use tower_lsp::lsp_types::Url; +use vhdl_lang::ast::DesignFile; use vhdl_lang::{kind_str, Token, VHDLParser, VHDLStandard}; +use crate::utils::to_escape_path; + use super::fast_hdlparam::*; +#[allow(unused)] pub fn vhdl_parser(path: &str) -> FastHdlparam { // The path of SystemVerilog source file let path = PathBuf::from(path); @@ -30,6 +35,22 @@ pub fn vhdl_parser(path: &str) -> FastHdlparam { hdlparam } + +pub fn vhdl_parse(uri: &Url) -> Option { + let path = uri.path(); + let path = PathBuf::from_str(path).unwrap(); + let path = to_escape_path(&path); + let mut diagnostics = Vec::new(); + let parser = VHDLParser::new(VHDLStandard::VHDL2008); + if let Ok((_, design_file)) = parser.parse_design_file(&path, &mut diagnostics) { + return Some(design_file); + } + + None +} + + +#[allow(unused)] fn parse_tokens(tokens: Vec) -> Vec { let mut modules = Vec::new(); let mut instance_type = HashSet::new(); @@ -121,6 +142,8 @@ fn parse_tokens(tokens: Vec) -> Vec { } + +#[allow(unused)] fn parse_port(tokens: &[Token], start: usize, is_map: bool) -> (Vec, usize) { let mut ports = Vec::new(); let mut i = start; @@ -209,6 +232,8 @@ fn parse_port(tokens: &[Token], start: usize, is_map: bool) -> (Vec, usize (ports, i) } + +#[allow(unused)] fn parse_width(tokens: &[Token], start: usize) -> (String, usize) { let mut width = String::new(); let mut i = start; @@ -249,6 +274,8 @@ fn parse_width(tokens: &[Token], start: usize) -> (String, usize) { (width, i) } + +#[allow(unused)] fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec, usize) { let mut params = Vec::new(); let mut i = start; @@ -322,6 +349,8 @@ fn parse_parameters(tokens: &[Token], start: usize, is_map: bool) -> (Vec String { match &token.value { vhdl_lang::Value::Identifier(symbol) => { diff --git a/src/definition/def_types.rs b/src/definition/def_types.rs index 8035a26..19b5203 100644 --- a/src/definition/def_types.rs +++ b/src/definition/def_types.rs @@ -1,4 +1,5 @@ use crate::sources::LSPSupport; +#[allow(unused)] use log::info; use ropey::Rope; use tower_lsp::lsp_types::*; @@ -193,7 +194,6 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send { // 优先找 定义,再找 scope for def in self.defs() { if def.ident() == token { - info!("find definition: {:?}", def); return Some(GenericDec { ident: def.ident(), byte_idx: def.byte_idx(), diff --git a/src/definition/mod.rs b/src/definition/mod.rs index dd0afe5..d790dd3 100644 --- a/src/definition/mod.rs +++ b/src/definition/mod.rs @@ -1,4 +1,4 @@ -use crate::{definition::extract_defs::get_ident, utils::get_definition_token}; +use crate::{utils::get_definition_token}; use crate::server::LSPServer; use crate::sources::LSPSupport; @@ -13,9 +13,10 @@ pub use def_types::*; pub mod feature; pub use feature::*; -mod extract_defs; -use extract_defs::*; +pub mod extract_defs; +pub use extract_defs::*; +pub mod vhdl; impl LSPServer { pub fn goto_definition(&self, params: GotoDefinitionParams) -> Option { @@ -54,54 +55,8 @@ impl LSPServer { Range::new(def_pos, def_pos), ))) } - - pub fn document_highlight( - &self, - params: DocumentHighlightParams, - ) -> Option> { - let uri = params.text_document_position_params.text_document.uri; - let pos = params.text_document_position_params.position; - let file_id = self.srcs.get_id(&uri).to_owned(); - self.srcs.wait_parse_ready(file_id, false); - let file = self.srcs.get_file(file_id)?; - let file = file.read().ok()?; - - let line_text = file.text.line(pos.line as usize); - let token = get_definition_token(&line_text, pos); - let scope_tree = self.srcs.scope_tree.read().ok()?; - // use the byte_idx of the definition if possible, otherwise use the cursor - let byte_idx = - match scope_tree - .as_ref()? - .get_definition(&token, file.text.pos_to_byte(&pos), &uri) - { - Some(def) => def.byte_idx, - None => file.text.pos_to_byte(&pos), - }; - let syntax_tree = file.syntax_tree.as_ref()?; - let references = all_identifiers(syntax_tree, &token); - Some( - scope_tree - .as_ref()? - .document_highlights(&uri, &file.text, references, byte_idx), - ) - } } -/// return all identifiers in a syntax tree matching a given token -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)); - } - } - } - idents -} type ScopesAndDefs = Option<(Vec>, Vec>)>; @@ -245,7 +200,7 @@ pub fn match_definitions( /// convert the syntax tree to a scope tree /// the root node is the global scope -pub fn get_scopes(syntax_tree: &SyntaxTree, url: &Url) -> Option { +pub fn get_scopes_from_syntax_tree(syntax_tree: &SyntaxTree, url: &Url) -> Option { let mut scopes: Vec> = Vec::new(); let mut global_scope: GenericScope = GenericScope::new(url); global_scope.ident = String::from("global"); @@ -265,3 +220,4 @@ pub fn get_scopes(syntax_tree: &SyntaxTree, url: &Url) -> Option { global_scope.scopes.append(&mut scopes); Some(global_scope) } + diff --git a/src/definition/vhdl.rs b/src/definition/vhdl.rs new file mode 100644 index 0000000..399c669 --- /dev/null +++ b/src/definition/vhdl.rs @@ -0,0 +1,6 @@ +use tower_lsp::lsp_types::*; +use crate::server::LSPServer; + +pub fn goto_vhdl_definition() { + +} \ No newline at end of file diff --git a/src/document_highlight/mod.rs b/src/document_highlight/mod.rs new file mode 100644 index 0000000..44b8393 --- /dev/null +++ b/src/document_highlight/mod.rs @@ -0,0 +1,57 @@ +use crate::{definition::Scope, server::LSPServer, sources::LSPSupport, utils::{get_definition_token, get_language_id_by_uri}}; +use sv_parser::{RefNode, SyntaxTree}; +use crate::definition::extract_defs::get_ident; +use tower_lsp::lsp_types::*; + +impl LSPServer { + pub fn document_highlight( + &self, + params: DocumentHighlightParams, + ) -> Option> { + let uri = params.text_document_position_params.text_document.uri; + let pos = params.text_document_position_params.position; + let file_id = self.srcs.get_id(&uri).to_owned(); + self.srcs.wait_parse_ready(file_id, false); + let file = self.srcs.get_file(file_id)?; + let file = file.read().ok()?; + + let line_text = file.text.line(pos.line as usize); + let token = get_definition_token(&line_text, pos); + + let language_id = get_language_id_by_uri(&uri); + + let scope_tree = self.srcs.scope_tree.read().ok()?; + // use the byte_idx of the definition if possible, otherwise use the cursor + let byte_idx = + match scope_tree + .as_ref()? + .get_definition(&token, file.text.pos_to_byte(&pos), &uri) + { + Some(def) => def.byte_idx, + None => file.text.pos_to_byte(&pos), + }; + let syntax_tree = file.syntax_tree.as_ref()?; + let references = all_identifiers(syntax_tree, &token); + + Some( + scope_tree + .as_ref()? + .document_highlights(&uri, &file.text, references, byte_idx), + ) + } +} + +/// return all identifiers in a syntax tree matching a given token +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)); + } + } + } + idents +} \ No newline at end of file diff --git a/src/document_symbol/vhdl.rs b/src/document_symbol/vhdl.rs index c96fb80..bb8fb17 100644 --- a/src/document_symbol/vhdl.rs +++ b/src/document_symbol/vhdl.rs @@ -1,6 +1,6 @@ use tower_lsp::lsp_types::*; use crate::server::LSPServer; -// pub fn vhdl_document_symbol(server: &LSPServer, param: &DocumentSymbolParams) -> Option { - -// } \ No newline at end of file +pub fn vhdl_document_symbol(server: &LSPServer, param: &DocumentSymbolParams) -> Option { + None +} \ No newline at end of file diff --git a/src/hover/mod.rs b/src/hover/mod.rs index 17c8ed3..4c9ad37 100644 --- a/src/hover/mod.rs +++ b/src/hover/mod.rs @@ -11,6 +11,8 @@ use tower_lsp::lsp_types::*; pub mod feature; use feature::*; +pub mod vhdl; + impl LSPServer { pub fn hover(&self, params: HoverParams) -> Option { let doc: Url = params.text_document_position_params.text_document.uri; @@ -203,7 +205,6 @@ fn hover_common_symbol( // 根据 symbol 的类别进行额外的判断 - let def_line = file.text.byte_to_line(symbol_definition.byte_idx()); make_hover_with_comment(&file.text, def_line, &language_id) } @@ -215,7 +216,7 @@ fn hover_position_port(line: &RopeSlice, pos: Position, language_id: &str) -> Op if let Some((port_name, range)) = get_word_range_at_position(line, pos, position_port_regex) { if port_name.starts_with(".") { let port_name = &port_name[1..]; - + } } diff --git a/src/hover/vhdl.rs b/src/hover/vhdl.rs new file mode 100644 index 0000000..46b7a70 --- /dev/null +++ b/src/hover/vhdl.rs @@ -0,0 +1,6 @@ +use tower_lsp::lsp_types::*; +use crate::server::LSPServer; + +pub fn hover_vhdl(server: &LSPServer, param: &DocumentSymbolParams) -> Option { + None +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 907f10d..8966cd9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,9 @@ pub mod hover; // 大纲 pub mod document_symbol; +// 语法高亮 +pub mod document_highlight; + // 诊断 pub mod diagnostics; diff --git a/src/main.rs b/src/main.rs index e7e895a..5672be0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod completion; mod definition; mod hover; mod document_symbol; +mod document_highlight; mod utils; mod diagnostics; mod format; diff --git a/src/sources.rs b/src/sources.rs index d6b723e..1e074ac 100644 --- a/src/sources.rs +++ b/src/sources.rs @@ -1,6 +1,6 @@ use crate::core::fast_hdlparam::FastHdlparam; use crate::definition::def_types::*; -use crate::definition::get_scopes; +use crate::definition::get_scopes_from_syntax_tree; use crate::diagnostics::{get_diagnostics, is_hidden}; use crate::server::LSPServer; #[allow(unused)] @@ -106,15 +106,27 @@ impl LSPServer { /// The Source struct holds all file specific information pub struct Source { + /// id pub id: usize, + /// uri pub uri: Url, + /// 代码文本信息 pub text: Rope, + /// 版本号 pub version: i32, - pub syntax_tree: Option, - // if there is a parse error, we can remove the last change + /// 解析的 IR,分为 DesignFile(VHDL)和 SyntaxTree(SV)两种 + pub parse_ir: Option, + /// 用于在解析失败时恢复解析的量 pub last_change_range: Option, } +pub enum ParseIR { + /// 基于 rust_hdl 的IR,存放 VHDL + DesignFile(vhdl_lang::ast::DesignFile), + /// 存放 sv 的 IR + SyntaxTree(sv_parser::SyntaxTree) +} + /// file metadata, including whether or not the syntax tree is up to date pub struct SourceMeta { pub id: usize, @@ -223,7 +235,7 @@ impl Sources { uri: doc.uri.clone(), text: Rope::from_str(&doc.text), version: doc.version, - syntax_tree: None, + parse_ir: None, last_change_range: None, })); let source_handle = source.clone(); @@ -231,6 +243,7 @@ impl Sources { let inc_dirs = self.include_dirs.clone(); info!("launch worker to parse {:?}", doc.uri.to_string()); + let language_id = doc.language_id.to_string(); // spawn parse thread let parse_handle = thread::spawn(move || { @@ -245,48 +258,41 @@ impl Sources { info!("do parse in {:?}", uri.to_string()); + + match language_id.as_str() { + "vhdl" => { + + }, + "verilog" | "system verilog" => { + + }, + _ => {} + } + let syntax_tree = recovery_sv_parse(&text, uri, range, &inc_dirs.read().unwrap()); let mut scope_tree = match &syntax_tree { - Some(tree) => get_scopes(tree, uri), + Some(tree) => get_scopes_from_syntax_tree(tree, uri), None => None, }; - - info!("finish parse {:?}", uri.to_string()); - // 计算 fast - // if let Some(syntax_tree) = &syntax_tree { - // let path = PathBuf::from(uri.path().to_string()); - // let fast = if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &path) { - // fast - // } else { - // crate::core::fast_hdlparam::FastHdlparam { - // fast_macro: crate::core::fast_hdlparam::Macro { - // defines: Vec::new(), - // errors: Vec::new(), - // includes: Vec::new(), - // invalid: Vec::new() - // }, - // content: Vec::new() - // } - // }; - // // update_fast_to_client(backend.clone(), fast); - // block_on(async { - // update_fast_to_client(fast, &path).await; - // }); - // } - let mut file = source_handle.write().unwrap(); - file.syntax_tree = syntax_tree; + // 加入语法树 + if let Some(syntax_tree) = syntax_tree { + let parse_ir = ParseIR::SyntaxTree(syntax_tree); + file.parse_ir = Some(parse_ir); + } else { + file.parse_ir = None; + } + // file.syntax_tree = syntax_tree; drop(file); - // 获取 scope_handle 的写权限 + // 更新 global_scope,用于 sv 的解析 // global_scope 为全局最大的那个 scope,它的 scopes 和 defs 下的元素和每一个文件一一对应 let mut global_scope = scope_handle.write().unwrap(); - match &mut *global_scope { Some(scope) => match &mut scope_tree { Some(tree) => { @@ -358,7 +364,7 @@ impl Sources { pub fn wait_parse_ready(&self, id: usize, wait_valid: bool) { let file = self.get_file(id).unwrap(); let file = file.read().unwrap(); - if file.syntax_tree.is_none() || wait_valid { + if file.parse_ir.is_none() || wait_valid { drop(file); let meta_data = self.get_meta_data(id).unwrap(); let (lock, cvar) = &*meta_data.read().unwrap().valid_parse; @@ -508,6 +514,14 @@ pub fn recovery_sv_parse( } +pub fn sv_parser_pipeline() { + +} + +pub fn vhdl_parser_pipeline() { + +} + //TODO: add bounds checking for utf8<->utf16 conversions /// This trait defines some helper functions to convert between lsp types /// and char/byte positions diff --git a/src/test/mod.rs b/src/test/mod.rs index 02a3f0f..696ca5a 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -232,7 +232,7 @@ mod test_svparse { #[cfg(test)] mod test_scope_tree { use std::{fs, path::{Path, PathBuf}}; - use crate::{definition::{get_scopes, GenericScope}, sources::recovery_sv_parse}; + use crate::{definition::{get_scopes_from_syntax_tree, GenericScope}, sources::recovery_sv_parse}; use ropey::Rope; use tower_lsp::lsp_types::Url; @@ -254,7 +254,7 @@ mod test_scope_tree { let file_url = format!("file://{}", file_path); let uri = Url::parse(&file_url); if let Ok(uri) = uri { - return get_scopes(&syntax_tree, &uri); + return get_scopes_from_syntax_tree(&syntax_tree, &uri); } else { eprintln!("error happen when unwrap uri: {:?}", uri); return None;