cairo_lang_defs/
diagnostic_utils.rs1use std::fmt;
2
3use cairo_lang_debug::DebugWithDb;
4use cairo_lang_diagnostics::DiagnosticLocation;
5use cairo_lang_filesystem::ids::FileId;
6use cairo_lang_filesystem::span::TextSpan;
7use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
8use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
9
10use crate::db::DefsGroup;
11
12#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
14pub struct StableLocation(SyntaxStablePtrId);
15impl StableLocation {
16 pub fn new(stable_ptr: SyntaxStablePtrId) -> Self {
17 Self(stable_ptr)
18 }
19
20 pub fn file_id(&self, db: &dyn DefsGroup) -> FileId {
21 self.0.file_id(db.upcast())
22 }
23
24 pub fn from_ast<TNode: TypedSyntaxNode>(node: &TNode) -> Self {
25 Self(node.as_syntax_node().stable_ptr())
26 }
27
28 pub fn syntax_node(&self, db: &dyn DefsGroup) -> SyntaxNode {
30 self.0.lookup(db.upcast())
31 }
32
33 pub fn stable_ptr(&self) -> SyntaxStablePtrId {
35 self.0
36 }
37
38 pub fn diagnostic_location(&self, db: &dyn DefsGroup) -> DiagnosticLocation {
40 let syntax_node = self.syntax_node(db);
41 DiagnosticLocation {
42 file_id: self.file_id(db),
43 span: syntax_node.span_without_trivia(db.upcast()),
44 }
45 }
46
47 pub fn diagnostic_location_until(
49 &self,
50 db: &dyn DefsGroup,
51 until_stable_ptr: SyntaxStablePtrId,
52 ) -> DiagnosticLocation {
53 let syntax_db = db.upcast();
54 let start = self.0.lookup(syntax_db).span_start_without_trivia(syntax_db);
55 let end = until_stable_ptr.lookup(syntax_db).span_end_without_trivia(syntax_db);
56 DiagnosticLocation { file_id: self.0.file_id(syntax_db), span: TextSpan { start, end } }
57 }
58}
59
60impl DebugWithDb<dyn DefsGroup> for StableLocation {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>, db: &dyn DefsGroup) -> fmt::Result {
62 let diag_location = self.diagnostic_location(db);
63 diag_location.fmt_location(f, db.upcast())
64 }
65}