lspkit_treesitter/
cache.rs1use std::collections::hash_map::DefaultHasher;
8use std::hash::{Hash, Hasher};
9use std::sync::Arc;
10
11use dashmap::DashMap;
12use tree_sitter::{Language, Parser, Tree};
13
14use crate::parser::ParserError;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub struct ContentHash(u64);
19
20impl ContentHash {
21 #[must_use]
23 pub fn of(source: &[u8]) -> Self {
24 let mut hasher = DefaultHasher::new();
25 source.hash(&mut hasher);
26 Self(hasher.finish())
27 }
28
29 #[must_use]
31 pub const fn get(self) -> u64 {
32 self.0
33 }
34}
35
36#[derive(Default, Clone)]
38pub struct ParseCache {
39 entries: Arc<DashMap<(String, ContentHash), Arc<Tree>>>,
40}
41
42impl ParseCache {
43 #[must_use]
45 pub fn new() -> Self {
46 Self::default()
47 }
48
49 pub fn parse(
54 &self,
55 language_name: &str,
56 language: &Language,
57 source: &[u8],
58 ) -> Result<Arc<Tree>, ParserError> {
59 let key = (language_name.to_owned(), ContentHash::of(source));
60 if let Some(existing) = self.entries.get(&key) {
61 return Ok(existing.clone());
62 }
63 let mut parser = Parser::new();
64 parser
65 .set_language(language)
66 .map_err(|_| ParserError::UnknownExtension(language_name.to_owned()))?;
67 let Some(tree) = parser.parse(source, None) else {
68 return Err(ParserError::UnknownExtension(language_name.to_owned()));
69 };
70 let arc = Arc::new(tree);
71 self.entries.insert(key, arc.clone());
72 Ok(arc)
73 }
74
75 pub fn clear(&self) {
77 self.entries.clear();
78 }
79
80 #[must_use]
82 pub fn len(&self) -> usize {
83 self.entries.len()
84 }
85
86 #[must_use]
88 pub fn is_empty(&self) -> bool {
89 self.entries.is_empty()
90 }
91}
92
93impl std::fmt::Debug for ParseCache {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 f.debug_struct("ParseCache")
96 .field("entries", &self.entries.len())
97 .finish()
98 }
99}