Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions crates/solidity-v2/outputs/cargo/ast/generated/public_api.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion crates/solidity-v2/outputs/cargo/ast/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ fn type_as_abi_parameter_impl(
visited_structs.remove(definition_id);
Some(("tuple".to_string(), components))
}
_ => Some((semantic.type_canonical_name(type_id)?, Vec::new())),
_ => Some((
semantic.type_canonical_name(type_id)?.to_owned(),
Vec::new(),
)),
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ruint::aliases::U256;
use slang_solidity_v2_semantic::binder;
use slang_solidity_v2_semantic::context::SemanticContext;
use slang_solidity_v2_semantic::context::SLOT_SIZE;

use crate::abi::{AbiEntry, ContractAbi, StorageItem};
use crate::ast::{ContractDefinitionStruct, StateVariableDefinition, StateVariableMutability};
Expand All @@ -26,20 +26,20 @@ impl ContractDefinitionStruct {
if let Some(constructor) = self.constructor() {
entries.push(constructor.compute_abi_entry()?);
}
for function in &self.compute_linearised_functions() {
for function in &self.linearised_functions() {
if function.is_externally_visible() {
entries.push(function.compute_abi_entry()?);
}
}
for state_variable in &self.compute_linearised_state_variables() {
for state_variable in &self.linearised_state_variables() {
if state_variable.is_externally_visible() {
entries.push(state_variable.compute_abi_entry()?);
}
}
for error in &self.compute_linearised_errors() {
for error in &self.linearised_errors() {
entries.push(error.compute_abi_entry()?);
}
for event in &self.compute_linearised_events() {
for event in &self.linearised_events() {
entries.push(event.compute_abi_entry()?);
}

Expand All @@ -63,7 +63,7 @@ impl ContractDefinitionStruct {

/// Computes the layouts of both permanent and transient state variables
fn compute_storage_layout(&self) -> Option<(Vec<StorageItem>, Vec<StorageItem>)> {
let all_state_variables = self.compute_linearised_state_variables();
let all_state_variables = self.linearised_state_variables();

// TODO(validation) SDR[2]: it is an error if any contract in the hierarchy
// other than the leaf has a custom offset layout
Expand Down Expand Up @@ -103,14 +103,17 @@ impl ContractDefinitionStruct {

// Check if we can pack the variable in the current slot, otherwise
// we start at the beginning of the next slot.
let remaining_bytes = SemanticContext::SLOT_SIZE - byte_offset_in_slot;
let remaining_bytes = SLOT_SIZE - byte_offset_in_slot;
if byte_offset_in_slot > 0 && variable_size > remaining_bytes {
current_slot += U256::from(1u64);
byte_offset_in_slot = 0;
}

let label = state_variable.ir_node.name.unparse().to_string();
let type_name = self.semantic.type_internal_name(variable_type_id);
let type_name = self
.semantic
.type_internal_name(variable_type_id)
.to_owned();
storage_layout.push(StorageItem {
node_id,
label,
Expand All @@ -121,8 +124,8 @@ impl ContractDefinitionStruct {

// Ready slot and offset for the next variable
byte_offset_in_slot += variable_size;
current_slot += U256::from(byte_offset_in_slot / SemanticContext::SLOT_SIZE);
byte_offset_in_slot %= SemanticContext::SLOT_SIZE;
current_slot += U256::from(byte_offset_in_slot / SLOT_SIZE);
byte_offset_in_slot %= SLOT_SIZE;
}
Some(storage_layout)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ impl ParametersStruct {
pub(crate) fn compute_canonical_signature(&self) -> Option<String> {
let mut result = Vec::new();
for type_id in self.parameter_types_iter() {
result.push(self.semantic.type_canonical_name(type_id?)?);
result.push(self.semantic.type_canonical_name(type_id?)?.to_owned());
}
Some(result.join(","))
}

pub(crate) fn compute_internal_signature(&self) -> Option<String> {
let mut result = Vec::new();
for type_id in self.parameter_types_iter() {
result.push(self.semantic.type_internal_name(type_id?));
result.push(self.semantic.type_internal_name(type_id?).to_owned());
}
Some(result.join(","))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl StateVariableDefinitionStruct {
let parameters = function_type
.parameter_types
.iter()
.map(|type_id| self.semantic.type_internal_name(*type_id))
.map(|type_id| self.semantic.type_internal_name(*type_id).to_owned())
.collect::<Vec<_>>()
.join(",");
Some(format!(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::cmp::Ordering;

use super::super::nodes::{
create_error_definition, create_event_definition, create_function_definition,
create_state_variable_definition,
};
use super::super::{
ContractDefinitionStruct, Definition, ErrorDefinition, EventDefinition, FunctionDefinition,
FunctionKind, StateVariableDefinition,
Expand All @@ -20,7 +22,7 @@ impl ContractDefinitionStruct {
/// Returns the list of contracts/interfaces in the hierarchy (including
/// self) in the order given by the C3 linearisation, with self contract
/// always first
pub fn compute_linearised_bases(&self) -> Vec<ContractBase> {
pub fn linearised_bases(&self) -> Vec<ContractBase> {
let Some(base_node_ids) = self
.semantic
.binder()
Expand All @@ -47,16 +49,12 @@ impl ContractDefinitionStruct {
}

/// Returns the list of state variable definitions in the order laid out in storage
pub fn compute_linearised_state_variables(&self) -> Vec<StateVariableDefinition> {
let mut state_variables = Vec::new();
let bases = self.compute_linearised_bases();
for base in bases.iter().rev() {
let ContractBase::Contract(contract) = base else {
continue;
};
state_variables.extend(contract.members().iter_state_variable_definitions());
}
state_variables
pub fn linearised_state_variables(&self) -> Vec<StateVariableDefinition> {
self.semantic
.linearised_state_variables(self.ir_node.id())
.iter()
.map(|ir_node| create_state_variable_definition(ir_node, &self.semantic))
.collect()
}

pub fn functions(&self) -> Vec<FunctionDefinition> {
Expand Down Expand Up @@ -86,82 +84,35 @@ impl ContractDefinitionStruct {

/// Returns the list of functions defined in all the hierarchy of the
/// contract, in alphabetical order
pub fn compute_linearised_functions(&self) -> Vec<FunctionDefinition> {
let mut functions: Vec<FunctionDefinition> = Vec::new();
let bases = self.compute_linearised_bases();
for base in &bases {
// TODO(validation) SDR[3]: we don't pick up functions defined in
// interfaces because they should be implemented in inheriting
// contracts, but this is not yet enforced anywhere
let ContractBase::Contract(contract) = base else {
continue;
};

// Handle function overriding
let contract_functions = contract
.functions()
.into_iter()
.filter(|function| {
// check the existing functions and remove any duplicates
// because they should be overridden by them
let existing = functions
.iter()
.any(|linearised_function| linearised_function.overrides(function));
!existing
})
// collect to avoid holding the read-borrow on `functions`
.collect::<Vec<_>>();

functions.extend(contract_functions);
}

// sort returned functions by name
functions.sort_by(|a, b| match (a.name(), b.name()) {
(None, None) => Ordering::Equal,
(None, Some(_)) => Ordering::Less,
(Some(_), None) => Ordering::Greater,
(Some(a), Some(b)) => a.name().cmp(&b.name()),
});
functions
pub fn linearised_functions(&self) -> Vec<FunctionDefinition> {
self.semantic
.linearised_functions(self.ir_node.id())
.iter()
.map(|ir_node| create_function_definition(ir_node, &self.semantic))
.collect()
}

pub fn errors(&self) -> Vec<ErrorDefinition> {
self.members().iter_error_definitions().collect()
}

pub fn compute_linearised_errors(&self) -> Vec<ErrorDefinition> {
let mut errors = Vec::new();
let bases = self.compute_linearised_bases();
for base in bases.iter().rev() {
match base {
ContractBase::Contract(contract) => {
errors.extend(contract.members().iter_error_definitions());
}
ContractBase::Interface(interface) => {
errors.extend(interface.members().iter_error_definitions());
}
}
}
errors
pub fn linearised_errors(&self) -> Vec<ErrorDefinition> {
self.semantic
.linearised_errors(self.ir_node.id())
.iter()
.map(|ir_node| create_error_definition(ir_node, &self.semantic))
.collect()
}

pub fn events(&self) -> Vec<EventDefinition> {
self.members().iter_event_definitions().collect()
}

pub fn compute_linearised_events(&self) -> Vec<EventDefinition> {
let mut events = Vec::new();
let bases = self.compute_linearised_bases();
for base in bases.iter().rev() {
match base {
ContractBase::Contract(contract) => {
events.extend(contract.members().iter_event_definitions());
}
ContractBase::Interface(interface) => {
events.extend(interface.members().iter_event_definitions());
}
}
}
events
pub fn linearised_events(&self) -> Vec<EventDefinition> {
self.semantic
.linearised_events(self.ir_node.id())
.iter()
.map(|ir_node| create_event_definition(ir_node, &self.semantic))
.collect()
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ mod contract_definition;
mod contract_members;
mod decimal_number_expression;
mod hex_number_expression;
mod interface_definition;
pub use contract_base::ContractBase;

mod expression;
mod function_call_expression;
mod function_definition;
mod identifier;
mod identifier_path;
mod source_unit;
Expand Down
Loading