1use std::hash::{Hash, Hasher};
2use std::ops::{Deref, DerefMut};
3use std::path::PathBuf;
4use std::sync::Arc;
5
6use cairo_lang_diagnostics::{DiagnosticLocation, DiagnosticNote, Maybe, Severity};
7use cairo_lang_filesystem::flag::Flag;
8use cairo_lang_filesystem::ids::{
9 CodeMapping, CrateId, CrateLongId, FileId, FileKind, FileLongId, VirtualFile,
10};
11use cairo_lang_filesystem::span::{TextOffset, TextSpan, TextWidth};
12use cairo_lang_syntax::node::ast::{
13 FunctionWithBodyPtr, GenericParamPtr, ItemConstantPtr, ItemEnumPtr, ItemExternFunctionPtr,
14 ItemExternTypePtr, ItemImplAliasPtr, ItemImplPtr, ItemMacroDeclarationPtr, ItemModulePtr,
15 ItemStructPtr, ItemTraitPtr, ItemTypeAliasPtr, UsePathLeafPtr, UsePathStarPtr,
16};
17use cairo_lang_syntax::node::green::{GreenNode, GreenNodeDetails};
18use cairo_lang_syntax::node::ids::{GreenId, SyntaxStablePtrId};
19use cairo_lang_syntax::node::kind::SyntaxKind;
20use cairo_lang_syntax::node::stable_ptr::SyntaxStablePtr;
21use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode, ast};
22use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
23use cairo_lang_utils::{Intern, LookupIntern};
24use salsa::InternKey;
25use serde::{Deserialize, Serialize};
26use smol_str::SmolStr;
27
28use crate::db::{DefsGroup, ModuleData, ModuleDataCacheAndLoadingData};
29use crate::ids::{
30 ConstantId, ConstantLongId, EnumId, EnumLongId, ExternFunctionId, ExternFunctionLongId,
31 ExternTypeId, ExternTypeLongId, FileIndex, FreeFunctionId, FreeFunctionLongId, GenericParamId,
32 GenericParamLongId, GlobalUseId, GlobalUseLongId, ImplAliasId, ImplAliasLongId, ImplDefId,
33 ImplDefLongId, LanguageElementId, MacroDeclarationId, MacroDeclarationLongId, ModuleFileId,
34 ModuleId, ModuleItemId, ModuleTypeAliasId, ModuleTypeAliasLongId, PluginGeneratedFileId,
35 PluginGeneratedFileLongId, StructId, StructLongId, SubmoduleId, SubmoduleLongId, TraitId,
36 TraitLongId, UseId, UseLongId,
37};
38use crate::plugin::{DynGeneratedFileAuxData, PluginDiagnostic};
39
40#[derive(Serialize, Deserialize)]
42pub struct CachedCrateMetadata {
43 pub settings: Option<u64>,
45 pub compiler_version: String,
47 pub global_flags: OrderedHashMap<SmolStr, Flag>,
49}
50
51impl CachedCrateMetadata {
52 pub fn new(crate_id: CrateId, db: &dyn DefsGroup) -> Self {
54 let settings = db.crate_config(crate_id).map(|config| config.settings).map(|v| {
55 let mut hasher = xxhash_rust::xxh3::Xxh3::default();
56 v.hash(&mut hasher);
57 hasher.finish()
58 });
59 let compiler_version = env!("CARGO_PKG_VERSION").to_string();
60 let global_flags = db
61 .flags()
62 .iter()
63 .map(|(flag_id, flag)| (flag_id.lookup_intern(db).0, (**flag).clone()))
64 .collect();
65 Self { settings, compiler_version, global_flags }
66 }
67}
68
69fn validate_metadata(crate_id: CrateId, metadata: &CachedCrateMetadata, db: &dyn DefsGroup) {
71 let current_metadata = CachedCrateMetadata::new(crate_id, db);
72
73 if current_metadata.compiler_version != metadata.compiler_version {
74 panic!("Cached crate was compiled with a different compiler version.");
75 }
76 if current_metadata.settings != metadata.settings {
77 panic!("Cached crate was compiled with different settings.");
78 }
79
80 if !current_metadata.global_flags.eq_unordered(&metadata.global_flags) {
81 panic!("Cached crate was compiled with different global flags.");
82 }
83}
84
85type DefCache = (CachedCrateMetadata, Vec<(ModuleIdCached, ModuleDataCached)>, DefCacheLookups);
86
87pub fn load_cached_crate_modules(
89 db: &dyn DefsGroup,
90 crate_id: CrateId,
91) -> Option<ModuleDataCacheAndLoadingData> {
92 let blob_id = db.crate_config(crate_id)?.cache_file?;
93 let Some(content) = db.blob_content(blob_id) else {
94 return Default::default();
95 };
96
97 let size = usize::from_be_bytes(content[..8].try_into().unwrap());
98
99 let content = &content[8..size + 8];
100
101 let ((metadata, module_data, defs_lookups), _): (DefCache, _) =
102 bincode::serde::borrow_decode_from_slice(content, bincode::config::standard())
103 .unwrap_or_else(|e| {
104 panic!(
105 "failed to deserialize modules cache for crate `{}`: {e}",
106 crate_id.name(db),
107 )
108 });
109
110 validate_metadata(crate_id, &metadata, db);
111
112 let mut ctx = DefCacheLoadingContext::new(db, defs_lookups, crate_id);
113 Some((
114 module_data
115 .into_iter()
116 .map(|(module_id, module_data)| {
117 let module_id = module_id.embed(&mut ctx);
118
119 let module_data = module_data.embed(&mut ctx);
120 (module_id, module_data)
121 })
122 .collect::<OrderedHashMap<_, _>>()
123 .into(),
124 ctx.data.into(),
125 ))
126}
127
128pub fn generate_crate_def_cache(
130 db: &dyn DefsGroup,
131 crate_id: cairo_lang_filesystem::ids::CrateId,
132 ctx: &mut DefCacheSavingContext<'_>,
133) -> Maybe<Vec<(ModuleIdCached, ModuleDataCached)>> {
134 let modules = db.crate_modules(crate_id);
135
136 let cached: Vec<(ModuleIdCached, ModuleDataCached)> = modules
137 .iter()
138 .map(|id| {
139 let module_data = db.priv_module_data(*id)?;
140 Ok((ModuleIdCached::new(*id, ctx), ModuleDataCached::new(module_data, ctx)))
141 })
142 .collect::<Maybe<Vec<_>>>()?;
143
144 Ok(cached)
145}
146
147pub struct DefCacheLoadingContext<'db> {
149 db: &'db dyn DefsGroup,
151
152 data: DefCacheLoadingData,
154}
155
156impl<'db> DefCacheLoadingContext<'db> {
157 pub fn new(db: &'db dyn DefsGroup, lookups: DefCacheLookups, self_crate_id: CrateId) -> Self {
158 let mut res = Self { db, data: DefCacheLoadingData::new(lookups, self_crate_id) };
159 res.embed_lookups();
160 res
161 }
162 fn embed_lookups(&mut self) {
163 for id in 0..self.lookups.green_ids_lookup.len() {
164 GreenIdCached(id).embed(self);
165 }
166
167 for id in 0..self.lookups.crate_ids_lookup.len() {
168 CrateIdCached::Other(id).embed(self);
169 }
170 for id in 0..self.lookups.syntax_stable_ptr_ids_lookup.len() {
171 SyntaxStablePtrIdCached(id).embed(self);
172 }
173 for id in 0..self.lookups.submodule_ids_lookup.len() {
174 SubmoduleIdCached(id).embed(self);
175 }
176 for id in 0..self.lookups.constant_ids_lookup.len() {
177 ConstantIdCached(id).embed(self);
178 }
179 for id in 0..self.lookups.use_ids_lookup.len() {
180 UseIdCached(id).embed(self);
181 }
182 for id in 0..self.lookups.free_function_ids_lookup.len() {
183 FreeFunctionIdCached(id).embed(self);
184 }
185 for id in 0..self.lookups.struct_ids_lookup.len() {
186 StructIdCached(id).embed(self);
187 }
188 for id in 0..self.lookups.enum_ids_lookup.len() {
189 EnumIdCached(id).embed(self);
190 }
191 for id in 0..self.lookups.type_alias_ids_lookup.len() {
192 ModuleTypeAliasIdCached(id).embed(self);
193 }
194 for id in 0..self.lookups.impl_alias_ids_lookup.len() {
195 ImplAliasIdCached(id).embed(self);
196 }
197 for id in 0..self.lookups.trait_ids_lookup.len() {
198 TraitIdCached(id).embed(self);
199 }
200 for id in 0..self.lookups.impl_def_ids_lookup.len() {
201 ImplDefIdCached(id).embed(self);
202 }
203 for id in 0..self.lookups.extern_type_ids_lookup.len() {
204 ExternTypeIdCached(id).embed(self);
205 }
206 for id in 0..self.lookups.extern_function_ids_lookup.len() {
207 ExternFunctionIdCached(id).embed(self);
208 }
209 for id in 0..self.lookups.global_use_ids_lookup.len() {
210 GlobalUseIdCached(id).embed(self);
211 }
212 for id in 0..self.lookups.file_ids_lookup.len() {
213 FileIdCached(id).embed(self);
214 }
215 }
216}
217
218impl Deref for DefCacheLoadingContext<'_> {
219 type Target = DefCacheLoadingData;
220
221 fn deref(&self) -> &Self::Target {
222 &self.data
223 }
224}
225impl DerefMut for DefCacheLoadingContext<'_> {
226 fn deref_mut(&mut self) -> &mut Self::Target {
227 &mut self.data
228 }
229}
230
231#[derive(PartialEq, Eq)]
233pub struct DefCacheLoadingData {
234 green_ids: OrderedHashMap<GreenIdCached, GreenId>,
235 crate_ids: OrderedHashMap<CrateIdCached, CrateId>,
236 syntax_stable_ptr_ids: OrderedHashMap<SyntaxStablePtrIdCached, SyntaxStablePtrId>,
237 submodule_ids: OrderedHashMap<SubmoduleIdCached, SubmoduleId>,
238 constant_ids: OrderedHashMap<ConstantIdCached, ConstantId>,
239 use_ids: OrderedHashMap<UseIdCached, UseId>,
240 free_function_ids: OrderedHashMap<FreeFunctionIdCached, FreeFunctionId>,
241 struct_ids: OrderedHashMap<StructIdCached, StructId>,
242 enum_ids: OrderedHashMap<EnumIdCached, EnumId>,
243 type_alias_ids: OrderedHashMap<ModuleTypeAliasIdCached, ModuleTypeAliasId>,
244 impl_alias_ids: OrderedHashMap<ImplAliasIdCached, ImplAliasId>,
245 trait_ids: OrderedHashMap<TraitIdCached, TraitId>,
246 impl_def_ids: OrderedHashMap<ImplDefIdCached, ImplDefId>,
247 extern_type_ids: OrderedHashMap<ExternTypeIdCached, ExternTypeId>,
248 extern_function_ids: OrderedHashMap<ExternFunctionIdCached, ExternFunctionId>,
249 macro_declaration_ids: OrderedHashMap<MacroDeclarationIdCached, MacroDeclarationId>,
250 global_use_ids: OrderedHashMap<GlobalUseIdCached, GlobalUseId>,
251
252 file_ids: OrderedHashMap<FileIdCached, FileId>,
253 self_crate_id: CrateId,
254 lookups: DefCacheLookups,
255}
256
257impl DefCacheLoadingData {
258 fn new(lookups: DefCacheLookups, self_crate_id: CrateId) -> Self {
259 Self {
260 green_ids: OrderedHashMap::default(),
261 syntax_stable_ptr_ids: OrderedHashMap::default(),
262 crate_ids: OrderedHashMap::default(),
263 submodule_ids: OrderedHashMap::default(),
264 constant_ids: OrderedHashMap::default(),
265 use_ids: OrderedHashMap::default(),
266 free_function_ids: OrderedHashMap::default(),
267 struct_ids: OrderedHashMap::default(),
268 enum_ids: OrderedHashMap::default(),
269 type_alias_ids: OrderedHashMap::default(),
270 impl_alias_ids: OrderedHashMap::default(),
271 trait_ids: OrderedHashMap::default(),
272 impl_def_ids: OrderedHashMap::default(),
273 extern_type_ids: OrderedHashMap::default(),
274 extern_function_ids: OrderedHashMap::default(),
275 macro_declaration_ids: OrderedHashMap::default(),
276 global_use_ids: OrderedHashMap::default(),
277
278 file_ids: OrderedHashMap::default(),
279 self_crate_id,
280 lookups,
281 }
282 }
283}
284
285impl std::fmt::Debug for DefCacheLoadingData {
286 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
287 f.debug_struct("DefCacheLoadingData").finish()
288 }
289}
290
291impl Deref for DefCacheLoadingData {
292 type Target = DefCacheLookups;
293
294 fn deref(&self) -> &Self::Target {
295 &self.lookups
296 }
297}
298impl DerefMut for DefCacheLoadingData {
299 fn deref_mut(&mut self) -> &mut Self::Target {
300 &mut self.lookups
301 }
302}
303
304pub struct DefCacheSavingContext<'db> {
306 db: &'db dyn DefsGroup,
307 data: DefCacheSavingData,
308 self_crate_id: CrateId,
309}
310impl Deref for DefCacheSavingContext<'_> {
311 type Target = DefCacheSavingData;
312
313 fn deref(&self) -> &Self::Target {
314 &self.data
315 }
316}
317impl DerefMut for DefCacheSavingContext<'_> {
318 fn deref_mut(&mut self) -> &mut Self::Target {
319 &mut self.data
320 }
321}
322impl<'db> DefCacheSavingContext<'db> {
323 pub fn new(db: &'db dyn DefsGroup, self_crate_id: CrateId) -> Self {
324 Self { db, data: DefCacheSavingData::default(), self_crate_id }
325 }
326}
327
328#[derive(Default)]
330pub struct DefCacheSavingData {
331 green_ids: OrderedHashMap<GreenId, GreenIdCached>,
332 crate_ids: OrderedHashMap<CrateId, CrateIdCached>,
333 submodule_ids: OrderedHashMap<SubmoduleId, SubmoduleIdCached>,
334 constant_ids: OrderedHashMap<ConstantId, ConstantIdCached>,
335 use_ids: OrderedHashMap<UseId, UseIdCached>,
336 free_function_ids: OrderedHashMap<FreeFunctionId, FreeFunctionIdCached>,
337 struct_ids: OrderedHashMap<StructId, StructIdCached>,
338 enum_ids: OrderedHashMap<EnumId, EnumIdCached>,
339 type_alias_ids: OrderedHashMap<ModuleTypeAliasId, ModuleTypeAliasIdCached>,
340 impl_alias_ids: OrderedHashMap<ImplAliasId, ImplAliasIdCached>,
341 trait_ids: OrderedHashMap<TraitId, TraitIdCached>,
342 impl_def_ids: OrderedHashMap<ImplDefId, ImplDefIdCached>,
343 extern_type_ids: OrderedHashMap<ExternTypeId, ExternTypeIdCached>,
344 extern_function_ids: OrderedHashMap<ExternFunctionId, ExternFunctionIdCached>,
345 global_use_ids: OrderedHashMap<GlobalUseId, GlobalUseIdCached>,
346 macro_declaration_ids: OrderedHashMap<MacroDeclarationId, MacroDeclarationIdCached>,
347
348 syntax_stable_ptr_ids: OrderedHashMap<SyntaxStablePtrId, SyntaxStablePtrIdCached>,
349 file_ids: OrderedHashMap<FileId, FileIdCached>,
350
351 pub lookups: DefCacheLookups,
352}
353
354impl Deref for DefCacheSavingData {
355 type Target = DefCacheLookups;
356
357 fn deref(&self) -> &Self::Target {
358 &self.lookups
359 }
360}
361impl DerefMut for DefCacheSavingData {
362 fn deref_mut(&mut self) -> &mut Self::Target {
363 &mut self.lookups
364 }
365}
366
367#[derive(Serialize, Deserialize)]
368pub struct ModuleDataCached {
369 items: Vec<ModuleItemIdCached>,
370
371 constants: OrderedHashMap<ConstantIdCached, TypeSyntaxNodeCached<ast::ItemConstant>>,
372 submodules: OrderedHashMap<SubmoduleIdCached, TypeSyntaxNodeCached<ast::ItemModule>>,
373 uses: OrderedHashMap<UseIdCached, TypeSyntaxNodeCached<ast::UsePathLeaf>>,
374 free_functions:
375 OrderedHashMap<FreeFunctionIdCached, TypeSyntaxNodeCached<ast::FunctionWithBody>>,
376 structs: OrderedHashMap<StructIdCached, TypeSyntaxNodeCached<ast::ItemStruct>>,
377 enums: OrderedHashMap<EnumIdCached, TypeSyntaxNodeCached<ast::ItemEnum>>,
378 type_aliases: OrderedHashMap<ModuleTypeAliasIdCached, TypeSyntaxNodeCached<ast::ItemTypeAlias>>,
379 impl_aliases: OrderedHashMap<ImplAliasIdCached, TypeSyntaxNodeCached<ast::ItemImplAlias>>,
380 traits: OrderedHashMap<TraitIdCached, TypeSyntaxNodeCached<ast::ItemTrait>>,
381 impls: OrderedHashMap<ImplDefIdCached, TypeSyntaxNodeCached<ast::ItemImpl>>,
382 extern_types: OrderedHashMap<ExternTypeIdCached, TypeSyntaxNodeCached<ast::ItemExternType>>,
383 extern_functions:
384 OrderedHashMap<ExternFunctionIdCached, TypeSyntaxNodeCached<ast::ItemExternFunction>>,
385 macro_declarations:
386 OrderedHashMap<MacroDeclarationIdCached, TypeSyntaxNodeCached<ast::ItemMacroDeclaration>>,
387 global_uses: OrderedHashMap<GlobalUseIdCached, TypeSyntaxNodeCached<ast::UsePathStar>>,
388
389 files: Vec<FileIdCached>,
390
391 generated_file_aux_data: Vec<Option<DynGeneratedFileAuxData>>,
392 plugin_diagnostics: Vec<(ModuleFileCached, PluginDiagnosticCached)>,
393 diagnostics_notes: PluginFileDiagnosticNotesCached,
394}
395impl ModuleDataCached {
396 fn new(module_data: ModuleData, ctx: &mut DefCacheSavingContext<'_>) -> Self {
397 Self {
398 items: module_data.items.iter().map(|id| ModuleItemIdCached::new(*id, ctx)).collect(),
399 constants: module_data
400 .constants
401 .iter()
402 .map(|(id, node)| {
403 (ConstantIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
404 })
405 .collect(),
406
407 submodules: module_data
408 .submodules
409 .iter()
410 .map(|(id, node)| {
411 (SubmoduleIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
412 })
413 .collect(),
414
415 uses: module_data
416 .uses
417 .iter()
418 .map(|(id, node)| {
419 (UseIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
420 })
421 .collect(),
422 free_functions: module_data
423 .free_functions
424 .iter()
425 .map(|(id, node)| {
426 (
427 FreeFunctionIdCached::new(*id, ctx),
428 TypeSyntaxNodeCached::new(node.clone(), ctx),
429 )
430 })
431 .collect(),
432 structs: module_data
433 .structs
434 .iter()
435 .map(|(id, node)| {
436 (StructIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
437 })
438 .collect(),
439 enums: module_data
440 .enums
441 .iter()
442 .map(|(id, node)| {
443 (EnumIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
444 })
445 .collect(),
446 type_aliases: module_data
447 .type_aliases
448 .iter()
449 .map(|(id, node)| {
450 (
451 ModuleTypeAliasIdCached::new(*id, ctx),
452 TypeSyntaxNodeCached::new(node.clone(), ctx),
453 )
454 })
455 .collect(),
456 impl_aliases: module_data
457 .impl_aliases
458 .iter()
459 .map(|(id, node)| {
460 (ImplAliasIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
461 })
462 .collect(),
463 traits: module_data
464 .traits
465 .iter()
466 .map(|(id, node)| {
467 (TraitIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
468 })
469 .collect(),
470 impls: module_data
471 .impls
472 .iter()
473 .map(|(id, node)| {
474 (ImplDefIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
475 })
476 .collect(),
477 extern_types: module_data
478 .extern_types
479 .iter()
480 .map(|(id, node)| {
481 (
482 ExternTypeIdCached::new(*id, ctx),
483 TypeSyntaxNodeCached::new(node.clone(), ctx),
484 )
485 })
486 .collect(),
487 extern_functions: module_data
488 .extern_functions
489 .iter()
490 .map(|(id, node)| {
491 (
492 ExternFunctionIdCached::new(*id, ctx),
493 TypeSyntaxNodeCached::new(node.clone(), ctx),
494 )
495 })
496 .collect(),
497
498 macro_declarations: module_data
499 .macro_declarations
500 .iter()
501 .map(|(id, node)| {
502 (
503 MacroDeclarationIdCached::new(*id, ctx),
504 TypeSyntaxNodeCached::new(node.clone(), ctx),
505 )
506 })
507 .collect(),
508 global_uses: module_data
509 .global_uses
510 .iter()
511 .map(|(id, node)| {
512 (GlobalUseIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
513 })
514 .collect(),
515 files: module_data.files.iter().map(|id| FileIdCached::new(*id, ctx)).collect(),
516 generated_file_aux_data: module_data.generated_file_aux_data.to_vec(),
517
518 plugin_diagnostics: module_data
519 .plugin_diagnostics
520 .iter()
521 .map(|(file_id, diagnostic)| {
522 (
523 ModuleFileCached::new(*file_id, ctx),
524 PluginDiagnosticCached::new(diagnostic, ctx),
525 )
526 })
527 .collect(),
528 diagnostics_notes: module_data
529 .diagnostics_notes
530 .iter()
531 .map(|(filed_id, note)| {
532 (
533 FileIdCached::new(*filed_id, ctx),
534 DiagnosticNoteCached::new(note.clone(), ctx),
535 )
536 })
537 .collect(),
538 }
539 }
540 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleData {
541 ModuleData {
542 items: self.items.iter().map(|id| id.embed(ctx)).collect(),
543 constants: Arc::new(
544 self.constants.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
545 ),
546 submodules: Arc::new(
547 self.submodules.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
548 ),
549 uses: Arc::new(
550 self.uses.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
551 ),
552 free_functions: Arc::new(
553 self.free_functions
554 .iter()
555 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
556 .collect(),
557 ),
558 structs: Arc::new(
559 self.structs.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
560 ),
561 enums: Arc::new(
562 self.enums.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
563 ),
564 type_aliases: Arc::new(
565 self.type_aliases
566 .iter()
567 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
568 .collect(),
569 ),
570 impl_aliases: Arc::new(
571 self.impl_aliases
572 .iter()
573 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
574 .collect(),
575 ),
576 traits: Arc::new(
577 self.traits.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
578 ),
579 impls: Arc::new(
580 self.impls.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
581 ),
582 extern_types: Arc::new(
583 self.extern_types
584 .iter()
585 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
586 .collect(),
587 ),
588 extern_functions: Arc::new(
589 self.extern_functions
590 .iter()
591 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
592 .collect(),
593 ),
594 macro_declarations: Arc::new(
595 self.macro_declarations
596 .iter()
597 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
598 .collect(),
599 ),
600 global_uses: Arc::new(
601 self.global_uses
602 .iter()
603 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
604 .collect(),
605 ),
606 files: self.files.iter().map(|id| id.embed(ctx)).collect(),
607
608 plugin_diagnostics: self
609 .plugin_diagnostics
610 .into_iter()
611 .map(|(file_id, diagnostic)| (file_id.embed(ctx), diagnostic.embed(ctx)))
612 .collect(),
613
614 diagnostics_notes: self
615 .diagnostics_notes
616 .into_iter()
617 .map(|(file_id, note)| (file_id.embed(ctx), note.embed(ctx)))
618 .collect(),
619
620 generated_file_aux_data: self.generated_file_aux_data.into(),
621 }
622 }
623}
624
625#[derive(Serialize, Deserialize, Default, PartialEq, Eq)]
627pub struct DefCacheLookups {
628 green_ids_lookup: Vec<GreenNodeCached>,
629 crate_ids_lookup: Vec<CrateCached>,
630 syntax_stable_ptr_ids_lookup: Vec<SyntaxStablePtrCached>,
631 submodule_ids_lookup: Vec<SubmoduleCached>,
632 constant_ids_lookup: Vec<ConstantCached>,
633 use_ids_lookup: Vec<UseCached>,
634 free_function_ids_lookup: Vec<FreeFunctionCached>,
635 struct_ids_lookup: Vec<StructCached>,
636 enum_ids_lookup: Vec<EnumCached>,
637 type_alias_ids_lookup: Vec<ModuleTypeAliasCached>,
638 impl_alias_ids_lookup: Vec<ImplAliasCached>,
639 trait_ids_lookup: Vec<TraitCached>,
640 impl_def_ids_lookup: Vec<ImplDefCached>,
641 extern_type_ids_lookup: Vec<ExternTypeCached>,
642 extern_function_ids_lookup: Vec<ExternFunctionCached>,
643 global_use_ids_lookup: Vec<GlobalUseCached>,
644 macro_declaration_ids_lookup: Vec<MacroDeclarationCached>,
645
646 file_ids_lookup: Vec<FileCached>,
647}
648
649#[derive(Serialize, Deserialize, Clone)]
650struct TypeSyntaxNodeCached<T: TypedSyntaxNode> {
651 syntax_node: SyntaxNodeCached,
652 _marker: std::marker::PhantomData<T>,
653}
654impl<T: TypedSyntaxNode> TypeSyntaxNodeCached<T> {
655 fn new(syntax_node: T, ctx: &mut DefCacheSavingContext<'_>) -> Self {
656 Self {
657 syntax_node: SyntaxNodeCached::new(syntax_node.as_syntax_node(), ctx),
658 _marker: std::marker::PhantomData,
659 }
660 }
661 fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> T {
662 T::from_syntax_node(ctx.db, self.syntax_node.embed(ctx))
663 }
664}
665
666#[derive(Serialize, Deserialize, Clone)]
667pub struct GenericParamCached {
668 language_element: LanguageElementCached,
669}
670impl GenericParamCached {
671 pub fn new(generic_param_id: GenericParamId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
672 Self { language_element: LanguageElementCached::new(generic_param_id, ctx) }
673 }
674
675 pub fn get_embedded(
676 self,
677 data: &Arc<DefCacheLoadingData>,
678 db: &dyn DefsGroup,
679 ) -> GenericParamId {
680 let (module_file_id, stable_ptr) = self.language_element.get_embedded(data);
681 GenericParamLongId(module_file_id, GenericParamPtr(stable_ptr)).intern(db)
682 }
683}
684
685#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
686struct ModuleFileCached {
687 module: ModuleIdCached,
688 file_index: usize,
689}
690impl ModuleFileCached {
691 fn new(module_file_id: ModuleFileId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
692 Self { module: ModuleIdCached::new(module_file_id.0, ctx), file_index: module_file_id.1.0 }
693 }
694 fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleFileId {
695 ModuleFileId(self.module.embed(ctx), FileIndex(self.file_index))
696 }
697 fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> ModuleFileId {
698 ModuleFileId(self.module.get_embedded(data), FileIndex(self.file_index))
699 }
700}
701
702#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
703pub enum ModuleIdCached {
704 CrateRoot(CrateIdCached),
705 Submodule(SubmoduleIdCached),
706}
707impl ModuleIdCached {
708 fn new(module_id: ModuleId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
709 match module_id {
710 ModuleId::CrateRoot(crate_id) => {
711 ModuleIdCached::CrateRoot(CrateIdCached::new(crate_id, ctx))
712 }
713 ModuleId::Submodule(submodule_id) => {
714 ModuleIdCached::Submodule(SubmoduleIdCached::new(submodule_id, ctx))
715 }
716 }
717 }
718 fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleId {
719 match self {
720 ModuleIdCached::CrateRoot(crate_id) => ModuleId::CrateRoot(crate_id.embed(ctx)),
721 ModuleIdCached::Submodule(submodule_id) => ModuleId::Submodule(submodule_id.embed(ctx)),
722 }
723 }
724 fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> ModuleId {
725 match self {
726 ModuleIdCached::CrateRoot(crate_id) => ModuleId::CrateRoot(crate_id.get_embedded(data)),
727 ModuleIdCached::Submodule(submodule_id) => {
728 ModuleId::Submodule(submodule_id.get_embedded(data))
729 }
730 }
731 }
732}
733
734#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
735enum CrateCached {
736 Real { name: SmolStr, discriminator: Option<SmolStr> },
737 Virtual { name: SmolStr, file_id: FileIdCached, settings: String },
738}
739impl CrateCached {
740 fn new(crate_id: CrateLongId, _ctx: &mut DefCacheSavingContext<'_>) -> Self {
741 match crate_id {
742 CrateLongId::Real { name, discriminator } => CrateCached::Real { name, discriminator },
743 CrateLongId::Virtual { name, file_id, settings, cache_file: _ } => {
744 CrateCached::Virtual { name, file_id: FileIdCached::new(file_id, _ctx), settings }
745 }
746 }
747 }
748 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> CrateLongId {
749 match self {
750 CrateCached::Real { name, discriminator } => CrateLongId::Real { name, discriminator },
751 CrateCached::Virtual { name, file_id, settings } => {
752 CrateLongId::Virtual {
753 name,
754 file_id: file_id.embed(ctx),
755 settings,
756 cache_file: None, }
758 }
759 }
760 }
761}
762#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
763pub enum CrateIdCached {
764 SelfCrate,
765 Other(usize),
766}
767impl CrateIdCached {
768 fn new(crate_id: CrateId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
769 if crate_id == ctx.self_crate_id {
770 return CrateIdCached::SelfCrate;
771 }
772 if let Some(id) = ctx.crate_ids.get(&crate_id) {
773 return *id;
774 }
775 let crate_long_id = CrateCached::new(crate_id.lookup_intern(ctx.db), ctx);
776 let id = CrateIdCached::Other(ctx.crate_ids_lookup.len());
777 ctx.crate_ids_lookup.push(crate_long_id);
778 ctx.crate_ids.insert(crate_id, id);
779 id
780 }
781 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> CrateId {
782 let CrateIdCached::Other(id) = self else {
783 return ctx.self_crate_id;
784 };
785
786 if let Some(crate_id) = ctx.crate_ids.get(&self) {
787 return *crate_id;
788 }
789 let crate_long_id = ctx.crate_ids_lookup[id].clone();
790 let crate_id = crate_long_id.embed(ctx).intern(ctx.db);
791 ctx.data.crate_ids.insert(self, crate_id);
792 crate_id
793 }
794 fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> CrateId {
795 let CrateIdCached::Other(_) = self else {
796 return data.self_crate_id;
797 };
798 data.crate_ids[&self]
799 }
800}
801
802#[derive(Serialize, Deserialize, Copy, Clone)]
803enum ModuleItemIdCached {
804 Constant(ConstantIdCached),
805 Submodule(SubmoduleIdCached),
806 Use(UseIdCached),
807 FreeFunction(FreeFunctionIdCached),
808 Struct(StructIdCached),
809 Enum(EnumIdCached),
810 TypeAlias(ModuleTypeAliasIdCached),
811 ImplAlias(ImplAliasIdCached),
812 Trait(TraitIdCached),
813 Impl(ImplDefIdCached),
814 ExternType(ExternTypeIdCached),
815 ExternFunction(ExternFunctionIdCached),
816 MacroDeclaration(MacroDeclarationIdCached),
817}
818
819impl ModuleItemIdCached {
820 fn new(module_item_id: ModuleItemId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
821 match module_item_id {
822 ModuleItemId::Constant(constant_id) => {
823 ModuleItemIdCached::Constant(ConstantIdCached::new(constant_id, ctx))
824 }
825 ModuleItemId::Submodule(submodule_id) => {
826 ModuleItemIdCached::Submodule(SubmoduleIdCached::new(submodule_id, ctx))
827 }
828 ModuleItemId::Use(use_id) => ModuleItemIdCached::Use(UseIdCached::new(use_id, ctx)),
829 ModuleItemId::FreeFunction(free_function_id) => {
830 ModuleItemIdCached::FreeFunction(FreeFunctionIdCached::new(free_function_id, ctx))
831 }
832 ModuleItemId::Struct(struct_id) => {
833 ModuleItemIdCached::Struct(StructIdCached::new(struct_id, ctx))
834 }
835 ModuleItemId::Enum(enum_id) => {
836 ModuleItemIdCached::Enum(EnumIdCached::new(enum_id, ctx))
837 }
838 ModuleItemId::TypeAlias(type_alias_id) => {
839 ModuleItemIdCached::TypeAlias(ModuleTypeAliasIdCached::new(type_alias_id, ctx))
840 }
841 ModuleItemId::ImplAlias(impl_alias_id) => {
842 ModuleItemIdCached::ImplAlias(ImplAliasIdCached::new(impl_alias_id, ctx))
843 }
844 ModuleItemId::Trait(trait_id) => {
845 ModuleItemIdCached::Trait(TraitIdCached::new(trait_id, ctx))
846 }
847 ModuleItemId::Impl(impl_def_id) => {
848 ModuleItemIdCached::Impl(ImplDefIdCached::new(impl_def_id, ctx))
849 }
850 ModuleItemId::ExternType(extern_type_id) => {
851 ModuleItemIdCached::ExternType(ExternTypeIdCached::new(extern_type_id, ctx))
852 }
853 ModuleItemId::ExternFunction(extern_function_id) => ModuleItemIdCached::ExternFunction(
854 ExternFunctionIdCached::new(extern_function_id, ctx),
855 ),
856 ModuleItemId::MacroDeclaration(macro_declaration_id) => {
857 ModuleItemIdCached::MacroDeclaration(MacroDeclarationIdCached::new(
858 macro_declaration_id,
859 ctx,
860 ))
861 }
862 }
863 }
864 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleItemId {
865 match self {
866 ModuleItemIdCached::Constant(constant_id) => {
867 ModuleItemId::Constant(constant_id.embed(ctx))
868 }
869 ModuleItemIdCached::Submodule(submodule_id) => {
870 ModuleItemId::Submodule(submodule_id.embed(ctx))
871 }
872 ModuleItemIdCached::Use(use_id) => ModuleItemId::Use(use_id.embed(ctx)),
873 ModuleItemIdCached::FreeFunction(free_function_id) => {
874 ModuleItemId::FreeFunction(free_function_id.embed(ctx))
875 }
876 ModuleItemIdCached::Struct(struct_id) => ModuleItemId::Struct(struct_id.embed(ctx)),
877 ModuleItemIdCached::Enum(enum_id) => ModuleItemId::Enum(enum_id.embed(ctx)),
878 ModuleItemIdCached::TypeAlias(type_alias_id) => {
879 ModuleItemId::TypeAlias(type_alias_id.embed(ctx))
880 }
881 ModuleItemIdCached::ImplAlias(impl_alias_id) => {
882 ModuleItemId::ImplAlias(impl_alias_id.embed(ctx))
883 }
884 ModuleItemIdCached::Trait(trait_id) => ModuleItemId::Trait(trait_id.embed(ctx)),
885 ModuleItemIdCached::Impl(impl_def_id) => ModuleItemId::Impl(impl_def_id.embed(ctx)),
886 ModuleItemIdCached::ExternType(extern_type_id) => {
887 ModuleItemId::ExternType(extern_type_id.embed(ctx))
888 }
889 ModuleItemIdCached::ExternFunction(extern_function_id) => {
890 ModuleItemId::ExternFunction(extern_function_id.embed(ctx))
891 }
892 ModuleItemIdCached::MacroDeclaration(macro_declaration_id) => {
893 ModuleItemId::MacroDeclaration(macro_declaration_id.embed(ctx))
894 }
895 }
896 }
897}
898
899#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
900struct ConstantCached {
901 language_element: LanguageElementCached,
902}
903impl ConstantCached {
904 fn new(constant_id: ConstantLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
905 Self { language_element: LanguageElementCached::new(constant_id.intern(ctx.db), ctx) }
906 }
907 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ConstantLongId {
908 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
909
910 ConstantLongId(module_file_id, ItemConstantPtr(stable_ptr))
911 }
912}
913
914#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
915struct ConstantIdCached(usize);
916
917impl ConstantIdCached {
918 fn new(constant_id: ConstantId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
919 if let Some(id) = ctx.constant_ids.get(&constant_id) {
920 return *id;
921 }
922 let constant = ConstantCached::new(constant_id.lookup_intern(ctx.db), ctx);
923 let id = ConstantIdCached(ctx.constant_ids_lookup.len());
924 ctx.constant_ids_lookup.push(constant);
925 ctx.constant_ids.insert(constant_id, id);
926 id
927 }
928 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ConstantId {
929 if let Some(constant_id) = ctx.constant_ids.get(&self) {
930 return *constant_id;
931 }
932 let constant = ctx.constant_ids_lookup[self.0].clone();
933 let constant = constant.embed(ctx).intern(ctx.db);
934 ctx.constant_ids.insert(self, constant);
935 constant
936 }
937}
938
939#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
940struct SubmoduleCached {
941 language_element: LanguageElementCached,
942}
943impl SubmoduleCached {
944 fn new(submodule_id: SubmoduleLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
945 Self { language_element: LanguageElementCached::new(submodule_id.intern(ctx.db), ctx) }
946 }
947 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SubmoduleLongId {
948 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
949
950 SubmoduleLongId(module_file_id, ItemModulePtr(stable_ptr))
951 }
952}
953
954#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
955pub struct SubmoduleIdCached(usize);
956
957impl SubmoduleIdCached {
958 fn new(submodule_id: SubmoduleId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
959 if let Some(id) = ctx.submodule_ids.get(&submodule_id) {
960 return *id;
961 }
962 let submodule = SubmoduleCached::new(submodule_id.lookup_intern(ctx.db), ctx);
963 let id = SubmoduleIdCached(ctx.submodule_ids_lookup.len());
964 ctx.submodule_ids_lookup.push(submodule);
965 ctx.submodule_ids.insert(submodule_id, id);
966 id
967 }
968 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SubmoduleId {
969 if let Some(submodule_id) = ctx.submodule_ids.get(&self) {
970 return *submodule_id;
971 }
972 let submodule = ctx.submodule_ids_lookup[self.0].clone();
973 let submodule = submodule.embed(ctx).intern(ctx.db);
974 ctx.submodule_ids.insert(self, submodule);
975 submodule
976 }
977 fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> SubmoduleId {
978 data.submodule_ids[&self]
979 }
980}
981
982#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
983struct UseCached {
984 language_element: LanguageElementCached,
985}
986impl UseCached {
987 fn new(use_id: UseLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
988 Self { language_element: LanguageElementCached::new(use_id.intern(ctx.db), ctx) }
989 }
990 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> UseLongId {
991 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
992
993 UseLongId(module_file_id, UsePathLeafPtr(stable_ptr))
994 }
995}
996
997#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
998struct UseIdCached(usize);
999
1000impl UseIdCached {
1001 fn new(use_id: UseId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1002 if let Some(id) = ctx.use_ids.get(&use_id) {
1003 return *id;
1004 }
1005 let use_cache = UseCached::new(use_id.lookup_intern(ctx.db), ctx);
1006 let id = UseIdCached(ctx.use_ids_lookup.len());
1007 ctx.use_ids_lookup.push(use_cache);
1008 ctx.use_ids.insert(use_id, id);
1009 id
1010 }
1011 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> UseId {
1012 if let Some(use_id) = ctx.use_ids.get(&self) {
1013 return *use_id;
1014 }
1015 let use_cached = ctx.use_ids_lookup[self.0].clone();
1016 let use_cached = use_cached.embed(ctx).intern(ctx.db);
1017 ctx.use_ids.insert(self, use_cached);
1018 use_cached
1019 }
1020}
1021
1022#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1023struct FreeFunctionCached {
1024 language_element: LanguageElementCached,
1025}
1026impl FreeFunctionCached {
1027 fn new(free_function_id: FreeFunctionLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1028 Self { language_element: LanguageElementCached::new(free_function_id.intern(ctx.db), ctx) }
1029 }
1030 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FreeFunctionLongId {
1031 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1032
1033 FreeFunctionLongId(module_file_id, FunctionWithBodyPtr(stable_ptr))
1034 }
1035}
1036
1037#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1038struct FreeFunctionIdCached(usize);
1039
1040impl FreeFunctionIdCached {
1041 fn new(free_function_id: FreeFunctionId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1042 if let Some(id) = ctx.free_function_ids.get(&free_function_id) {
1043 return *id;
1044 }
1045 let free_function = FreeFunctionCached::new(free_function_id.lookup_intern(ctx.db), ctx);
1046 let id = FreeFunctionIdCached(ctx.free_function_ids_lookup.len());
1047 ctx.free_function_ids_lookup.push(free_function);
1048 ctx.free_function_ids.insert(free_function_id, id);
1049 id
1050 }
1051 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FreeFunctionId {
1052 if let Some(free_function_id) = ctx.free_function_ids.get(&self) {
1053 return *free_function_id;
1054 }
1055 let free_function = ctx.free_function_ids_lookup[self.0].clone();
1056 let free_function = free_function.embed(ctx).intern(ctx.db);
1057 ctx.free_function_ids.insert(self, free_function);
1058 free_function
1059 }
1060}
1061
1062#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1063struct StructCached {
1064 language_element: LanguageElementCached,
1065}
1066impl StructCached {
1067 fn new(struct_id: StructLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1068 Self { language_element: LanguageElementCached::new(struct_id.intern(ctx.db), ctx) }
1069 }
1070 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> StructLongId {
1071 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1072
1073 StructLongId(module_file_id, ItemStructPtr(stable_ptr))
1074 }
1075}
1076
1077#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1078struct StructIdCached(usize);
1079
1080impl StructIdCached {
1081 fn new(struct_id: StructId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1082 if let Some(id) = ctx.struct_ids.get(&struct_id) {
1083 return *id;
1084 }
1085 let struct_cached = StructCached::new(struct_id.lookup_intern(ctx.db), ctx);
1086 let id = StructIdCached(ctx.struct_ids_lookup.len());
1087 ctx.struct_ids_lookup.push(struct_cached);
1088 ctx.struct_ids.insert(struct_id, id);
1089 id
1090 }
1091 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> StructId {
1092 if let Some(struct_id) = ctx.struct_ids.get(&self) {
1093 return *struct_id;
1094 }
1095 let struct_cached = ctx.struct_ids_lookup[self.0].clone();
1096 let struct_cached = struct_cached.embed(ctx).intern(ctx.db);
1097 ctx.struct_ids.insert(self, struct_cached);
1098 struct_cached
1099 }
1100}
1101
1102#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1103struct EnumCached {
1104 language_element: LanguageElementCached,
1105}
1106impl EnumCached {
1107 fn new(enum_id: EnumLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1108 Self { language_element: LanguageElementCached::new(enum_id.intern(ctx.db), ctx) }
1109 }
1110 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> EnumLongId {
1111 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1112
1113 EnumLongId(module_file_id, ItemEnumPtr(stable_ptr))
1114 }
1115}
1116
1117#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1118struct EnumIdCached(usize);
1119
1120impl EnumIdCached {
1121 fn new(enum_id: EnumId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1122 if let Some(id) = ctx.enum_ids.get(&enum_id) {
1123 return *id;
1124 }
1125 let enum_cached = EnumCached::new(enum_id.lookup_intern(ctx.db), ctx);
1126 let id = EnumIdCached(ctx.enum_ids_lookup.len());
1127 ctx.enum_ids_lookup.push(enum_cached);
1128 ctx.enum_ids.insert(enum_id, id);
1129 id
1130 }
1131 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> EnumId {
1132 if let Some(enum_id) = ctx.enum_ids.get(&self) {
1133 return *enum_id;
1134 }
1135 let enum_cached = ctx.enum_ids_lookup[self.0].clone();
1136 let enum_cached = enum_cached.embed(ctx).intern(ctx.db);
1137 ctx.enum_ids.insert(self, enum_cached);
1138 enum_cached
1139 }
1140}
1141
1142#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1143struct ModuleTypeAliasCached {
1144 language_element: LanguageElementCached,
1145}
1146impl ModuleTypeAliasCached {
1147 fn new(type_alias_id: ModuleTypeAliasLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1148 Self { language_element: LanguageElementCached::new(type_alias_id.intern(ctx.db), ctx) }
1149 }
1150 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleTypeAliasLongId {
1151 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1152
1153 ModuleTypeAliasLongId(module_file_id, ItemTypeAliasPtr(stable_ptr))
1154 }
1155}
1156
1157#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1158struct ModuleTypeAliasIdCached(usize);
1159
1160impl ModuleTypeAliasIdCached {
1161 fn new(type_alias_id: ModuleTypeAliasId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1162 if let Some(id) = ctx.type_alias_ids.get(&type_alias_id) {
1163 return *id;
1164 }
1165 let type_alias = ModuleTypeAliasCached::new(type_alias_id.lookup_intern(ctx.db), ctx);
1166 let id = ModuleTypeAliasIdCached(ctx.type_alias_ids_lookup.len());
1167 ctx.type_alias_ids_lookup.push(type_alias);
1168 ctx.type_alias_ids.insert(type_alias_id, id);
1169 id
1170 }
1171 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleTypeAliasId {
1172 if let Some(type_alias_id) = ctx.type_alias_ids.get(&self) {
1173 return *type_alias_id;
1174 }
1175 let type_alias = ctx.type_alias_ids_lookup[self.0].clone();
1176 let type_alias = type_alias.embed(ctx).intern(ctx.db);
1177 ctx.type_alias_ids.insert(self, type_alias);
1178 type_alias
1179 }
1180}
1181
1182#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1183struct ImplAliasCached {
1184 language_element: LanguageElementCached,
1185}
1186impl ImplAliasCached {
1187 fn new(impl_alias_id: ImplAliasLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1188 Self { language_element: LanguageElementCached::new(impl_alias_id.intern(ctx.db), ctx) }
1189 }
1190 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplAliasLongId {
1191 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1192
1193 ImplAliasLongId(module_file_id, ItemImplAliasPtr(stable_ptr))
1194 }
1195}
1196
1197#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1198struct ImplAliasIdCached(usize);
1199
1200impl ImplAliasIdCached {
1201 fn new(impl_alias_id: ImplAliasId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1202 if let Some(id) = ctx.impl_alias_ids.get(&impl_alias_id) {
1203 return *id;
1204 }
1205 let impl_alias = ImplAliasCached::new(impl_alias_id.lookup_intern(ctx.db), ctx);
1206 let id = ImplAliasIdCached(ctx.impl_alias_ids_lookup.len());
1207 ctx.impl_alias_ids_lookup.push(impl_alias);
1208 ctx.impl_alias_ids.insert(impl_alias_id, id);
1209 id
1210 }
1211 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplAliasId {
1212 if let Some(impl_alias_id) = ctx.impl_alias_ids.get(&self) {
1213 return *impl_alias_id;
1214 }
1215 let impl_alias = ctx.impl_alias_ids_lookup[self.0].clone();
1216 let impl_alias = impl_alias.embed(ctx).intern(ctx.db);
1217 ctx.impl_alias_ids.insert(self, impl_alias);
1218 impl_alias
1219 }
1220}
1221
1222#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1223struct TraitCached {
1224 language_element: LanguageElementCached,
1225}
1226impl TraitCached {
1227 fn new(trait_id: TraitLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1228 Self { language_element: LanguageElementCached::new(trait_id.intern(ctx.db), ctx) }
1229 }
1230 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> TraitLongId {
1231 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1232
1233 TraitLongId(module_file_id, ItemTraitPtr(stable_ptr))
1234 }
1235}
1236
1237#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1238struct TraitIdCached(usize);
1239
1240impl TraitIdCached {
1241 fn new(trait_id: TraitId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1242 if let Some(id) = ctx.trait_ids.get(&trait_id) {
1243 return *id;
1244 }
1245 let trait_cached = TraitCached::new(trait_id.lookup_intern(ctx.db), ctx);
1246 let id = TraitIdCached(ctx.trait_ids_lookup.len());
1247 ctx.trait_ids_lookup.push(trait_cached);
1248 ctx.trait_ids.insert(trait_id, id);
1249 id
1250 }
1251 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> TraitId {
1252 if let Some(trait_id) = ctx.trait_ids.get(&self) {
1253 return *trait_id;
1254 }
1255 let trait_cached = ctx.trait_ids_lookup[self.0].clone();
1256 let trait_cached = trait_cached.embed(ctx).intern(ctx.db);
1257 ctx.trait_ids.insert(self, trait_cached);
1258 trait_cached
1259 }
1260}
1261
1262#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1263struct ImplDefCached {
1264 language_element: LanguageElementCached,
1265}
1266impl ImplDefCached {
1267 fn new(impl_def_id: ImplDefLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1268 Self { language_element: LanguageElementCached::new(impl_def_id.intern(ctx.db), ctx) }
1269 }
1270 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplDefLongId {
1271 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1272
1273 ImplDefLongId(module_file_id, ItemImplPtr(stable_ptr))
1274 }
1275}
1276
1277#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1278pub struct ImplDefIdCached(usize);
1279
1280impl ImplDefIdCached {
1281 pub fn new(impl_def_id: ImplDefId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1282 if let Some(id) = ctx.impl_def_ids.get(&impl_def_id) {
1283 return *id;
1284 }
1285 let impl_def = ImplDefCached::new(impl_def_id.lookup_intern(ctx.db), ctx);
1286 let id = ImplDefIdCached(ctx.impl_def_ids_lookup.len());
1287 ctx.impl_def_ids_lookup.push(impl_def);
1288 ctx.impl_def_ids.insert(impl_def_id, id);
1289 id
1290 }
1291
1292 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplDefId {
1293 if let Some(impl_def_id) = ctx.impl_def_ids.get(&self) {
1294 return *impl_def_id;
1295 }
1296 let impl_def = ctx.impl_def_ids_lookup[self.0].clone();
1297 let impl_def = impl_def.embed(ctx).intern(ctx.db);
1298 ctx.impl_def_ids.insert(self, impl_def);
1299 impl_def
1300 }
1301
1302 pub fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> ImplDefId {
1303 data.impl_def_ids[&self]
1304 }
1305}
1306
1307#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1308struct ExternTypeCached {
1309 language_element: LanguageElementCached,
1310}
1311impl ExternTypeCached {
1312 fn new(extern_type_id: ExternTypeLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1313 Self { language_element: LanguageElementCached::new(extern_type_id.intern(ctx.db), ctx) }
1314 }
1315 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternTypeLongId {
1316 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1317
1318 ExternTypeLongId(module_file_id, ItemExternTypePtr(stable_ptr))
1319 }
1320}
1321
1322#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1323struct ExternTypeIdCached(usize);
1324
1325impl ExternTypeIdCached {
1326 fn new(extern_type_id: ExternTypeId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1327 if let Some(id) = ctx.extern_type_ids.get(&extern_type_id) {
1328 return *id;
1329 }
1330 let extern_type = ExternTypeCached::new(extern_type_id.lookup_intern(ctx.db), ctx);
1331 let id = ExternTypeIdCached(ctx.extern_type_ids_lookup.len());
1332 ctx.extern_type_ids_lookup.push(extern_type);
1333 ctx.extern_type_ids.insert(extern_type_id, id);
1334 id
1335 }
1336 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternTypeId {
1337 if let Some(extern_type_id) = ctx.extern_type_ids.get(&self) {
1338 return *extern_type_id;
1339 }
1340 let extern_type = ctx.extern_type_ids_lookup[self.0].clone();
1341 let extern_type = extern_type.embed(ctx).intern(ctx.db);
1342 ctx.extern_type_ids.insert(self, extern_type);
1343 extern_type
1344 }
1345}
1346
1347#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1348struct ExternFunctionCached {
1349 language_element: LanguageElementCached,
1350}
1351impl ExternFunctionCached {
1352 fn new(extern_function_id: ExternFunctionLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1353 Self {
1354 language_element: LanguageElementCached::new(extern_function_id.intern(ctx.db), ctx),
1355 }
1356 }
1357 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternFunctionLongId {
1358 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1359
1360 ExternFunctionLongId(module_file_id, ItemExternFunctionPtr(stable_ptr))
1361 }
1362}
1363
1364#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1365struct ExternFunctionIdCached(usize);
1366
1367impl ExternFunctionIdCached {
1368 fn new(extern_function_id: ExternFunctionId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1369 if let Some(id) = ctx.extern_function_ids.get(&extern_function_id) {
1370 return *id;
1371 }
1372 let extern_function =
1373 ExternFunctionCached::new(extern_function_id.lookup_intern(ctx.db), ctx);
1374 let id = ExternFunctionIdCached(ctx.extern_function_ids_lookup.len());
1375 ctx.extern_function_ids_lookup.push(extern_function);
1376 ctx.extern_function_ids.insert(extern_function_id, id);
1377 id
1378 }
1379 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternFunctionId {
1380 if let Some(extern_function_id) = ctx.extern_function_ids.get(&self) {
1381 return *extern_function_id;
1382 }
1383 let extern_function = ctx.extern_function_ids_lookup[self.0].clone();
1384 let extern_function = extern_function.embed(ctx).intern(ctx.db);
1385 ctx.extern_function_ids.insert(self, extern_function);
1386 extern_function
1387 }
1388}
1389#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1390struct MacroDeclarationCached {
1391 language_element: LanguageElementCached,
1392}
1393
1394impl MacroDeclarationCached {
1395 fn new(
1396 macro_declaration_id: MacroDeclarationLongId,
1397 ctx: &mut DefCacheSavingContext<'_>,
1398 ) -> Self {
1399 Self {
1400 language_element: LanguageElementCached::new(macro_declaration_id.intern(ctx.db), ctx),
1401 }
1402 }
1403 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> MacroDeclarationLongId {
1404 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1405
1406 MacroDeclarationLongId(module_file_id, ItemMacroDeclarationPtr(stable_ptr))
1407 }
1408}
1409
1410#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1411struct MacroDeclarationIdCached(usize);
1412
1413impl MacroDeclarationIdCached {
1414 fn new(macro_declaration_id: MacroDeclarationId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1415 if let Some(id) = ctx.macro_declaration_ids.get(¯o_declaration_id) {
1416 return *id;
1417 }
1418 let macro_declaration =
1419 MacroDeclarationCached::new(macro_declaration_id.lookup_intern(ctx.db), ctx);
1420 let id = MacroDeclarationIdCached(ctx.macro_declaration_ids_lookup.len());
1421 ctx.macro_declaration_ids_lookup.push(macro_declaration);
1422 ctx.macro_declaration_ids.insert(macro_declaration_id, id);
1423 id
1424 }
1425 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> MacroDeclarationId {
1426 if let Some(macro_declaration_id) = ctx.macro_declaration_ids.get(&self) {
1427 return *macro_declaration_id;
1428 }
1429 let macro_declaration = ctx.macro_declaration_ids_lookup[self.0].clone();
1430 let macro_declaration = macro_declaration.embed(ctx).intern(ctx.db);
1431 ctx.macro_declaration_ids.insert(self, macro_declaration);
1432 macro_declaration
1433 }
1434}
1435
1436#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1437struct GlobalUseCached {
1438 language_element: LanguageElementCached,
1439}
1440impl GlobalUseCached {
1441 fn new(global_use_id: GlobalUseLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1442 Self { language_element: LanguageElementCached::new(global_use_id.intern(ctx.db), ctx) }
1443 }
1444 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> GlobalUseLongId {
1445 let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1446
1447 GlobalUseLongId(module_file_id, UsePathStarPtr(stable_ptr))
1448 }
1449}
1450
1451#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1452struct GlobalUseIdCached(usize);
1453
1454impl GlobalUseIdCached {
1455 fn new(global_use_id: GlobalUseId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1456 if let Some(id) = ctx.global_use_ids.get(&global_use_id) {
1457 return *id;
1458 }
1459 let global_use = GlobalUseCached::new(global_use_id.lookup_intern(ctx.db), ctx);
1460 let id = GlobalUseIdCached(ctx.global_use_ids_lookup.len());
1461 ctx.global_use_ids_lookup.push(global_use);
1462 ctx.global_use_ids.insert(global_use_id, id);
1463 id
1464 }
1465 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> GlobalUseId {
1466 if let Some(global_use_id) = ctx.global_use_ids.get(&self) {
1467 return *global_use_id;
1468 }
1469 let global_use = ctx.global_use_ids_lookup[self.0].clone();
1470 let global_use = global_use.embed(ctx).intern(ctx.db);
1471 ctx.global_use_ids.insert(self, global_use);
1472 global_use
1473 }
1474}
1475
1476#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
1477struct SyntaxNodeCached(Box<SyntaxNodeInnerCached>);
1478
1479#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
1480struct SyntaxNodeInnerCached {
1481 green: GreenIdCached,
1482 offset: TextOffset,
1483 parent: Option<SyntaxNodeCached>,
1484 stable_ptr: SyntaxStablePtrIdCached,
1485}
1486
1487impl SyntaxNodeCached {
1488 fn new(syntax_node: SyntaxNode, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1489 let db = ctx.db;
1490 let green = GreenIdCached::new(syntax_node.green_node(db).intern(db), ctx);
1491 let parent = syntax_node.parent(db).map(|it| Self::new(it, ctx));
1492 let stable_ptr = SyntaxStablePtrIdCached::new(syntax_node.stable_ptr(db), ctx);
1493 let offset = syntax_node.offset(db);
1494 let inner = SyntaxNodeInnerCached { green, offset, parent, stable_ptr };
1495 SyntaxNodeCached(Box::new(inner))
1496 }
1497 fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> SyntaxNode {
1498 let inner = self.0.as_ref();
1499 let green = inner.green.embed(ctx);
1500 let parent = inner.parent.as_ref().map(|it| it.embed(ctx));
1501 let stable_ptr = inner.stable_ptr.embed(ctx);
1502 let offset = inner.offset;
1503 SyntaxNode::new_with_inner(ctx.db, green, offset, parent, stable_ptr)
1504 }
1505}
1506
1507#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
1508pub struct LanguageElementCached {
1509 module_file_id: ModuleFileCached,
1510 stable_ptr: SyntaxStablePtrIdCached,
1511}
1512impl LanguageElementCached {
1513 pub fn new<T: LanguageElementId>(
1514 language_element: T,
1515 ctx: &mut DefCacheSavingContext<'_>,
1516 ) -> Self {
1517 Self {
1518 module_file_id: ModuleFileCached::new(language_element.module_file_id(ctx.db), ctx),
1519 stable_ptr: SyntaxStablePtrIdCached::new(
1520 language_element.untyped_stable_ptr(ctx.db),
1521 ctx,
1522 ),
1523 }
1524 }
1525 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> (ModuleFileId, SyntaxStablePtrId) {
1526 let module_file_id = self.module_file_id.embed(ctx);
1527 let stable_ptr = self.stable_ptr.embed(ctx);
1528 (module_file_id, stable_ptr)
1529 }
1530 pub fn get_embedded(
1531 self,
1532 data: &Arc<DefCacheLoadingData>,
1533 ) -> (ModuleFileId, SyntaxStablePtrId) {
1534 let module_file_id = self.module_file_id.get_embedded(data);
1535 let stable_ptr = self.stable_ptr.get_embedded(data);
1536 (module_file_id, stable_ptr)
1537 }
1538}
1539
1540#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1541enum SyntaxStablePtrCached {
1542 Root(FileIdCached, GreenIdCached),
1544 Child {
1546 parent: SyntaxStablePtrIdCached,
1548 kind: SyntaxKind,
1550 key_fields: Vec<GreenIdCached>,
1554 index: usize,
1556 },
1557}
1558
1559impl SyntaxStablePtrCached {
1560 fn new(syntax_stable_ptr: SyntaxStablePtr, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1561 match syntax_stable_ptr {
1562 SyntaxStablePtr::Root(root, green_id) => SyntaxStablePtrCached::Root(
1563 FileIdCached::new(root, ctx),
1564 GreenIdCached::new(green_id, ctx),
1565 ),
1566 SyntaxStablePtr::Child { parent, kind, key_fields, index } => {
1567 SyntaxStablePtrCached::Child {
1568 parent: SyntaxStablePtrIdCached::new(parent, ctx),
1569 kind,
1570 key_fields: key_fields
1571 .iter()
1572 .map(|field| GreenIdCached::new(*field, ctx))
1573 .collect(),
1574 index,
1575 }
1576 }
1577 }
1578 }
1579 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SyntaxStablePtr {
1580 match self {
1581 SyntaxStablePtrCached::Root(file, green_id) => {
1582 SyntaxStablePtr::Root(file.embed(ctx), green_id.embed(ctx))
1583 }
1584 SyntaxStablePtrCached::Child { parent, kind, key_fields, index } => {
1585 SyntaxStablePtr::Child {
1586 parent: parent.embed(ctx),
1587 kind,
1588 key_fields: key_fields.into_iter().map(|field| field.embed(ctx)).collect(),
1589 index,
1590 }
1591 }
1592 }
1593 }
1594}
1595
1596#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1597pub struct SyntaxStablePtrIdCached(usize);
1598impl SyntaxStablePtrIdCached {
1599 pub fn new(
1600 syntax_stable_ptr_id: SyntaxStablePtrId,
1601 ctx: &mut DefCacheSavingContext<'_>,
1602 ) -> Self {
1603 if let Some(id) = ctx.syntax_stable_ptr_ids.get(&syntax_stable_ptr_id) {
1604 return *id;
1605 }
1606 let stable_ptr =
1607 SyntaxStablePtrCached::new(syntax_stable_ptr_id.lookup_intern(ctx.db), ctx);
1608 let id = SyntaxStablePtrIdCached(ctx.syntax_stable_ptr_ids_lookup.len());
1609 ctx.syntax_stable_ptr_ids_lookup.push(stable_ptr);
1610 ctx.syntax_stable_ptr_ids.insert(syntax_stable_ptr_id, id);
1611 id
1612 }
1613 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SyntaxStablePtrId {
1614 if let Some(syntax_stable_ptr_id) = ctx.syntax_stable_ptr_ids.get(&self) {
1615 return *syntax_stable_ptr_id;
1616 }
1617 let stable_ptr = ctx.syntax_stable_ptr_ids_lookup[self.0].clone();
1618 let stable_ptr = stable_ptr.embed(ctx);
1619 let stable_ptr_id = stable_ptr.intern(ctx.db);
1620 ctx.syntax_stable_ptr_ids.insert(self, stable_ptr_id);
1621 stable_ptr_id
1622 }
1623 pub fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> SyntaxStablePtrId {
1624 data.syntax_stable_ptr_ids[&self]
1625 }
1626}
1627
1628#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1629enum GreenNodeDetailsCached {
1630 Token(SmolStr),
1631 Node { children: Vec<GreenIdCached>, width: TextWidth },
1632}
1633
1634impl GreenNodeDetailsCached {
1635 fn new(
1636 green_node_details: &GreenNodeDetails,
1637 ctx: &mut DefCacheSavingContext<'_>,
1638 ) -> GreenNodeDetailsCached {
1639 match green_node_details {
1640 GreenNodeDetails::Token(token) => GreenNodeDetailsCached::Token(token.clone()),
1641 GreenNodeDetails::Node { children, width } => GreenNodeDetailsCached::Node {
1642 children: children.iter().map(|child| GreenIdCached::new(*child, ctx)).collect(),
1643 width: *width,
1644 },
1645 }
1646 }
1647 fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> GreenNodeDetails {
1648 match self {
1649 GreenNodeDetailsCached::Token(token) => GreenNodeDetails::Token(token.clone()),
1650 GreenNodeDetailsCached::Node { children, width } => GreenNodeDetails::Node {
1651 children: children.iter().map(|child| child.embed(ctx)).collect(),
1652 width: *width,
1653 },
1654 }
1655 }
1656}
1657
1658#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1659struct GreenNodeCached {
1660 kind: SyntaxKind,
1661 details: GreenNodeDetailsCached,
1662}
1663impl GreenNodeCached {
1664 fn new(green_node: &GreenNode, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1665 Self {
1666 kind: green_node.kind,
1667 details: GreenNodeDetailsCached::new(&green_node.details, ctx),
1668 }
1669 }
1670 fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> GreenNode {
1671 GreenNode { kind: self.kind, details: self.details.embed(ctx) }
1672 }
1673}
1674
1675#[derive(Serialize, Deserialize, Clone, Copy, Eq, Hash, PartialEq)]
1676struct GreenIdCached(usize);
1677
1678impl GreenIdCached {
1679 fn new(green_id: GreenId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1680 if let Some(id) = ctx.green_ids.get(&green_id) {
1681 return *id;
1682 }
1683 let green_node = GreenNodeCached::new(green_id.lookup_intern(ctx.db).as_ref(), ctx);
1684 let id = GreenIdCached(ctx.green_ids_lookup.len());
1685 ctx.green_ids_lookup.push(green_node);
1686 ctx.green_ids.insert(green_id, id);
1687 id
1688 }
1689 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> GreenId {
1690 if let Some(green_id) = ctx.green_ids.get(&self) {
1691 return *green_id;
1692 }
1693 let green_node = ctx.green_ids_lookup[self.0].clone();
1694 let green_node = Arc::new(green_node.embed(ctx));
1695 let green_id = green_node.intern(ctx.db);
1696 ctx.green_ids.insert(self, green_id);
1697 green_id
1698 }
1699}
1700#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1701enum FileCached {
1702 OnDisk(PathBuf),
1703 Virtual(VirtualFileCached),
1704 External(PluginGeneratedFileCached),
1705}
1706
1707impl FileCached {
1708 fn new(file: &FileLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1709 match file {
1710 FileLongId::OnDisk(path) => FileCached::OnDisk(path.clone()),
1711 FileLongId::Virtual(virtual_file) => {
1712 FileCached::Virtual(VirtualFileCached::new(virtual_file, ctx))
1713 }
1714 FileLongId::External(external_file) => {
1715 FileCached::External(PluginGeneratedFileCached::new(
1716 PluginGeneratedFileId::from_intern_id(*external_file),
1717 ctx,
1718 ))
1719 }
1720 }
1721 }
1722 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FileLongId {
1723 match self {
1724 FileCached::OnDisk(path) => FileLongId::OnDisk(path),
1725 FileCached::Virtual(virtual_file) => FileLongId::Virtual(virtual_file.embed(ctx)),
1726 FileCached::External(external_file) => {
1727 FileLongId::External(external_file.embed(ctx).as_intern_id())
1728 }
1729 }
1730 }
1731}
1732
1733#[derive(Serialize, Deserialize, Clone, Copy, Eq, Hash, PartialEq)]
1734struct FileIdCached(usize);
1735impl FileIdCached {
1736 fn new(file_id: FileId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1737 if let Some(id) = ctx.file_ids.get(&file_id) {
1738 return *id;
1739 }
1740 let file = FileCached::new(&file_id.lookup_intern(ctx.db), ctx);
1741 let id = FileIdCached(ctx.file_ids_lookup.len());
1742 ctx.file_ids_lookup.push(file);
1743 ctx.file_ids.insert(file_id, id);
1744 id
1745 }
1746 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FileId {
1747 if let Some(file_id) = ctx.file_ids.get(&self) {
1748 return *file_id;
1749 }
1750 let file = ctx.file_ids_lookup[self.0].clone();
1751 let file = file.embed(ctx);
1752 let file_id = file.intern(ctx.db);
1753 ctx.file_ids.insert(self, file_id);
1754 file_id
1755 }
1756}
1757
1758#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1759struct VirtualFileCached {
1760 parent: Option<FileIdCached>,
1761 name: SmolStr,
1762 content: String,
1763 code_mappings: Vec<CodeMapping>,
1764 kind: FileKind,
1765 original_item_removed: bool,
1766}
1767
1768impl VirtualFileCached {
1769 fn new(virtual_file: &VirtualFile, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1770 Self {
1771 parent: virtual_file.parent.map(|parent| FileIdCached::new(parent, ctx)),
1772 name: virtual_file.name.clone(),
1773 content: String::from(&*(virtual_file.content)),
1774 code_mappings: virtual_file.code_mappings.to_vec(),
1775 kind: virtual_file.kind.clone(),
1776 original_item_removed: virtual_file.original_item_removed,
1777 }
1778 }
1779 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> VirtualFile {
1780 VirtualFile {
1781 parent: self.parent.map(|parent| parent.embed(ctx)),
1782 name: self.name,
1783 content: self.content.into(),
1784 code_mappings: self.code_mappings.into(),
1785 kind: self.kind,
1786 original_item_removed: self.original_item_removed,
1787 }
1788 }
1789}
1790
1791#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1792struct PluginGeneratedFileCached {
1793 module_id: ModuleIdCached,
1794 stable_ptr: SyntaxStablePtrIdCached,
1795 name: SmolStr,
1796}
1797
1798impl PluginGeneratedFileCached {
1799 fn new(
1800 plugin_generated_file: PluginGeneratedFileId,
1801 ctx: &mut DefCacheSavingContext<'_>,
1802 ) -> Self {
1803 let long_id = plugin_generated_file.lookup_intern(ctx.db);
1804 Self {
1805 module_id: ModuleIdCached::new(long_id.module_id, ctx),
1806 stable_ptr: SyntaxStablePtrIdCached::new(long_id.stable_ptr, ctx),
1807 name: long_id.name,
1808 }
1809 }
1810 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> PluginGeneratedFileId {
1811 let module_id = self.module_id.embed(ctx);
1812 let stable_ptr = self.stable_ptr.embed(ctx);
1813 let long_id = PluginGeneratedFileLongId { module_id, stable_ptr, name: self.name };
1814 long_id.intern(ctx.db)
1815 }
1816}
1817
1818#[derive(Serialize, Deserialize, Clone)]
1819enum SeverityCached {
1820 Error,
1821 Warning,
1822}
1823
1824#[derive(Serialize, Deserialize, Clone)]
1825struct PluginDiagnosticCached {
1826 stable_ptr: SyntaxStablePtrIdCached,
1827 message: String,
1828 severity: SeverityCached,
1829 inner_span: Option<(TextWidth, TextWidth)>,
1830}
1831
1832impl PluginDiagnosticCached {
1833 fn new(
1834 diagnostic: &PluginDiagnostic,
1835 ctx: &mut DefCacheSavingContext<'_>,
1836 ) -> PluginDiagnosticCached {
1837 PluginDiagnosticCached {
1838 stable_ptr: SyntaxStablePtrIdCached::new(diagnostic.stable_ptr, ctx),
1839 message: diagnostic.message.clone(),
1840 severity: match diagnostic.severity {
1841 Severity::Error => SeverityCached::Error,
1842 Severity::Warning => SeverityCached::Warning,
1843 },
1844 inner_span: diagnostic.inner_span,
1845 }
1846 }
1847 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> PluginDiagnostic {
1848 PluginDiagnostic {
1849 stable_ptr: self.stable_ptr.embed(ctx),
1850 message: self.message,
1851 severity: match self.severity {
1852 SeverityCached::Error => Severity::Error,
1853 SeverityCached::Warning => Severity::Warning,
1854 },
1855 inner_span: self.inner_span,
1856 }
1857 }
1858}
1859
1860type PluginFileDiagnosticNotesCached = OrderedHashMap<FileIdCached, DiagnosticNoteCached>;
1861
1862#[derive(Serialize, Deserialize, Clone)]
1863struct DiagnosticNoteCached {
1864 text: String,
1865 location: Option<DiagnosticLocationCached>,
1866}
1867
1868impl DiagnosticNoteCached {
1869 fn new(note: DiagnosticNote, ctx: &mut DefCacheSavingContext<'_>) -> DiagnosticNoteCached {
1870 DiagnosticNoteCached {
1871 text: note.text.clone(),
1872 location: note.location.map(|location| DiagnosticLocationCached::new(&location, ctx)),
1873 }
1874 }
1875 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> DiagnosticNote {
1876 DiagnosticNote {
1877 text: self.text,
1878 location: self.location.map(|location| location.embed(ctx)),
1879 }
1880 }
1881}
1882
1883#[derive(Serialize, Deserialize, Clone)]
1884struct DiagnosticLocationCached {
1885 file_id: FileIdCached,
1886 span: TextSpan,
1887}
1888
1889impl DiagnosticLocationCached {
1890 fn new(
1891 location: &DiagnosticLocation,
1892 ctx: &mut DefCacheSavingContext<'_>,
1893 ) -> DiagnosticLocationCached {
1894 DiagnosticLocationCached {
1895 file_id: FileIdCached::new(location.file_id, ctx),
1896 span: location.span,
1897 }
1898 }
1899 fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> DiagnosticLocation {
1900 DiagnosticLocation { file_id: self.file_id.embed(ctx), span: self.span }
1901 }
1902}