add utils of vhdl | add document_symbol
This commit is contained in:
parent
df57c83b0e
commit
f0f31c6c97
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,3 +11,5 @@ log_files
|
||||
test.txt
|
||||
|
||||
build.bat
|
||||
|
||||
.DS_Store
|
113
Cargo.lock
generated
113
Cargo.lock
generated
@ -281,6 +281,15 @@ version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
@ -343,6 +352,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tower-lsp",
|
||||
"vhdl_lang",
|
||||
"vhdl_ls",
|
||||
"walkdir",
|
||||
"which",
|
||||
]
|
||||
@ -400,6 +410,29 @@ dependencies = [
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@ -528,6 +561,15 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuzzy-matcher"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
|
||||
dependencies = [
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.14"
|
||||
@ -608,6 +650,12 @@ version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.57"
|
||||
@ -725,6 +773,18 @@ version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||
|
||||
[[package]]
|
||||
name = "lsp-server"
|
||||
version = "0.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-types"
|
||||
version = "0.94.1"
|
||||
@ -738,6 +798,19 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-types"
|
||||
version = "0.95.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e34d33a8e9b006cd3fc4fe69a921affa097bae4bb65f76271f4644f9a334365"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
@ -1203,18 +1276,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.179"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.179"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1223,9 +1296,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.104"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
|
||||
checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -1483,6 +1556,16 @@ dependencies = [
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
@ -1602,7 +1685,7 @@ dependencies = [
|
||||
"dashmap",
|
||||
"futures",
|
||||
"httparse",
|
||||
"lsp-types",
|
||||
"lsp-types 0.94.1",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -1760,6 +1843,22 @@ dependencies = [
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vhdl_ls"
|
||||
version = "0.83.0"
|
||||
dependencies = [
|
||||
"clap 4.4.18",
|
||||
"env_logger",
|
||||
"fnv",
|
||||
"fuzzy-matcher",
|
||||
"log",
|
||||
"lsp-server",
|
||||
"lsp-types 0.95.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"vhdl_lang",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.3"
|
||||
|
@ -7,6 +7,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"}
|
||||
vhdl_lang = { version = "^0.83.0", path = "rust_hdl/vhdl_lang" }
|
||||
vhdl_ls = { version = "^0.83.0", path = "rust_hdl/vhdl_ls" }
|
||||
once_cell = "1.8"
|
||||
percent-encoding = "2.1.0"
|
||||
log = "0.4.19"
|
||||
|
2
rust_hdl
2
rust_hdl
@ -1 +1 @@
|
||||
Subproject commit f881ca161ac60accdf65295851ded9abf413da75
|
||||
Subproject commit d3f01fe8ec8d6d48031e3eaf043a65244297ca9c
|
@ -1,6 +1,109 @@
|
||||
use log::info;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use crate::server::LSPServer;
|
||||
use crate::{server::LSPServer, utils::to_lsp_range};
|
||||
use crate::utils::{to_escape_path, to_symbol_kind};
|
||||
|
||||
pub fn vhdl_document_symbol(server: &LSPServer, param: &DocumentSymbolParams) -> Option<DocumentSymbolResponse> {
|
||||
None
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use vhdl_lang::{EntHierarchy, Token};
|
||||
|
||||
pub fn vhdl_document_symbol(server: &LSPServer, params: &DocumentSymbolParams) -> Option<DocumentSymbolResponse> {
|
||||
let uri = ¶ms.text_document.uri;
|
||||
let file_id = server.srcs.get_id(&uri).to_owned();
|
||||
server.srcs.wait_parse_ready(file_id, false);
|
||||
let projects = server.srcs.design_file_map.read().ok()?;
|
||||
|
||||
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_string = escape_path.to_str().unwrap_or("");
|
||||
if escape_path_string.len() == 0 {
|
||||
info!("error happen in [vhdl_parser_pipeline], escape_path_string is empty");
|
||||
return None;
|
||||
}
|
||||
let project = match projects.get(escape_path_string) {
|
||||
Some(project) => project,
|
||||
None => return None
|
||||
};
|
||||
|
||||
let source = project.get_source(&escape_path)?;
|
||||
|
||||
// Some files are mapped to multiple libraries, only use the first library for document symbols
|
||||
let library_name = project
|
||||
.library_mapping_of(&source)
|
||||
.into_iter()
|
||||
.next()?;
|
||||
|
||||
// TODO: Confirm vscode support
|
||||
// if server.client_has_hierarchical_document_symbol_support() {
|
||||
fn to_document_symbol(
|
||||
EntHierarchy { ent, children }: EntHierarchy,
|
||||
ctx: &Vec<Token>,
|
||||
) -> DocumentSymbol {
|
||||
// Use the declaration position, if it exists,
|
||||
// else the position of the first source range token.
|
||||
// The latter is applicable for unnamed elements, e.g., processes or loops.
|
||||
let selection_pos = ent.decl_pos().unwrap_or(ent.src_span.start_token.pos(ctx));
|
||||
let src_range = ent.src_span.pos(ctx).range();
|
||||
#[allow(deprecated)]
|
||||
DocumentSymbol {
|
||||
name: ent.describe(),
|
||||
kind: to_symbol_kind(ent.kind()),
|
||||
tags: None,
|
||||
detail: None,
|
||||
selection_range: to_lsp_range(selection_pos.range),
|
||||
range: to_lsp_range(src_range),
|
||||
children: if !children.is_empty() {
|
||||
Some(
|
||||
children
|
||||
.into_iter()
|
||||
.map(|hierarchy| to_document_symbol(hierarchy, ctx))
|
||||
.collect(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
deprecated: None,
|
||||
}
|
||||
}
|
||||
|
||||
Some(DocumentSymbolResponse::Nested(
|
||||
project
|
||||
.document_symbols(&library_name, &source)
|
||||
.into_iter()
|
||||
.map(|(hierarchy, tokens)| to_document_symbol(hierarchy, tokens))
|
||||
.collect(),
|
||||
))
|
||||
// } else {
|
||||
// #[allow(clippy::ptr_arg)]
|
||||
// fn to_symbol_information(ent: EntRef, ctx: &Vec<Token>) -> SymbolInformation {
|
||||
// let selection_pos = ent.decl_pos().unwrap_or(ent.src_span.start_token.pos(ctx));
|
||||
// #[allow(deprecated)]
|
||||
// SymbolInformation {
|
||||
// name: ent.describe(),
|
||||
// kind: to_symbol_kind(ent.kind()),
|
||||
// tags: None,
|
||||
// location: srcpos_to_location(selection_pos),
|
||||
// deprecated: None,
|
||||
// container_name: ent.parent_in_same_source().map(|ent| ent.describe()),
|
||||
// }
|
||||
// }
|
||||
|
||||
// Some(DocumentSymbolResponse::Flat(
|
||||
// project
|
||||
// .document_symbols(&library_name, &source)
|
||||
// .into_iter()
|
||||
// .flat_map(|(a, ctx)| {
|
||||
// a.into_flat()
|
||||
// .into_iter()
|
||||
// .map(|hierarchy| to_symbol_information(hierarchy, ctx))
|
||||
// })
|
||||
// .collect(),
|
||||
// ))
|
||||
// }
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
use crate::core::fast_hdlparam::FastHdlparam;
|
||||
use crate::core::fast_hdlparam::HdlParam;
|
||||
use crate::core::sv_parser::make_fast_from_syntaxtree;
|
||||
use crate::core::vhdl_parser::make_fast_from_design_file;
|
||||
@ -13,7 +12,7 @@ use log::info;
|
||||
use log::{debug, error};
|
||||
use pathdiff::diff_paths;
|
||||
use ropey::{Rope, RopeSlice};
|
||||
use vhdl_lang::ast::DesignFile;
|
||||
use vhdl_lang::MessagePrinter;
|
||||
use std::cmp::min;
|
||||
use std::collections::HashMap;
|
||||
use std::env::current_dir;
|
||||
@ -130,7 +129,7 @@ pub struct Source {
|
||||
pub enum ParseIR {
|
||||
/// 基于 rust_hdl 的IR,存放 VHDL
|
||||
#[allow(unused)]
|
||||
DesignFile(vhdl_lang::ast::DesignFile),
|
||||
VHDLProject(vhdl_lang::Project),
|
||||
/// 存放 sv 的 IR
|
||||
SyntaxTree(sv_parser::SyntaxTree)
|
||||
}
|
||||
@ -178,7 +177,7 @@ pub struct Sources {
|
||||
/// scope tree 类型的树形结构,用于提供 sv 的 lsp
|
||||
pub scope_tree: Arc<RwLock<Option<GenericScope>>>,
|
||||
/// 存储 vhdl design file ir 的对象
|
||||
pub design_file_map: Arc<RwLock<HashMap<String, DesignFile>>>,
|
||||
pub design_file_map: Arc<RwLock<HashMap<String, vhdl_lang::Project>>>,
|
||||
// include directories, passed to parser to resolve `include
|
||||
pub include_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
||||
// source directories
|
||||
@ -567,7 +566,7 @@ pub fn sv_parser_pipeline(
|
||||
}
|
||||
|
||||
pub fn vhdl_parser_pipeline(
|
||||
design_file_handle: &Arc<RwLock<HashMap<String, DesignFile>>>,
|
||||
design_file_handle: &Arc<RwLock<HashMap<String, vhdl_lang::Project>>>,
|
||||
hdl_param_handle: &Arc<HdlParam>,
|
||||
uri: &Url
|
||||
) {
|
||||
@ -589,7 +588,9 @@ pub fn vhdl_parser_pipeline(
|
||||
if let Some(fast) = make_fast_from_design_file(&design_file) {
|
||||
hdl_param_handle.update_fast(escape_path_string.to_string(), fast);
|
||||
}
|
||||
design_files.insert(escape_path_string.to_string(), design_file);
|
||||
let mut msg_printer = MessagePrinter::default();
|
||||
let project = vhdl_lang::Project::new_without_config(&escape_path, &mut msg_printer, None);
|
||||
design_files.insert(escape_path_string.to_string(), project);
|
||||
}
|
||||
}
|
||||
|
||||
|
113
src/utils/mod.rs
113
src/utils/mod.rs
@ -4,6 +4,7 @@ use percent_encoding::percent_decode_str;
|
||||
use regex::Regex;
|
||||
use ropey::RopeSlice;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use vhdl_lang::{ast::ObjectClass, AnyEntKind, Object, Overloaded, Type, Concurrent};
|
||||
|
||||
pub mod fast;
|
||||
|
||||
@ -140,3 +141,115 @@ pub fn to_escape_path(path: &PathBuf) -> PathBuf {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_lsp_pos(position: vhdl_lang::Position) -> Position {
|
||||
Position {
|
||||
line: position.line,
|
||||
character: position.character,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_lsp_range(range: vhdl_lang::Range) -> Range {
|
||||
Range {
|
||||
start: to_lsp_pos(range.start),
|
||||
end: to_lsp_pos(range.end),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_symbol_kind(kind: &AnyEntKind) -> SymbolKind {
|
||||
match kind {
|
||||
AnyEntKind::ExternalAlias { class, .. } => object_class_kind(ObjectClass::from(*class)),
|
||||
AnyEntKind::ObjectAlias { base_object, .. } => object_kind(base_object.object()),
|
||||
AnyEntKind::Object(o) => object_kind(o),
|
||||
AnyEntKind::LoopParameter(_) => SymbolKind::CONSTANT,
|
||||
AnyEntKind::PhysicalLiteral(_) => SymbolKind::CONSTANT,
|
||||
AnyEntKind::DeferredConstant(_) => SymbolKind::CONSTANT,
|
||||
AnyEntKind::File { .. } => SymbolKind::FILE,
|
||||
AnyEntKind::InterfaceFile { .. } => SymbolKind::INTERFACE,
|
||||
AnyEntKind::Component(_) => SymbolKind::CLASS,
|
||||
AnyEntKind::Attribute(_) => SymbolKind::PROPERTY,
|
||||
AnyEntKind::Overloaded(o) => overloaded_kind(o),
|
||||
AnyEntKind::Type(t) => type_kind(t),
|
||||
AnyEntKind::ElementDeclaration(_) => SymbolKind::FIELD,
|
||||
AnyEntKind::Sequential(_) => SymbolKind::NAMESPACE,
|
||||
AnyEntKind::Concurrent(Some(Concurrent::Instance)) => SymbolKind::MODULE,
|
||||
AnyEntKind::Concurrent(_) => SymbolKind::NAMESPACE,
|
||||
AnyEntKind::Library => SymbolKind::NAMESPACE,
|
||||
AnyEntKind::View(_) => SymbolKind::INTERFACE,
|
||||
AnyEntKind::Design(d) => match d {
|
||||
vhdl_lang::Design::Entity(_, _) => SymbolKind::MODULE,
|
||||
vhdl_lang::Design::Architecture(..) => SymbolKind::MODULE,
|
||||
vhdl_lang::Design::Configuration => SymbolKind::MODULE,
|
||||
vhdl_lang::Design::Package(_, _) => SymbolKind::PACKAGE,
|
||||
vhdl_lang::Design::PackageBody(..) => SymbolKind::PACKAGE,
|
||||
vhdl_lang::Design::UninstPackage(_, _) => SymbolKind::PACKAGE,
|
||||
vhdl_lang::Design::PackageInstance(_) => SymbolKind::PACKAGE,
|
||||
vhdl_lang::Design::InterfacePackageInstance(_) => SymbolKind::PACKAGE,
|
||||
vhdl_lang::Design::Context(_) => SymbolKind::NAMESPACE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_kind(t: &Type) -> SymbolKind {
|
||||
match t {
|
||||
vhdl_lang::Type::Array { .. } => SymbolKind::ARRAY,
|
||||
vhdl_lang::Type::Enum(_) => SymbolKind::ENUM,
|
||||
vhdl_lang::Type::Integer => SymbolKind::NUMBER,
|
||||
vhdl_lang::Type::Real => SymbolKind::NUMBER,
|
||||
vhdl_lang::Type::Physical => SymbolKind::NUMBER,
|
||||
vhdl_lang::Type::Access(_) => SymbolKind::ENUM,
|
||||
vhdl_lang::Type::Record(_) => SymbolKind::STRUCT,
|
||||
vhdl_lang::Type::Incomplete => SymbolKind::NULL,
|
||||
vhdl_lang::Type::Subtype(t) => type_kind(t.type_mark().kind()),
|
||||
vhdl_lang::Type::Protected(_, _) => SymbolKind::CLASS,
|
||||
vhdl_lang::Type::File => SymbolKind::FILE,
|
||||
vhdl_lang::Type::Interface => SymbolKind::TYPE_PARAMETER,
|
||||
vhdl_lang::Type::Alias(t) => type_kind(t.kind()),
|
||||
vhdl_lang::Type::Universal(_) => SymbolKind::NUMBER,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn overloaded_kind(overloaded: &Overloaded) -> SymbolKind {
|
||||
match overloaded {
|
||||
Overloaded::SubprogramDecl(_) => SymbolKind::FUNCTION,
|
||||
Overloaded::Subprogram(_) => SymbolKind::FUNCTION,
|
||||
Overloaded::UninstSubprogramDecl(..) => SymbolKind::FUNCTION,
|
||||
Overloaded::UninstSubprogram(..) => SymbolKind::FUNCTION,
|
||||
Overloaded::InterfaceSubprogram(_) => SymbolKind::FUNCTION,
|
||||
Overloaded::EnumLiteral(_) => SymbolKind::ENUM_MEMBER,
|
||||
Overloaded::Alias(o) => overloaded_kind(o.kind()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object_kind(object: &Object) -> SymbolKind {
|
||||
if matches!(object.subtype.type_mark().kind(), Type::Protected(..)) {
|
||||
SymbolKind::OBJECT
|
||||
} else if object.iface.is_some() {
|
||||
SymbolKind::INTERFACE
|
||||
} else {
|
||||
object_class_kind(object.class)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object_class_kind(class: ObjectClass) -> SymbolKind {
|
||||
match class {
|
||||
ObjectClass::Signal => SymbolKind::EVENT,
|
||||
ObjectClass::Constant => SymbolKind::CONSTANT,
|
||||
ObjectClass::Variable => SymbolKind::VARIABLE,
|
||||
ObjectClass::SharedVariable => SymbolKind::VARIABLE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_lsp_pos(position: Position) -> vhdl_lang::Position {
|
||||
vhdl_lang::Position {
|
||||
line: position.line,
|
||||
character: position.character,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_lsp_range(range: Range) -> vhdl_lang::Range {
|
||||
vhdl_lang::Range {
|
||||
start: from_lsp_pos(range.start),
|
||||
end: from_lsp_pos(range.end),
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user