Skip to main content

code_moniker_workspace/code/
symbols.rs

1use std::path::PathBuf;
2
3use code_moniker_core::core::code_graph::{DefRecord, RefRecord};
4use code_moniker_core::core::moniker::Moniker;
5use code_moniker_core::lang::Lang;
6
7use crate::environment;
8use crate::snapshot::{SourceId, SymbolId, SymbolLocation};
9use crate::source::CodeIndexMaterial;
10
11#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct NormalizedSource {
13	pub id: SourceId,
14	pub uri: String,
15	pub language: Lang,
16	pub rel_path: PathBuf,
17}
18
19#[derive(Clone, Debug, Eq, PartialEq)]
20pub struct NormalizedSymbol {
21	pub id: SymbolId,
22	pub source: NormalizedSource,
23	pub identity: String,
24}
25
26pub struct CodeIndexSymbolProvider<'a> {
27	material: &'a CodeIndexMaterial,
28}
29
30impl<'a> CodeIndexSymbolProvider<'a> {
31	pub fn new(material: &'a CodeIndexMaterial) -> Self {
32		Self { material }
33	}
34
35	pub fn source_at(&self, file_idx: usize) -> Option<NormalizedSource> {
36		let file = self.material.files.get(file_idx)?;
37		Some(NormalizedSource {
38			id: file.source_id,
39			uri: file.source_uri.clone(),
40			language: file.lang,
41			rel_path: file.rel_path.clone(),
42		})
43	}
44
45	pub fn symbol_at(&self, loc: SymbolLocation) -> Option<NormalizedSymbol> {
46		let file = self.material.files.get(loc.file)?;
47		let def = file.graph.defs().nth(loc.symbol)?;
48		let source = self.source_at(loc.file)?;
49		Some(NormalizedSymbol {
50			id: file.identity.symbol_id(loc.file, loc.symbol),
51			source,
52			identity: self.material.identity.moniker_uri(&def.moniker),
53		})
54	}
55
56	pub fn symbol_for_moniker(&self, moniker: &Moniker) -> Option<NormalizedSymbol> {
57		let id = self.material.symbols_by_moniker.get(moniker)?;
58		let (file, symbol) = self.material.identity.symbol_location(id)?;
59		self.symbol_at(SymbolLocation { file, symbol })
60	}
61
62	pub fn identity_for_moniker(&self, moniker: &Moniker) -> String {
63		self.material.identity.moniker_uri(moniker)
64	}
65}
66
67pub fn is_navigable_def(lang: Lang, def: &DefRecord) -> bool {
68	lang.kind_spec(&def_kind(def)).is_some()
69}
70
71pub fn def_kind(def: &DefRecord) -> String {
72	std::str::from_utf8(&def.kind).unwrap_or("?").to_string()
73}
74
75pub fn ref_kind(reference: &RefRecord) -> String {
76	std::str::from_utf8(&reference.kind)
77		.unwrap_or("?")
78		.to_string()
79}
80
81pub fn last_name(moniker: &Moniker) -> String {
82	moniker
83		.as_view()
84		.segments()
85		.last()
86		.and_then(|s| std::str::from_utf8(s.name).ok())
87		.unwrap_or(".")
88		.to_string()
89}
90
91pub fn compact_moniker(moniker: &Moniker) -> String {
92	environment::compact_moniker(moniker, crate::DEFAULT_IDENTITY_SCHEME)
93}