1use rustc_hash::FxHashMap;
10use slotmap::{DefaultKey, SlotMap};
11use sway_features::ExperimentalFeatures;
12use sway_types::SourceEngine;
13
14use crate::{
15 block::BlockContent,
16 function::FunctionContent,
17 metadata::Metadatum,
18 module::{Kind, ModuleContent, ModuleIterator},
19 value::ValueContent,
20 variable::LocalVarContent,
21 Constant, ConstantContent, GlobalVarContent, StorageKeyContent, Type, TypeContent,
22};
23
24#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
27pub enum Backtrace {
28 All,
29 #[default]
30 AllExceptNever,
31 OnlyAlways,
32 None,
33}
34
35pub struct Context<'eng> {
40 pub source_engine: &'eng SourceEngine,
41
42 pub(crate) modules: SlotMap<DefaultKey, ModuleContent>,
43 pub(crate) functions: SlotMap<DefaultKey, FunctionContent>,
44 pub(crate) blocks: SlotMap<DefaultKey, BlockContent>,
45 pub(crate) values: SlotMap<DefaultKey, ValueContent>,
46 pub(crate) local_vars: SlotMap<DefaultKey, LocalVarContent>,
47 pub(crate) global_vars: SlotMap<DefaultKey, GlobalVarContent>,
48 pub(crate) storage_keys: SlotMap<DefaultKey, StorageKeyContent>,
49 pub(crate) types: SlotMap<DefaultKey, TypeContent>,
50 pub(crate) type_map: FxHashMap<TypeContent, Type>,
51 pub(crate) constants: SlotMap<DefaultKey, ConstantContent>,
52 pub(crate) constants_map: FxHashMap<u64, Vec<Constant>>,
54
55 pub(crate) metadata: SlotMap<DefaultKey, Metadatum>,
56
57 pub program_kind: Kind,
58
59 pub experimental: ExperimentalFeatures,
60 pub backtrace: Backtrace,
61
62 next_unique_sym_tag: u64,
63 next_unique_panic_error_code: u64,
64 next_unique_panicking_call_id: u64,
65}
66
67impl<'eng> Context<'eng> {
68 pub fn new(
69 source_engine: &'eng SourceEngine,
70 experimental: ExperimentalFeatures,
71 backtrace: Backtrace,
72 ) -> Self {
73 let mut def = Self {
74 source_engine,
75 modules: Default::default(),
76 functions: Default::default(),
77 blocks: Default::default(),
78 values: Default::default(),
79 local_vars: Default::default(),
80 global_vars: Default::default(),
81 storage_keys: Default::default(),
82 types: Default::default(),
83 type_map: Default::default(),
84 constants: Default::default(),
85 constants_map: Default::default(),
86 metadata: Default::default(),
87 next_unique_sym_tag: 0,
88 next_unique_panic_error_code: 0,
89 next_unique_panicking_call_id: 1,
92 program_kind: Kind::Contract,
93 experimental,
94 backtrace,
95 };
96 Type::create_basic_types(&mut def);
97 def
98 }
99
100 pub fn source_engine(&self) -> &'eng SourceEngine {
101 self.source_engine
102 }
103
104 pub fn module_iter(&self) -> ModuleIterator {
106 ModuleIterator::new(self)
107 }
108
109 pub fn get_unique_name(&mut self) -> String {
113 format!("anon_{}", self.get_unique_symbol_id())
114 }
115
116 pub fn get_unique_symbol_id(&mut self) -> u64 {
118 let sym = self.next_unique_sym_tag;
119 self.next_unique_sym_tag += 1;
120 sym
121 }
122
123 pub fn get_unique_panic_error_code(&mut self) -> u64 {
125 let code = self.next_unique_panic_error_code;
126 self.next_unique_panic_error_code += 1;
127 code
128 }
129
130 pub fn get_unique_panicking_call_id(&mut self) -> u64 {
132 let id = self.next_unique_panicking_call_id;
133 self.next_unique_panicking_call_id += 1;
134 id
135 }
136}
137
138use std::fmt::{Display, Error, Formatter};
139
140impl Display for Context<'_> {
141 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
142 write!(f, "{}", crate::printer::to_string(self))
143 }
144}
145
146impl From<Context<'_>> for String {
147 fn from(context: Context) -> Self {
148 crate::printer::to_string(&context)
149 }
150}