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(_) => {
127 todo!("Will be implemented by https://github.com/FuelLabs/sway/issues/6860")
128 }
129 }
130 }
131
132 pub(crate) fn to_fn_ref(
133 &self,
134 handler: &Handler,
135 engines: &Engines,
136 ) -> Result<ParsedDeclId<FunctionDeclaration>, ErrorEmitted> {
137 match self {
138 Declaration::FunctionDeclaration(decl_id) => Ok(*decl_id),
139 decl => Err(handler.emit_err(CompileError::DeclIsNotAFunction {
140 actually: decl.friendly_type_name().to_string(),
141 span: decl.span(engines),
142 })),
143 }
144 }
145
146 pub(crate) fn to_struct_decl(
147 &self,
148 handler: &Handler,
149 engines: &Engines,
150 ) -> Result<ParsedDeclId<StructDeclaration>, ErrorEmitted> {
151 match self {
152 Declaration::StructDeclaration(decl_id) => Ok(*decl_id),
153 Declaration::TypeAliasDeclaration(decl_id) => {
154 let alias = engines.pe().get_type_alias(decl_id);
155 let struct_decl_id = engines.te().get(alias.ty.type_id).expect_struct(
156 handler,
157 engines,
158 &self.span(engines),
159 )?;
160
161 let parsed_decl_id = engines.de().get_parsed_decl_id(&struct_decl_id);
162 parsed_decl_id.ok_or_else(|| {
163 handler.emit_err(CompileError::InternalOwned(
164 "Cannot get parsed decl id from decl id".to_string(),
165 self.span(engines),
166 ))
167 })
168 }
169 decl => Err(handler.emit_err(CompileError::DeclIsNotAStruct {
170 actually: decl.friendly_type_name().to_string(),
171 span: decl.span(engines),
172 })),
173 }
174 }
175
176 #[allow(unused)]
177 pub(crate) fn visibility(&self, decl_engine: &ParsedDeclEngine) -> Visibility {
178 match self {
179 Declaration::TraitDeclaration(decl_id) => decl_engine.get_trait(decl_id).visibility,
180 Declaration::ConstantDeclaration(decl_id) => {
181 decl_engine.get_constant(decl_id).visibility
182 }
183 Declaration::ConfigurableDeclaration(decl_id) => {
184 decl_engine.get_configurable(decl_id).visibility
185 }
186 Declaration::StructDeclaration(decl_id) => decl_engine.get_struct(decl_id).visibility,
187 Declaration::EnumDeclaration(decl_id) => decl_engine.get_enum(decl_id).visibility,
188 Declaration::EnumVariantDeclaration(decl) => {
189 decl_engine.get_enum(&decl.enum_ref).visibility
190 }
191 Declaration::FunctionDeclaration(decl_id) => {
192 decl_engine.get_function(decl_id).visibility
193 }
194 Declaration::TypeAliasDeclaration(decl_id) => {
195 decl_engine.get_type_alias(decl_id).visibility
196 }
197 Declaration::VariableDeclaration(_decl_id) => Visibility::Private,
198 Declaration::ImplSelfOrTrait(_)
199 | Declaration::StorageDeclaration(_)
200 | Declaration::AbiDeclaration(_)
201 | Declaration::TraitTypeDeclaration(_)
202 | Declaration::TraitFnDeclaration(_) => Visibility::Public,
203 Declaration::ConstGenericDeclaration(_) => {
204 todo!("Will be implemented by https://github.com/FuelLabs/sway/issues/6860")
205 }
206 }
207 }
208}
209
210impl DisplayWithEngines for Declaration {
211 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
212 write!(
213 f,
214 "{} parsed declaration ({})",
215 self.friendly_type_name(),
216 match self {
217 Declaration::VariableDeclaration(decl_id) => {
218 engines.pe().get(decl_id).name.as_str().into()
219 }
220 Declaration::FunctionDeclaration(decl_id) => {
221 engines.pe().get(decl_id).name.as_str().into()
222 }
223 Declaration::TraitDeclaration(decl_id) => {
224 engines.pe().get(decl_id).name.as_str().into()
225 }
226 Declaration::StructDeclaration(decl_id) => {
227 engines.pe().get(decl_id).name.as_str().into()
228 }
229 Declaration::EnumDeclaration(decl_id) => {
230 engines.pe().get(decl_id).name.as_str().into()
231 }
232 Declaration::ImplSelfOrTrait(decl_id) => {
233 engines
234 .pe()
235 .get(decl_id)
236 .trait_name
237 .as_vec_string()
238 .join("::")
239 .as_str()
240 .into()
241 }
242 Declaration::TypeAliasDeclaration(decl_id) =>
243 engines.pe().get(decl_id).name.as_str().into(),
244 _ => String::new(),
245 }
246 )
247 }
248}
249
250impl DebugWithEngines for Declaration {
251 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
252 DisplayWithEngines::fmt(&self, f, engines)
253 }
254}
255
256impl EqWithEngines for Declaration {}
257impl PartialEqWithEngines for Declaration {
258 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
259 let decl_engine = ctx.engines().pe();
260 match (self, other) {
261 (Declaration::VariableDeclaration(lid), Declaration::VariableDeclaration(rid)) => {
262 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
263 }
264 (Declaration::FunctionDeclaration(lid), Declaration::FunctionDeclaration(rid)) => {
265 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
266 }
267 (Declaration::TraitDeclaration(lid), Declaration::TraitDeclaration(rid)) => {
268 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
269 }
270 (Declaration::StructDeclaration(lid), Declaration::StructDeclaration(rid)) => {
271 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
272 }
273 (Declaration::EnumDeclaration(lid), Declaration::EnumDeclaration(rid)) => {
274 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
275 }
276 (Declaration::ImplSelfOrTrait(lid), Declaration::ImplSelfOrTrait(rid)) => {
277 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
278 }
279 (Declaration::AbiDeclaration(lid), Declaration::AbiDeclaration(rid)) => {
280 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
281 }
282 (Declaration::ConstantDeclaration(lid), Declaration::ConstantDeclaration(rid)) => {
283 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
284 }
285 (Declaration::StorageDeclaration(lid), Declaration::StorageDeclaration(rid)) => {
286 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
287 }
288 (Declaration::TypeAliasDeclaration(lid), Declaration::TypeAliasDeclaration(rid)) => {
289 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
290 }
291 (Declaration::TraitTypeDeclaration(lid), Declaration::TraitTypeDeclaration(rid)) => {
292 decl_engine.get(lid).eq(&decl_engine.get(rid), ctx)
293 }
294 _ => false,
295 }
296 }
297}