Skip to content

Commit

Permalink
Add traits to the DeclarationEngine (FuelLabs#2683)
Browse files Browse the repository at this point in the history
* Make the DE a lazy static as a semi-temporary bandaid.

* more public methods.

* update

* Add Span to the DeclarationId type so that it can derive Spanned.

* Add new macro to use with DE.

* Add the CopyTypes trait to DeclarationId

* fmt

* Add traits to the DeclarationEngine.

* Remove macro requirement.

* Fix bad merge.

Co-authored-by: Toby Hutton <[email protected]>
  • Loading branch information
emilyaherbert and otrho authored Sep 6, 2022
1 parent f6e3300 commit d79bb51
Show file tree
Hide file tree
Showing 15 changed files with 274 additions and 131 deletions.
139 changes: 76 additions & 63 deletions sway-core/src/control_flow_analysis/dead_code_analysis.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;
use crate::{
declaration_engine::declaration_engine::de_get_storage,
declaration_engine::declaration_engine::de_get_trait,
parse_tree::{CallPath, Visibility},
semantic_analysis::{
ast_node::{
Expand Down Expand Up @@ -143,59 +144,67 @@ impl ControlFlowGraph {
.unwrap(),
]
}
TreeType::Contract | TreeType::Library { .. } => graph
.graph
.node_indices()
.filter(|i| match graph.graph[*i] {
ControlFlowGraphNode::OrganizationalDominator(_) => false,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::FunctionDeclaration(
TypedFunctionDeclaration {
visibility: Visibility::Public,
..
},
)),
..
}) => true,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::TraitDeclaration(
TypedTraitDeclaration {
visibility: Visibility::Public,
..
},
)),
..
}) => true,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::StructDeclaration(
TypedStructDeclaration {
visibility: Visibility::Public,
..
},
)),
..
}) => true,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait { .. }),
..
}) => true,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::ConstantDeclaration(
TypedConstantDeclaration {
visibility: Visibility::Public,
..
},
)),
..
}) => true,
_ => false,
})
.collect(),
TreeType::Contract | TreeType::Library { .. } => {
let mut ret = vec![];
for i in graph.graph.node_indices() {
let count_it = match &graph.graph[i] {
ControlFlowGraphNode::OrganizationalDominator(_) => false,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::FunctionDeclaration(
TypedFunctionDeclaration {
visibility: Visibility::Public,
..
},
)),
..
}) => true,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::TraitDeclaration(
decl_id,
)),
..
}) => {
let trait_decl = de_get_trait(decl_id.clone(), &decl_id.span())?;
match trait_decl.visibility {
Visibility::Private => true,
Visibility::Public => false,
}
}
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::StructDeclaration(
TypedStructDeclaration {
visibility: Visibility::Public,
..
},
)),
..
}) => true,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait { .. }),
..
}) => true,
ControlFlowGraphNode::ProgramNode(TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::ConstantDeclaration(
TypedConstantDeclaration {
visibility: Visibility::Public,
..
},
)),
..
}) => true,
_ => false,
};
if count_it {
ret.push(i);
}
}
ret
}
};
Ok(())
}
Expand Down Expand Up @@ -351,8 +360,9 @@ fn connect_declaration(
connect_typed_fn_decl(fn_decl, graph, entry_node, span, exit_node, tree_type)?;
Ok(leaves.to_vec())
}
TraitDeclaration(trait_decl) => {
connect_trait_declaration(trait_decl, graph, entry_node);
TraitDeclaration(decl_id) => {
let trait_decl = de_get_trait(decl_id.clone(), &span)?;
connect_trait_declaration(&trait_decl, graph, entry_node);
Ok(leaves.to_vec())
}
AbiDeclaration(abi_decl) => {
Expand Down Expand Up @@ -1257,15 +1267,18 @@ fn construct_dead_code_warning_from_node(node: &TypedAstNode) -> Option<CompileW
warning_content: Warning::DeadStructDeclaration,
},
TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::TraitDeclaration(
TypedTraitDeclaration { name, .. },
)),
content: TypedAstNodeContent::Declaration(TypedDeclaration::TraitDeclaration(decl_id)),
..
} => CompileWarning {
span: name.span(),
warning_content: Warning::DeadTrait,
},
} => {
let span = match de_get_trait(decl_id.clone(), &decl_id.span()) {
Ok(TypedTraitDeclaration { name, .. }) => name.span(),
Err(_) => node.span.clone(),
};
CompileWarning {
span,
warning_content: Warning::DeadTrait,
}
}
TypedAstNode {
content:
TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait(TypedImplTrait {
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/declaration_engine/declaration_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ pub(crate) fn de_insert_trait(r#trait: TypedTraitDeclaration) -> DeclarationId {
DECLARATION_ENGINE.de_insert_trait(r#trait)
}

pub(crate) fn de_get_trait(
pub fn de_get_trait(
index: DeclarationId,
span: &Span,
) -> Result<TypedTraitDeclaration, CompileError> {
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/declaration_engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ pub(crate) mod declaration_engine;
pub(crate) mod declaration_id;
pub(crate) mod declaration_wrapper;

pub use declaration_engine::de_get_storage;
pub use declaration_engine::{de_get_storage, de_get_trait};
16 changes: 15 additions & 1 deletion sway-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,21 @@ pub fn parsed_to_ast(
};

// Collect information about the types used in this program
let types_metadata = typed_program.collect_types_metadata();
let CompileResult {
value: types_metadata_result,
warnings: new_warnings,
errors: new_errors,
} = typed_program.collect_types_metadata();
warnings.extend(new_warnings);
errors.extend(new_errors);
let types_metadata = match types_metadata_result {
Some(types_metadata) => types_metadata,
None => {
errors = dedup_unsorted(errors);
warnings = dedup_unsorted(warnings);
return CompileAstResult::Failure { errors, warnings };
}
};

// Collect all the types of logged values. These are required when generating the JSON ABI.
typed_program.logged_types.extend(
Expand Down
8 changes: 7 additions & 1 deletion sway-core/src/parse_tree/declaration/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
type_system::TypeInfo,
};

use sway_types::{ident::Ident, span::Span};
use sway_types::{ident::Ident, span::Span, Spanned};

#[derive(Debug, Clone)]
pub struct TraitDeclaration {
Expand All @@ -22,6 +22,12 @@ pub(crate) struct Supertrait {
pub(crate) name: CallPath,
}

impl Spanned for Supertrait {
fn span(&self) -> Span {
self.name.span()
}
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct TraitFn {
pub name: Ident,
Expand Down
36 changes: 27 additions & 9 deletions sway-core/src/semantic_analysis/ast_node/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ pub use storage::*;
pub use variable::*;

use crate::{
declaration_engine::{declaration_engine::de_get_storage, declaration_id::DeclarationId},
declaration_engine::{
declaration_engine::{de_get_storage, de_get_trait},
declaration_id::DeclarationId,
},
error::*,
parse_tree::*,
semantic_analysis::*,
Expand All @@ -32,7 +35,7 @@ pub enum TypedDeclaration {
VariableDeclaration(TypedVariableDeclaration),
ConstantDeclaration(TypedConstantDeclaration),
FunctionDeclaration(TypedFunctionDeclaration),
TraitDeclaration(TypedTraitDeclaration),
TraitDeclaration(DeclarationId),
StructDeclaration(TypedStructDeclaration),
EnumDeclaration(TypedEnumDeclaration),
ImplTrait(TypedImplTrait),
Expand Down Expand Up @@ -73,7 +76,7 @@ impl Spanned for TypedDeclaration {
VariableDeclaration(TypedVariableDeclaration { name, .. }) => name.span(),
ConstantDeclaration(TypedConstantDeclaration { name, .. }) => name.span(),
FunctionDeclaration(TypedFunctionDeclaration { span, .. }) => span.clone(),
TraitDeclaration(TypedTraitDeclaration { name, .. }) => name.span(),
TraitDeclaration(decl_id) => decl_id.span(),
StructDeclaration(TypedStructDeclaration { name, .. }) => name.span(),
EnumDeclaration(TypedEnumDeclaration { span, .. }) => span.clone(),
AbiDeclaration(TypedAbiDeclaration { span, .. }) => span.clone(),
Expand Down Expand Up @@ -121,8 +124,12 @@ impl fmt::Display for TypedDeclaration {
}) => {
name.as_str().into()
}
TypedDeclaration::TraitDeclaration(TypedTraitDeclaration { name, .. }) =>
name.as_str().into(),
TypedDeclaration::TraitDeclaration(decl_id) => {
match de_get_trait(decl_id.clone(), &decl_id.span()) {
Ok(TypedTraitDeclaration { name, .. }) => name.as_str().into(),
Err(_) => "unknown trait".into(),
}
}
TypedDeclaration::StructDeclaration(TypedStructDeclaration { name, .. }) =>
name.as_str().into(),
TypedDeclaration::EnumDeclaration(TypedEnumDeclaration { name, .. }) =>
Expand Down Expand Up @@ -335,9 +342,20 @@ impl TypedDeclaration {
ok(type_id, warnings, errors)
}

pub(crate) fn visibility(&self) -> Visibility {
pub(crate) fn visibility(&self) -> CompileResult<Visibility> {
use TypedDeclaration::*;
match self {
let mut warnings = vec![];
let mut errors = vec![];
let visibility = match self {
TraitDeclaration(decl_id) => {
let TypedTraitDeclaration { visibility, .. } = check!(
CompileResult::from(de_get_trait(decl_id.clone(), &decl_id.span())),
return err(warnings, errors),
warnings,
errors
);
visibility
}
GenericTypeForFunctionScope { .. }
| ImplTrait { .. }
| StorageDeclaration { .. }
Expand All @@ -350,9 +368,9 @@ impl TypedDeclaration {
EnumDeclaration(TypedEnumDeclaration { visibility, .. })
| ConstantDeclaration(TypedConstantDeclaration { visibility, .. })
| FunctionDeclaration(TypedFunctionDeclaration { visibility, .. })
| TraitDeclaration(TypedTraitDeclaration { visibility, .. })
| StructDeclaration(TypedStructDeclaration { visibility, .. }) => *visibility,
}
};
ok(visibility, warnings, errors)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet};
use sway_types::{Ident, Span, Spanned};

use crate::{
declaration_engine::declaration_engine::de_get_trait,
error::{err, ok},
semantic_analysis::{
Mode, TypeCheckContext, TypedAstNodeContent, TypedExpression, TypedExpressionVariant,
Expand Down Expand Up @@ -102,7 +103,13 @@ impl TypedImplTrait {
.ok(&mut warnings, &mut errors)
.cloned()
{
Some(TypedDeclaration::TraitDeclaration(tr)) => {
Some(TypedDeclaration::TraitDeclaration(decl_id)) => {
let tr = check!(
CompileResult::from(de_get_trait(decl_id, &trait_name.span())),
return err(warnings, errors),
warnings,
errors
);
let functions_buf = check!(
type_check_trait_implementation(
ctx,
Expand Down
20 changes: 14 additions & 6 deletions sway-core/src/semantic_analysis/ast_node/declaration/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use derivative::Derivative;
use sway_types::{Ident, Spanned};

use crate::{
declaration_engine::declaration_engine::de_get_trait,
error::{err, ok},
semantic_analysis::{
ast_node::{type_check_interface_surface, type_check_trait_methods},
Expand Down Expand Up @@ -117,12 +118,19 @@ fn handle_supertraits(
.ok(&mut warnings, &mut errors)
.cloned()
{
Some(TypedDeclaration::TraitDeclaration(TypedTraitDeclaration {
ref interface_surface,
ref methods,
ref supertraits,
..
})) => {
Some(TypedDeclaration::TraitDeclaration(decl_id)) => {
let TypedTraitDeclaration {
ref interface_surface,
ref methods,
ref supertraits,
..
} = check!(
CompileResult::from(de_get_trait(decl_id.clone(), &supertrait.span())),
return err(warnings, errors),
warnings,
errors
);

// insert dummy versions of the interfaces for all of the supertraits
trait_namespace.insert_trait_implementation(
supertrait.name.clone(),
Expand Down
Loading

0 comments on commit d79bb51

Please sign in to comment.