Skip to content

Commit

Permalink
Use DeclRef for struct and enum TypeInfo (FuelLabs#4213)
Browse files Browse the repository at this point in the history
## Description

Use references and the decl engine to resolve information about structs
and enums instead of copying around declaration data.

This should facilitate FuelLabs#3744

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
  • Loading branch information
IGI-111 authored Mar 3, 2023
1 parent 40cf1c2 commit 8be626a
Show file tree
Hide file tree
Showing 61 changed files with 1,573 additions and 1,296 deletions.
3 changes: 2 additions & 1 deletion forc-pkg/src/pkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,7 @@ pub fn compile(
json_abi_with_callpaths: profile.json_abi_with_callpaths,
},
engines.te(),
engines.de(),
&mut types
)
))
Expand All @@ -1755,7 +1756,7 @@ pub fn compile(

let abi = time_expr!(
"generate JSON ABI program",
evm_json_abi::generate_json_abi_program(typed_program, engines.te())
evm_json_abi::generate_json_abi_program(typed_program, &engines)
);

ops.extend(abi.into_iter());
Expand Down
8 changes: 4 additions & 4 deletions forc-plugins/forc-doc/src/descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ impl Descriptor {
use swayfmt::parse;
use TyDeclaration::*;
match ty_decl {
StructDeclaration { decl_id, .. } => {
let struct_decl = decl_engine.get_struct(decl_id);
StructDeclaration(decl_ref) => {
let struct_decl = decl_engine.get_struct(decl_ref);
if !document_private_items && struct_decl.visibility.is_private() {
Ok(Descriptor::NonDocumentable)
} else {
Expand Down Expand Up @@ -71,8 +71,8 @@ impl Descriptor {
}))
}
}
EnumDeclaration { decl_id, .. } => {
let enum_decl = decl_engine.get_enum(decl_id);
EnumDeclaration(decl_ref) => {
let enum_decl = decl_engine.get_enum(decl_ref);
if !document_private_items && enum_decl.visibility.is_private() {
Ok(Descriptor::NonDocumentable)
} else {
Expand Down
91 changes: 62 additions & 29 deletions sway-core/src/abi_generation/evm_json_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@ use sway_types::integer_bits::IntegerBits;

use crate::{
asm_generation::EvmAbiResult,
decl_engine::DeclEngine,
language::ty::{TyFunctionDeclaration, TyProgram, TyProgramKind},
TypeArgument, TypeEngine, TypeId, TypeInfo,
Engines, TypeArgument, TypeEngine, TypeId, TypeInfo,
};

pub fn generate_json_abi_program(program: &TyProgram, type_engine: &TypeEngine) -> EvmAbiResult {
pub fn generate_json_abi_program(program: &TyProgram, engines: &Engines<'_>) -> EvmAbiResult {
let type_engine = engines.te();
let decl_engine = engines.de();
match &program.kind {
TyProgramKind::Contract { abi_entries, .. } => abi_entries
.iter()
.map(|x| generate_json_abi_function(x, type_engine))
.map(|x| generate_json_abi_function(x, type_engine, decl_engine))
.collect(),
TyProgramKind::Script { main_function, .. }
| TyProgramKind::Predicate { main_function, .. } => {
vec![generate_json_abi_function(main_function, type_engine)]
vec![generate_json_abi_function(
main_function,
type_engine,
decl_engine,
)]
}
_ => vec![],
}
Expand All @@ -24,25 +31,26 @@ pub fn generate_json_abi_program(program: &TyProgram, type_engine: &TypeEngine)
fn get_json_type_str(
type_id: &TypeId,
type_engine: &TypeEngine,
decl_engine: &DeclEngine,
resolved_type_id: TypeId,
) -> String {
if type_id.is_generic_parameter(type_engine, resolved_type_id) {
if type_id.is_generic_parameter(type_engine, decl_engine, resolved_type_id) {
format!(
"generic {}",
json_abi_str(&type_engine.get(*type_id), type_engine)
json_abi_str(&type_engine.get(*type_id), type_engine, decl_engine)
)
} else {
match (type_engine.get(*type_id), type_engine.get(resolved_type_id)) {
(TypeInfo::Custom { .. }, TypeInfo::Struct { .. }) => {
format!(
"struct {}",
json_abi_str(&type_engine.get(*type_id), type_engine)
json_abi_str(&type_engine.get(*type_id), type_engine, decl_engine)
)
}
(TypeInfo::Custom { .. }, TypeInfo::Enum { .. }) => {
format!(
"enum {}",
json_abi_str(&type_engine.get(*type_id), type_engine)
json_abi_str(&type_engine.get(*type_id), type_engine, decl_engine)
)
}
(TypeInfo::Tuple(fields), TypeInfo::Tuple(resolved_fields)) => {
Expand All @@ -60,15 +68,19 @@ fn get_json_type_str(
(TypeInfo::Custom { .. }, _) => {
format!(
"generic {}",
json_abi_str(&type_engine.get(*type_id), type_engine)
json_abi_str(&type_engine.get(*type_id), type_engine, decl_engine)
)
}
_ => json_abi_str(&type_engine.get(*type_id), type_engine),
_ => json_abi_str(&type_engine.get(*type_id), type_engine, decl_engine),
}
}
}

pub fn json_abi_str(type_info: &TypeInfo, type_engine: &TypeEngine) -> String {
pub fn json_abi_str(
type_info: &TypeInfo,
type_engine: &TypeEngine,
decl_engine: &DeclEngine,
) -> String {
use TypeInfo::*;
match type_info {
Unknown => "unknown".into(),
Expand All @@ -87,7 +99,7 @@ pub fn json_abi_str(type_info: &TypeInfo, type_engine: &TypeEngine) -> String {
Tuple(fields) => {
let field_strs = fields
.iter()
.map(|field| json_abi_str_type_arg(field, type_engine))
.map(|field| json_abi_str_type_arg(field, type_engine, decl_engine))
.collect::<Vec<String>>();
format!("({})", field_strs.join(", "))
}
Expand All @@ -96,19 +108,21 @@ pub fn json_abi_str(type_info: &TypeInfo, type_engine: &TypeEngine) -> String {
Numeric => "u64".into(), // u64 is the default
Contract => "contract".into(),
ErrorRecovery => "unknown due to error".into(),
Enum { call_path, .. } => {
format!("enum {}", call_path.suffix)
Enum(decl_ref) => {
let decl = decl_engine.get_enum(decl_ref);
format!("enum {}", decl.call_path.suffix)
}
Struct { call_path, .. } => {
format!("struct {}", call_path.suffix)
Struct(decl_ref) => {
let decl = decl_engine.get_struct(decl_ref);
format!("struct {}", decl.call_path.suffix)
}
ContractCaller { abi_name, .. } => {
format!("contract caller {abi_name}")
}
Array(elem_ty, length) => {
format!(
"{}[{}]",
json_abi_str_type_arg(elem_ty, type_engine),
json_abi_str_type_arg(elem_ty, type_engine, decl_engine),
length.val()
)
}
Expand All @@ -118,7 +132,11 @@ pub fn json_abi_str(type_info: &TypeInfo, type_engine: &TypeEngine) -> String {
}
}

pub fn json_abi_param_type(type_info: &TypeInfo, type_engine: &TypeEngine) -> ethabi::ParamType {
pub fn json_abi_param_type(
type_info: &TypeInfo,
type_engine: &TypeEngine,
decl_engine: &DeclEngine,
) -> ethabi::ParamType {
use TypeInfo::*;
match type_info {
Str(x) => ethabi::ParamType::FixedArray(Box::new(ethabi::ParamType::String), x.val()),
Expand All @@ -135,20 +153,28 @@ pub fn json_abi_param_type(type_info: &TypeInfo, type_engine: &TypeEngine) -> et
Tuple(fields) => ethabi::ParamType::Tuple(
fields
.iter()
.map(|f| json_abi_param_type(&type_engine.get(f.type_id), type_engine))
.collect::<Vec<ethabi::ParamType>>(),
),
Struct { fields, .. } => ethabi::ParamType::Tuple(
fields
.iter()
.map(|f| {
json_abi_param_type(&type_engine.get(f.type_argument.type_id), type_engine)
})
.map(|f| json_abi_param_type(&type_engine.get(f.type_id), type_engine, decl_engine))
.collect::<Vec<ethabi::ParamType>>(),
),
Struct(decl_ref) => {
let decl = decl_engine.get_struct(decl_ref);
ethabi::ParamType::Tuple(
decl.fields
.iter()
.map(|f| {
json_abi_param_type(
&type_engine.get(f.type_argument.type_id),
type_engine,
decl_engine,
)
})
.collect::<Vec<ethabi::ParamType>>(),
)
}
Array(elem_ty, ..) => ethabi::ParamType::Array(Box::new(json_abi_param_type(
&type_engine.get(elem_ty.type_id),
type_engine,
decl_engine,
))),
_ => panic!("cannot convert type to Solidity ABI param type: {type_info:?}",),
}
Expand All @@ -157,6 +183,7 @@ pub fn json_abi_param_type(type_info: &TypeInfo, type_engine: &TypeEngine) -> et
pub(self) fn generate_json_abi_function(
fn_decl: &TyFunctionDeclaration,
type_engine: &TypeEngine,
decl_engine: &DeclEngine,
) -> ethabi::operation::Operation {
// A list of all `ethabi::Param`s needed for inputs
let input_types = fn_decl
Expand All @@ -168,6 +195,7 @@ pub(self) fn generate_json_abi_function(
internal_type: Some(get_json_type_str(
&x.type_argument.type_id,
type_engine,
decl_engine,
x.type_argument.type_id,
)),
})
Expand All @@ -180,6 +208,7 @@ pub(self) fn generate_json_abi_function(
internal_type: Some(get_json_type_str(
&fn_decl.return_type.type_id,
type_engine,
decl_engine,
fn_decl.return_type.type_id,
)),
};
Expand All @@ -195,6 +224,10 @@ pub(self) fn generate_json_abi_function(
})
}

pub(self) fn json_abi_str_type_arg(type_arg: &TypeArgument, type_engine: &TypeEngine) -> String {
json_abi_str(&type_engine.get(type_arg.type_id), type_engine)
pub(self) fn json_abi_str_type_arg(
type_arg: &TypeArgument,
type_engine: &TypeEngine,
decl_engine: &DeclEngine,
) -> String {
json_abi_str(&type_engine.get(type_arg.type_id), type_engine, decl_engine)
}
Loading

0 comments on commit 8be626a

Please sign in to comment.