sway_core/language/parsed/
declaration.rs1mod abi;
2mod configurable;
3mod const_generic;
4mod constant;
5mod r#enum;
6pub mod function;
7mod impl_trait;
8mod storage;
9mod r#struct;
10mod r#trait;
11mod type_alias;
12mod variable;
13
14use std::fmt;
15
16pub use abi::*;
17pub use configurable::*;
18pub use const_generic::*;
19pub use constant::*;
20pub use function::*;
21pub use impl_trait::*;
22pub use r#enum::*;
23pub use r#struct::*;
24pub use r#trait::*;
25pub use storage::*;
26use sway_error::{
27 error::CompileError,
28 handler::{ErrorEmitted, Handler},
29};
30use sway_types::{Ident, Span, Spanned};
31pub use type_alias::*;
32pub use variable::*;
33
34use crate::{
35 decl_engine::{
36 parsed_engine::{ParsedDeclEngine, ParsedDeclEngineGet},
37 parsed_id::ParsedDeclId,
38 DeclEngineGetParsedDeclId,
39 },
40 engine_threading::{
41 DebugWithEngines, DisplayWithEngines, EqWithEngines, PartialEqWithEngines,
42 PartialEqWithEnginesContext,
43 },
44 language::Visibility,
45 Engines,
46};
47
48#[derive(Debug, Clone)]
49pub enum Declaration {
50 VariableDeclaration(ParsedDeclId<VariableDeclaration>),
51 FunctionDeclaration(ParsedDeclId<FunctionDeclaration>),
52 TraitDeclaration(ParsedDeclId<TraitDeclaration>),
53 StructDeclaration(ParsedDeclId<StructDeclaration>),
54 EnumDeclaration(ParsedDeclId<EnumDeclaration>),
55 EnumVariantDeclaration(EnumVariantDeclaration),
56 ImplSelfOrTrait(ParsedDeclId<ImplSelfOrTrait>),
57 AbiDeclaration(ParsedDeclId<AbiDeclaration>),
58 ConstantDeclaration(ParsedDeclId<ConstantDeclaration>),
59 ConfigurableDeclaration(ParsedDeclId<ConfigurableDeclaration>),
60 StorageDeclaration(ParsedDeclId<StorageDeclaration>),
61 TypeAliasDeclaration(ParsedDeclId<TypeAliasDeclaration>),
62 TraitTypeDeclaration(ParsedDeclId<TraitTypeDeclaration>),
63 TraitFnDeclaration(ParsedDeclId<TraitFn>),
64 ConstGenericDeclaration(ParsedDeclId<ConstGenericDeclaration>),
65}
66
67#[derive(Debug, Clone)]
68pub struct EnumVariantDeclaration {
69 pub enum_ref: ParsedDeclId<EnumDeclaration>,
70 pub variant_name: Ident,
71 pub variant_decl_span: Span,
72}
73
74impl Declaration {
75 pub(crate) fn is_test(&self, engines: &Engines) -> bool {
77 if let Declaration::FunctionDeclaration(fn_decl) = self {
78 let fn_decl = engines.pe().get_function(fn_decl);
79 fn_decl.is_test()
80 } else {
81 false
82 }
83 }
84
85 pub fn friendly_type_name(&self) -> &'static str {
88 use Declaration::*;
89 match self {
90 VariableDeclaration(_) => "variable",
91 ConstantDeclaration(_) => "constant",
92 ConfigurableDeclaration(_) => "configurable",
93 TraitTypeDeclaration(_) => "type",
94 FunctionDeclaration(_) => "function",
95 TraitDeclaration(_) => "trait",
96 TraitFnDeclaration(_) => "trait fn",
97 StructDeclaration(_) => "struct",
98 EnumDeclaration(_) => "enum",
99 EnumVariantDeclaration(_) => "enum variant",
100 ImplSelfOrTrait(_) => "impl self/trait",
101 AbiDeclaration(_) => "abi",
102 StorageDeclaration(_) => "contract storage",
103 TypeAliasDeclaration(_) => "type alias",
104 ConstGenericDeclaration(_) => "const generic",
105 }
106 }
107
108 pub fn span(&self, engines: &Engines) -> sway_types::Span {
109 use Declaration::*;
110 let pe = engines.pe();
111 match self {
112 VariableDeclaration(decl_id) => pe.get_variable(decl_id).span(),
113 FunctionDeclaration(decl_id) => pe.get_function(decl_id).span(),
114 TraitDeclaration(decl_id) => pe.get_trait(decl_id).span(),
115 StructDeclaration(decl_id) => pe.get_struct(decl_id).span(),
116 EnumDeclaration(decl_id) => pe.get_enum(decl_id).span(),
117 EnumVariantDeclaration(decl) => decl.variant_decl_span.clone(),
118 ImplSelfOrTrait(decl_id) => pe.get_impl_self_or_trait(decl_id).span(),
119 AbiDeclaration(decl_id) => pe.get_abi(decl_id).span(),
120 ConstantDeclaration(decl_id) => pe.get_constant(decl_id).span(),
121 ConfigurableDeclaration(decl_id) => pe.get_configurable(decl_id).span(),
122 StorageDeclaration(decl_id) => pe.get_storage(decl_id).span(),
123 TypeAliasDeclaration(decl_id) => pe.get_type_alias(decl_id).span(),
124 TraitTypeDeclaration(decl_id) => pe.get_trait_type(decl_id).span(),
125 TraitFnDeclaration(decl_id) => pe.get_trait_fn(decl_id).span(),
126 ConstGenericDeclaration(decl_id) => pe.get_const_generic(decl_id).span(),
127 }
128 }
129
130 pub(crate) fn to_fn_ref(
131 &self,
132 handler: &Handler,
133 engines: &Engines,
134 ) -> Result<ParsedDeclId<FunctionDeclaration>, ErrorEmitted> {
135 match self {
136 Declaration::FunctionDeclaration(decl_id) => Ok(*decl_id),
137 decl => Err(handler.emit_err(CompileError::DeclIsNotAFunction {
138 actually: decl.friendly_type_name().to_string(),
139 span: decl.span(engines),
140 })),
141 }
142 }
143
144 pub(crate) fn to_struct_decl(
145 &self,
146 handler: &Handler,
147 engines: &Engines,
148 ) -> Result<ParsedDeclId<StructDeclaration>, ErrorEmitted> {
149 match self {
150 Declaration::StructDeclaration(decl_id) => Ok(*decl_id),
151 Declaration::TypeAliasDeclaration(decl_id) => {
152 let alias = engines.pe().get_type_alias(decl_id);
153 let struct_decl_id = engines.te().get(alias.ty.type_id).expect_struct(
154 handler,
155 engines,
156 &self.span(engines),
157 )?;
158
159 let parsed_decl_id = engines.de().get_parsed_decl_id(&struct_decl_id);
160 parsed_decl_id.ok_or_else(|| {
161 handler.emit_err(CompileError::InternalOwned(
162 "Cannot get parsed decl id from decl id".to_string(),
163 self.span(engines),
164 ))
165 })
166 }
167 decl => Err(handler.emit_err(CompileError::DeclIsNotAStruct {
168 actually: decl.friendly_type_name().to_string(),
169 span: decl.span(engines),
170 })),
171 }
172 }
173
174 pub(crate) fn to_enum_decl(
175 &self,
176 handler: &Handler,
177 engines: &Engines,
178 ) -> Result<ParsedDeclId<EnumDeclaration>, ErrorEmitted> {
179 match self {
180 Declaration::EnumDeclaration(decl_id) => Ok(*decl_id),
181 Declaration::TypeAliasDeclaration(decl_id) => {
182 let alias = engines.pe().get_type_alias(decl_id);
183 let enum_decl_id = engines.te().get(alias.ty.type_id).expect_enum(
184 handler,
185 engines,
186 String::default(),
187 &self.span(engines),
188 )?;
189
190 let parsed_decl_id = engines.de().get_parsed_decl_id(&enum_decl_id);
191 parsed_decl_id.ok_or_else(|| {
192 handler.emit_err(CompileError::InternalOwned(
193 "Cannot get parsed decl id from decl id".to_string(),
194 self.span(engines),
195 ))
196 })
197 }
198 decl => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
199 actually: decl.friendly_type_name().to_string(),
200 span: decl.span(engines),
201 })),
202 }
203 }
204
205 #[allow(unused)]
206 pub(crate) fn visibility(&self, decl_engine: &ParsedDeclEngine) -> Visibility {
207 match self {
208 Declaration::TraitDeclaration(decl_id) => decl_engine.get_trait(decl_id).visibility,
209 Declaration::ConstantDeclaration(decl_id) => {
210 decl_engine.get_constant(decl_id).visibility
211 }
212 Declaration::ConfigurableDeclaration(decl_id) => {
213 decl_engine.get_configurable(decl_id).visibility
214 }
215 Declaration::StructDeclaration(decl_id) => decl_engine.get_struct(decl_id).visibility,
216 Declaration::EnumDeclaration(decl_id) => decl_engine.get_enum(decl_id).visibility,
217 Declaration::EnumVariantDeclaration(decl) => {
218 decl_engine.get_enum(&decl.enum_ref).visibility
219 }
220 Declaration::FunctionDeclaration(decl_id) => {
221 decl_engine.get_function(decl_id).visibility
222 }
223 Declaration::TypeAliasDeclaration(decl_id) => {
224 decl_engine.get_type_alias(decl_id).visibility
225 }
226 Declaration::VariableDeclaration(_decl_id) => Visibility::Private,
227 Declaration::ImplSelfOrTrait(_)
228 | Declaration::StorageDeclaration(_)
229 | Declaration::AbiDeclaration(_)
230 | Declaration::TraitTypeDeclaration(_)
231 | Declaration::TraitFnDeclaration(_) => Visibility::Public,
232 Declaration::ConstGenericDeclaration(_) => {
233 unreachable!("Const generics do not have visibility")
234 }
235 }
236 }
237}
238
239impl DisplayWithEngines for Declaration {
240 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
241 write!(
242 f,
243 "{} parsed declaration ({})",
244 self.friendly_type_name(),
245 match self {
246 Declaration::VariableDeclaration(decl_id) => {
247 engines.pe().get(decl_id).name.as_str().into()
248 }
249 Declaration::FunctionDeclaration(decl_id) => {
250 engines.pe().get(decl_id).name.as_str().into()
251 }
252 Declaration::TraitDeclaration(decl_id) => {
253 engines.pe().get(decl_id).name.as_str().into()
254 }
255 Declaration::StructDeclaration(decl_id) => {
256 engines.pe().get(decl_id).name.as_str().into()
257 }
258 Declaration::EnumDeclaration(decl_id) => {
259 engines.pe().get(decl_id).name.as_str().into()
260 }
261 Declaration::ImplSelfOrTrait(decl_id) => {
262 engines
263 .pe()
264 .get(decl_id)
265 .trait_name
266 .as_vec_string()
267 .join("::")
268 .as_str()
269 .into()
270 }
271 Declaration::TypeAliasDeclaration(decl_id) =>
272 engines.pe().get(decl_id).name.as_str().into(),
273 _ => String::new(),
274 }
275 )
276 }
277}
278
279impl DebugWithEngines for Declaration {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
281 DisplayWithEngines::fmt(&self, f, engines)
282 }
283}
284
285impl EqWithEngines for Declaration {}
286impl PartialEqWithEngines for Declaration {
287 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
288 let decl_engine = ctx.engines().pe();
289 match (self, other) {
290 (Declaration::VariableDeclaration(lid), Declaration::VariableDeclaration(rid)) => {
291 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
292 }
293 (Declaration::FunctionDeclaration(lid), Declaration::FunctionDeclaration(rid)) => {
294 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
295 }
296 (Declaration::TraitDeclaration(lid), Declaration::TraitDeclaration(rid)) => {
297 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
298 }
299 (Declaration::StructDeclaration(lid), Declaration::StructDeclaration(rid)) => {
300 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
301 }
302 (Declaration::EnumDeclaration(lid), Declaration::EnumDeclaration(rid)) => {
303 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
304 }
305 (Declaration::ImplSelfOrTrait(lid), Declaration::ImplSelfOrTrait(rid)) => {
306 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
307 }
308 (Declaration::AbiDeclaration(lid), Declaration::AbiDeclaration(rid)) => {
309 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
310 }
311 (Declaration::ConstantDeclaration(lid), Declaration::ConstantDeclaration(rid)) => {
312 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
313 }
314 (Declaration::StorageDeclaration(lid), Declaration::StorageDeclaration(rid)) => {
315 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
316 }
317 (Declaration::TypeAliasDeclaration(lid), Declaration::TypeAliasDeclaration(rid)) => {
318 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
319 }
320 (Declaration::TraitTypeDeclaration(lid), Declaration::TraitTypeDeclaration(rid)) => {
321 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
322 }
323 _ => false,
324 }
325 }
326}