microcad_lang/lower/ir/
source.rs1use crate::lower::ir;
7
8use microcad_lang_base::{
9 ComputedHash, Hashed, Identifier, LineCol, ResourceLocation, SourceLocInfo, SrcRef,
10 SrcReferrer, Url,
11};
12
13#[derive(Clone, Debug)]
15pub struct Source {
16 pub doc: Option<ir::DocBlock>,
18 pub name: ir::QualifiedName,
20 pub statements: ir::StatementList,
22 pub url: Url,
24 pub source: Hashed<String>,
26 pub line_offset: u32,
28}
29
30impl Source {
31 pub fn new(
33 doc: Option<ir::DocBlock>,
34 statements: ir::StatementList,
35 source: Hashed<String>,
36 url: Url,
37 ) -> Self {
38 Self {
39 doc,
40 statements,
41 source,
42 url,
43 name: ir::QualifiedName::default(),
44 line_offset: 0,
45 }
46 }
47
48 pub fn with_line_offset(self, line_offset: u32) -> Self {
49 let mut src = self;
50 src.line_offset = line_offset;
51 src
52 }
53
54 pub fn id(&self) -> Identifier {
56 self.name.last().unwrap_or(&Identifier::none()).clone()
57 }
58
59 pub fn filename(&self) -> std::path::PathBuf {
61 self.to_file_path()
62 .unwrap_or(std::path::PathBuf::from("<NO FILE>"))
63 }
64
65 pub fn set_filename(&mut self, path: impl AsRef<std::path::Path>) {
67 assert!(self.to_file_path().is_none());
68 self.url = Url::from_file_path(
69 path.as_ref()
70 .canonicalize()
71 .unwrap_or(path.as_ref().to_path_buf()),
72 )
73 .unwrap_or(self.url.clone());
74 }
75
76 pub fn get_code(&self, src_ref: &SrcRef) -> &str {
80 let range = &src_ref.range;
81 &self.source[range.start..range.end]
82 }
83
84 pub fn set_name(&mut self, name: ir::QualifiedName) {
86 self.name = name
87 }
88
89 pub fn source_loc_info<'a>(&'a self) -> SourceLocInfo<'a> {
91 SourceLocInfo {
92 code: &self.source,
93 url: self.url.clone(),
94 line_offset: self.line_offset,
95 }
96 }
97}
98
99impl ResourceLocation for Source {
100 fn url(&self) -> µcad_lang_base::Url {
101 &self.url
102 }
103}
104
105impl std::fmt::Display for Source {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 self.statements.iter().try_for_each(|s| writeln!(f, "{s}"))
108 }
109}
110
111impl SrcReferrer for Source {
112 fn src_ref(&self) -> SrcRef {
113 SrcRef::new(
114 0..self.source.len(),
115 LineCol::default(),
116 self.source.computed_hash(),
117 )
118 }
119}