use normal style for comments

Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2024-05-01 16:12:32 +02:00
parent 72515254fe
commit 426f673b0a
184 changed files with 3 additions and 1789 deletions
-14
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity contract build.
//!
use std::collections::HashSet;
use std::fs::File;
@@ -13,9 +11,7 @@ use serde::Serialize;
use crate::solc::combined_json::contract::Contract as CombinedJsonContract;
use crate::solc::standard_json::output::contract::Contract as StandardJsonOutputContract;
///
/// The Solidity contract build.
///
#[derive(Debug, Serialize, Deserialize)]
pub struct Contract {
/// The contract path.
@@ -31,9 +27,7 @@ pub struct Contract {
}
impl Contract {
///
/// A shortcut constructor.
///
pub fn new(
path: String,
identifier: String,
@@ -50,9 +44,7 @@ impl Contract {
}
}
///
/// Writes the contract text assembly and bytecode to files.
///
pub fn write_to_directory(
self,
path: &Path,
@@ -107,9 +99,7 @@ impl Contract {
Ok(())
}
///
/// Writes the contract text assembly and bytecode to the combined JSON.
///
pub fn write_to_combined_json(
self,
combined_json_contract: &mut CombinedJsonContract,
@@ -130,9 +120,7 @@ impl Contract {
Ok(())
}
///
/// Writes the contract text assembly and bytecode to the standard JSON.
///
pub fn write_to_standard_json(
self,
standard_json_contract: &mut StandardJsonOutputContract,
@@ -151,9 +139,7 @@ impl Contract {
Ok(())
}
///
/// Converts the full path to a short one.
///
pub fn short_path(path: &str) -> &str {
path.rfind('/')
.map(|last_slash| &path[last_slash + 1..])
-10
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity project build.
//!
pub mod contract;
@@ -13,9 +11,7 @@ use crate::solc::version::Version as SolcVersion;
use self::contract::Contract;
///
/// The Solidity project build.
///
#[derive(Debug, Default)]
pub struct Build {
/// The contract data,
@@ -23,9 +19,7 @@ pub struct Build {
}
impl Build {
///
/// Writes all contracts to the specified directory.
///
pub fn write_to_directory(
self,
output_directory: &Path,
@@ -45,9 +39,7 @@ impl Build {
Ok(())
}
///
/// Writes all contracts assembly and bytecode to the combined JSON.
///
pub fn write_to_combined_json(
self,
combined_json: &mut CombinedJson,
@@ -74,9 +66,7 @@ impl Build {
Ok(())
}
///
/// Writes all contracts assembly and bytecode to the standard JSON.
///
pub fn write_to_standard_json(
mut self,
standard_json: &mut StandardJsonOutput,
-2
View File
@@ -1,6 +1,4 @@
//!
//! Solidity to EraVM compiler constants.
//!
#![allow(dead_code)]
@@ -1,6 +1,4 @@
//!
//! The inner JSON legacy assembly code element.
//!
use std::collections::HashSet;
@@ -9,9 +7,7 @@ use serde::Serialize;
use crate::evmla::assembly::Assembly;
///
/// The inner JSON legacy assembly code element.
///
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(untagged)]
pub enum Data {
@@ -24,9 +20,7 @@ pub enum Data {
}
impl Data {
///
/// Returns the inner assembly reference if it is present.
///
pub fn get_assembly(&self) -> Option<&Assembly> {
match self {
Self::Assembly(ref assembly) => Some(assembly),
@@ -34,9 +28,7 @@ impl Data {
Self::Path(_) => None,
}
}
///
/// Returns the inner assembly mutable reference if it is present.
///
pub fn get_assembly_mut(&mut self) -> Option<&mut Assembly> {
match self {
Self::Assembly(ref mut assembly) => Some(assembly),
@@ -45,9 +37,7 @@ impl Data {
}
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
match self {
Self::Assembly(assembly) => assembly.get_missing_libraries(),
@@ -56,9 +46,7 @@ impl Data {
}
}
///
/// Gets the contract `keccak256` hash.
///
pub fn keccak256(&self) -> String {
match self {
Self::Assembly(assembly) => assembly.keccak256(),
@@ -1,10 +1,6 @@
//!
//! Translates the CODECOPY use cases.
//!
///
/// Translates the contract hash copying.
///
pub fn contract_hash<'ctx, D>(
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
offset: inkwell::values::IntValue<'ctx>,
@@ -26,9 +22,7 @@ where
Ok(())
}
///
/// Translates the library marker copying.
///
pub fn library_marker<D>(
context: &mut revive_llvm_context::EraVMContext<D>,
offset: u64,
@@ -46,9 +40,7 @@ where
Ok(())
}
///
/// Translates the static data copying.
///
pub fn static_data<'ctx, D>(
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
destination: inkwell::values::IntValue<'ctx>,
@@ -1,10 +1,6 @@
//!
//! Translates the jump operations.
//!
///
/// Translates the unconditional jump.
///
pub fn unconditional<D>(
context: &mut revive_llvm_context::EraVMContext<D>,
destination: num::BigUint,
@@ -28,9 +24,7 @@ where
Ok(())
}
///
/// Translates the conditional jump.
///
pub fn conditional<D>(
context: &mut revive_llvm_context::EraVMContext<D>,
destination: num::BigUint,
@@ -1,6 +1,4 @@
//!
//! The EVM instruction.
//!
pub mod codecopy;
pub mod jump;
@@ -14,9 +12,7 @@ use serde::Serialize;
use self::name::Name;
///
/// The EVM instruction.
///
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Instruction {
/// The opcode or tag identifier.
@@ -34,9 +30,7 @@ pub struct Instruction {
}
impl Instruction {
///
/// Returns the number of input stack arguments.
///
pub const fn input_size(&self, version: &semver::Version) -> usize {
match self.name {
Name::POP => 1,
@@ -135,9 +129,7 @@ impl Instruction {
}
}
///
/// Returns the number of output stack arguments.
///
pub const fn output_size(&self) -> usize {
match self.name {
Name::PUSH => 1,
@@ -285,9 +277,7 @@ impl Instruction {
}
}
///
/// Replaces the instruction data aliases with the actual data.
///
pub fn replace_data_aliases(
instructions: &mut [Self],
mapping: &BTreeMap<String, String>,
@@ -323,9 +313,7 @@ impl Instruction {
Ok(())
}
///
/// Initializes an `INVALID` instruction to terminate an invalid unreachable block part.
///
pub fn invalid(previous: &Self) -> Self {
Self {
name: Name::INVALID,
@@ -337,9 +325,7 @@ impl Instruction {
}
}
///
/// Initializes a recursive function `Call` instruction.
///
pub fn recursive_call(
name: String,
entry_key: revive_llvm_context::EraVMFunctionBlockKey,
@@ -366,9 +352,7 @@ impl Instruction {
}
}
///
/// Initializes a recursive function `Return` instruction.
///
pub fn recursive_return(input_size: usize, previous: &Self) -> Self {
Self {
name: Name::RecursiveReturn { input_size },
@@ -1,13 +1,9 @@
//!
//! The EVM instruction name.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The EVM instruction name.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
@@ -1,12 +1,8 @@
//!
//! Translates the stack memory operations.
//!
use inkwell::values::BasicValue;
///
/// Translates the ordinar value push.
///
pub fn push<'ctx, D>(
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
value: String,
@@ -25,9 +21,7 @@ where
Ok(result)
}
///
/// Translates the block tag label push.
///
pub fn push_tag<'ctx, D>(
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
value: String,
@@ -42,9 +36,7 @@ where
Ok(result.as_basic_value_enum())
}
///
/// Translates the stack memory duplicate.
///
pub fn dup<'ctx, D>(
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
offset: usize,
@@ -68,9 +60,7 @@ where
Ok(value)
}
///
/// Translates the stack memory swap.
///
pub fn swap<D>(
context: &mut revive_llvm_context::EraVMContext<D>,
offset: usize,
@@ -103,9 +93,7 @@ where
Ok(())
}
///
/// Translates the stack memory pop.
///
pub fn pop<D>(_context: &mut revive_llvm_context::EraVMContext<D>) -> anyhow::Result<()>
where
D: revive_llvm_context::EraVMDependency + Clone,
-17
View File
@@ -1,6 +1,4 @@
//!
//! The `solc --asm-json` output.
//!
pub mod data;
pub mod instruction;
@@ -19,9 +17,7 @@ use self::data::Data;
use self::instruction::name::Name as InstructionName;
use self::instruction::Instruction;
///
/// The JSON assembly.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Assembly {
/// The metadata string.
@@ -46,36 +42,27 @@ pub struct Assembly {
}
impl Assembly {
///
/// Gets the contract `keccak256` hash.
///
pub fn keccak256(&self) -> String {
let json = serde_json::to_vec(self).expect("Always valid");
revive_llvm_context::eravm_utils::keccak256(json.as_slice())
}
///
/// Sets the full contract path.
///
pub fn set_full_path(&mut self, full_path: String) {
self.full_path = Some(full_path);
}
///
/// Returns the full contract path if it is set, or `<undefined>` otherwise.
///
/// # Panics
/// If the `full_path` has not been set.
///
pub fn full_path(&self) -> &str {
self.full_path
.as_deref()
.unwrap_or_else(|| panic!("The full path of some contracts is unset"))
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
let mut missing_libraries = HashSet::new();
if let Some(code) = self.code.as_ref() {
@@ -94,9 +81,7 @@ impl Assembly {
missing_libraries
}
///
/// Replaces the deploy code dependencies with full contract path and returns the list.
///
pub fn deploy_dependencies_pass(
&mut self,
full_path: &str,
@@ -144,9 +129,7 @@ impl Assembly {
Ok(index_path_mapping)
}
///
/// Replaces the runtime code dependencies with full contract path and returns the list.
///
pub fn runtime_dependencies_pass(
&mut self,
full_path: &str,
@@ -1,16 +1,11 @@
//!
//! The Ethereal IR entry function link.
//!
use inkwell::values::BasicValue;
use crate::evmla::ethereal_ir::EtherealIR;
///
/// The Ethereal IR entry function link.
///
/// The link represents branching between the deploy and runtime code.
///
#[derive(Debug, Clone)]
pub struct EntryLink {
/// The code part type.
@@ -18,9 +13,7 @@ pub struct EntryLink {
}
impl EntryLink {
///
/// A shortcut constructor.
///
pub fn new(code_type: revive_llvm_context::EraVMCodeType) -> Self {
Self { code_type }
}
@@ -1,6 +1,4 @@
//!
//! The Ethereal IR block element.
//!
pub mod stack;
@@ -13,9 +11,7 @@ use crate::evmla::assembly::instruction::Instruction;
use self::stack::element::Element as StackElement;
use self::stack::Stack;
///
/// The Ethereal IR block element.
///
#[derive(Debug, Clone)]
pub struct Element {
/// The Solidity compiler version.
@@ -31,9 +27,7 @@ pub struct Element {
}
impl Element {
///
/// A shortcut constructor.
///
pub fn new(solc_version: semver::Version, instruction: Instruction) -> Self {
let input_size = instruction.input_size(&solc_version);
let output_size = instruction.output_size();
@@ -47,9 +41,7 @@ impl Element {
}
}
///
/// Pops the specified number of arguments, converted into their LLVM values.
///
fn pop_arguments_llvm<'ctx, D>(
&mut self,
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
@@ -1,10 +1,6 @@
//!
//! The Ethereal IR block element stack element.
//!
///
/// The Ethereal IR block element stack element.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Element {
/// The runtime value.
@@ -1,14 +1,10 @@
//!
//! The Ethereal IR block element stack.
//!
pub mod element;
use self::element::Element;
///
/// The Ethereal IR block element stack.
///
#[derive(Debug, Default, Clone)]
pub struct Stack {
/// The stack elements.
@@ -19,36 +15,27 @@ impl Stack {
/// The default stack size.
pub const DEFAULT_STACK_SIZE: usize = 16;
///
/// A shortcut constructor.
///
pub fn new() -> Self {
Self {
elements: Vec::with_capacity(Self::DEFAULT_STACK_SIZE),
}
}
///
/// A shortcut constructor.
///
pub fn with_capacity(capacity: usize) -> Self {
Self {
elements: Vec::with_capacity(capacity),
}
}
///
/// A shortcut constructor.
///
pub fn new_with_elements(elements: Vec<Element>) -> Self {
Self { elements }
}
///
/// The stack state hash, which acts as a block identifier.
///
/// Each block clone has its own initial stack state, which uniquely identifies the block.
///
pub fn hash(&self) -> md5::Digest {
let mut hash_context = md5::Context::new();
for element in self.elements.iter() {
@@ -60,32 +47,24 @@ impl Stack {
hash_context.compute()
}
///
/// Pushes an element onto the stack.
///
pub fn push(&mut self, element: Element) {
self.elements.push(element);
}
///
/// Appends another stack on top of this one.
///
pub fn append(&mut self, other: &mut Self) {
self.elements.append(&mut other.elements);
}
///
/// Pops a stack element.
///
pub fn pop(&mut self) -> anyhow::Result<Element> {
self.elements
.pop()
.ok_or_else(|| anyhow::anyhow!("Stack underflow"))
}
///
/// Pops the tag from the top.
///
pub fn pop_tag(&mut self) -> anyhow::Result<num::BigUint> {
match self.elements.pop() {
Some(Element::Tag(tag)) => Ok(tag),
@@ -94,9 +73,7 @@ impl Stack {
}
}
///
/// Swaps two stack elements.
///
pub fn swap(&mut self, index: usize) -> anyhow::Result<()> {
if self.elements.len() < index + 1 {
anyhow::bail!("Stack underflow");
@@ -108,9 +85,7 @@ impl Stack {
Ok(())
}
///
/// Duplicates a stack element.
///
pub fn dup(&mut self, index: usize) -> anyhow::Result<Element> {
if self.elements.len() < index {
anyhow::bail!("Stack underflow");
@@ -119,16 +94,12 @@ impl Stack {
Ok(self.elements[self.elements.len() - index].to_owned())
}
///
/// Returns the stack length.
///
pub fn len(&self) -> usize {
self.elements.len()
}
///
/// Returns an emptiness flag.
///
pub fn is_empty(&self) -> bool {
self.elements.len() == 0
}
@@ -1,6 +1,4 @@
//!
//! The Ethereal IR block.
//!
pub mod element;
@@ -14,9 +12,7 @@ use crate::evmla::assembly::instruction::Instruction;
use self::element::stack::Stack as ElementStack;
use self::element::Element;
///
/// The Ethereal IR block.
///
#[derive(Debug, Clone)]
pub struct Block {
/// The Solidity compiler version.
@@ -43,9 +39,7 @@ impl Block {
/// The predecessors hashset initial capacity.
pub const PREDECESSORS_HASHSET_DEFAULT_CAPACITY: usize = 4;
///
/// Assembles a block from the sequence of instructions.
///
pub fn try_from_instructions(
solc_version: semver::Version,
code_type: revive_llvm_context::EraVMCodeType,
@@ -109,9 +103,7 @@ impl Block {
Ok((block, cursor))
}
///
/// Inserts a predecessor tag.
///
pub fn insert_predecessor(
&mut self,
key: revive_llvm_context::EraVMFunctionBlockKey,
@@ -1,6 +1,4 @@
//!
//! The Ethereal IR function.
//!
pub mod block;
pub mod queue_element;
@@ -37,9 +35,7 @@ use self::queue_element::QueueElement;
use self::r#type::Type;
use self::visited_element::VisitedElement;
///
/// The Ethereal IR function.
///
#[derive(Debug, Clone)]
pub struct Function {
/// The Solidity compiler version.
@@ -55,9 +51,7 @@ pub struct Function {
}
impl Function {
///
/// A shortcut constructor.
///
pub fn new(solc_version: semver::Version, r#type: Type) -> Self {
let name = match r#type {
Type::Initial => EtherealIR::DEFAULT_ENTRY_FUNCTION_NAME.to_string(),
@@ -77,9 +71,7 @@ impl Function {
}
}
///
/// Runs the function block traversal.
///
pub fn traverse(
&mut self,
blocks: &HashMap<revive_llvm_context::EraVMFunctionBlockKey, Block>,
@@ -143,9 +135,7 @@ impl Function {
Ok(())
}
///
/// Consumes the entry or a conditional block attached to another one.
///
fn consume_block(
&mut self,
blocks: &HashMap<revive_llvm_context::EraVMFunctionBlockKey, Block>,
@@ -219,12 +209,9 @@ impl Function {
Ok(())
}
///
/// Processes an instruction, returning an error, if there is an invalid stack state.
///
/// The blocks with an invalid stack state are considered being partially unreachable, and
/// the invalid part is truncated after terminating with an `INVALID` instruction.
///
#[allow(clippy::too_many_arguments)]
fn handle_instruction(
blocks: &HashMap<revive_llvm_context::EraVMFunctionBlockKey, Block>,
@@ -993,9 +980,7 @@ impl Function {
Ok(())
}
///
/// Updates the stack data with input and output data.
///
fn update_io_data(
block_stack: &mut Stack,
block_element: &mut BlockElement,
@@ -1017,9 +1002,7 @@ impl Function {
Ok(())
}
///
/// Handles the recursive function call.
///
#[allow(clippy::too_many_arguments)]
fn handle_recursive_function_call(
recursive_function: &RecursiveFunction,
@@ -1095,9 +1078,7 @@ impl Function {
Ok((return_address, stack_output))
}
///
/// Pushes a block into the function.
///
fn insert_block(&mut self, mut block: Block) -> &mut Block {
let key = block.key.clone();
@@ -1120,11 +1101,8 @@ impl Function {
.expect("Always exists")
}
///
/// Checks whether the tag value actually references an existing block.
///
/// Checks both deploy and runtime code.
///
fn is_tag_value_valid(
blocks: &HashMap<revive_llvm_context::EraVMFunctionBlockKey, Block>,
tag: &num::BigUint,
@@ -1138,9 +1116,7 @@ impl Function {
))
}
///
/// Finalizes the function data.
///
fn finalize(&mut self) {
for (_tag, blocks) in self.blocks.iter() {
for block in blocks.iter() {
@@ -1,12 +1,8 @@
//!
//! The Ethereal IR block queue element.
//!
use crate::evmla::ethereal_ir::function::block::element::stack::Stack;
///
/// The Ethereal IR block queue element.
///
#[derive(Debug, Clone)]
pub struct QueueElement {
/// The block key.
@@ -18,9 +14,7 @@ pub struct QueueElement {
}
impl QueueElement {
///
/// A shortcut constructor.
///
pub fn new(
block_key: revive_llvm_context::EraVMFunctionBlockKey,
predecessor: Option<(revive_llvm_context::EraVMFunctionBlockKey, usize)>,
@@ -1,10 +1,6 @@
//!
//! The Ethereal IR function type.
//!
///
/// The Ethereal IR function type.
///
#[derive(Debug, Clone)]
pub enum Type {
/// The initial function, combining deploy and runtime code.
@@ -23,16 +19,12 @@ pub enum Type {
}
impl Type {
///
/// A shortcut constructor.
///
pub fn new_initial() -> Self {
Self::Initial
}
///
/// A shortcut constructor.
///
pub fn new_recursive(
name: String,
block_key: revive_llvm_context::EraVMFunctionBlockKey,
@@ -1,12 +1,8 @@
//!
//! The Ethereal IR block visited element.
//!
use std::cmp::Ordering;
///
/// The Ethereal IR block visited element.
///
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct VisitedElement {
/// The block key.
@@ -16,9 +12,7 @@ pub struct VisitedElement {
}
impl VisitedElement {
///
/// A shortcut constructor.
///
pub fn new(
block_key: revive_llvm_context::EraVMFunctionBlockKey,
stack_hash: md5::Digest,
@@ -1,6 +1,4 @@
//!
//! The Ethereal IR of the EVM bytecode.
//!
pub mod entry_link;
pub mod function;
@@ -16,18 +14,14 @@ use self::function::block::Block;
use self::function::r#type::Type as FunctionType;
use self::function::Function;
///
/// The Ethereal IR of the EVM bytecode.
///
/// The Ethereal IR (EthIR) is a special IR between the EVM legacy assembly and LLVM IR. It is
/// created to facilitate the translation and provide an additional environment for applying some
/// transformations, duplicating parts of the call and control flow graphs, tracking the
/// data flow, and a few more algorithms of static analysis.
///
/// The most important feature of EthIR is flattening the block tags and duplicating blocks for
/// each of initial states of the stack. The LLVM IR supports only static control flow, so the
/// stack state must be known all the way throughout the program.
///
#[derive(Debug)]
pub struct EtherealIR {
/// The Solidity compiler version.
@@ -47,9 +41,7 @@ impl EtherealIR {
/// The blocks hashmap initial capacity.
pub const BLOCKS_HASHMAP_DEFAULT_CAPACITY: usize = 64;
///
/// Assembles a sequence of functions from the sequence of instructions.
///
pub fn new(
solc_version: semver::Version,
extra_metadata: ExtraMetadata,
@@ -73,9 +65,7 @@ impl EtherealIR {
})
}
///
/// Gets blocks for the specified type of the contract code.
///
pub fn get_blocks(
solc_version: semver::Version,
code_type: revive_llvm_context::EraVMCodeType,
-2
View File
@@ -1,6 +1,4 @@
//!
//! The EVM legacy assembly compiling tools.
//!
pub mod assembly;
pub mod ethereal_ir;
-14
View File
@@ -1,6 +1,4 @@
//!
//! Solidity to EraVM compiler library.
//!
pub(crate) mod build;
pub(crate) mod r#const;
@@ -48,9 +46,7 @@ pub mod tests;
use std::collections::BTreeSet;
use std::path::PathBuf;
///
/// Runs the Yul mode.
///
pub fn yul(
input_files: &[PathBuf],
solc: &mut SolcCompiler,
@@ -94,9 +90,7 @@ pub fn yul(
Ok(build)
}
///
/// Runs the LLVM IR mode.
///
pub fn llvm_ir(
input_files: &[PathBuf],
optimizer_settings: revive_llvm_context::OptimizerSettings,
@@ -126,9 +120,7 @@ pub fn llvm_ir(
Ok(build)
}
///
/// Runs the EraVM assembly mode.
///
pub fn zkasm(
input_files: &[PathBuf],
include_metadata_hash: bool,
@@ -157,9 +149,7 @@ pub fn zkasm(
Ok(build)
}
///
/// Runs the standard output mode.
///
#[allow(clippy::too_many_arguments)]
pub fn standard_output(
input_files: &[PathBuf],
@@ -250,9 +240,7 @@ pub fn standard_output(
Ok(build)
}
///
/// Runs the standard JSON mode.
///
#[allow(clippy::too_many_arguments)]
pub fn standard_json(
solc: &mut SolcCompiler,
@@ -332,9 +320,7 @@ pub fn standard_json(
std::process::exit(0);
}
///
/// Runs the combined JSON mode.
///
#[allow(clippy::too_many_arguments)]
pub fn combined_json(
format: String,
-8
View File
@@ -1,6 +1,4 @@
//!
//! The missing Solidity libraries.
//!
use std::collections::BTreeMap;
use std::collections::HashSet;
@@ -8,25 +6,19 @@ use std::collections::HashSet;
use crate::solc::standard_json::output::Output as StandardJsonOutput;
use crate::solc::version::Version as SolcVersion;
///
/// The missing Solidity libraries.
///
pub struct MissingLibraries {
/// The missing libraries.
pub contract_libraries: BTreeMap<String, HashSet<String>>,
}
impl MissingLibraries {
///
/// A shortcut constructor.
///
pub fn new(contract_libraries: BTreeMap<String, HashSet<String>>) -> Self {
Self { contract_libraries }
}
///
/// Writes the missing libraries to the standard JSON.
///
pub fn write_to_standard_json(
mut self,
standard_json: &mut StandardJsonOutput,
-7
View File
@@ -1,8 +1,5 @@
//!
//! Process for compiling a single compilation unit.
//!
//! The input data.
//!
use serde::Deserialize;
use serde::Serialize;
@@ -10,9 +7,7 @@ use serde::Serialize;
use crate::project::contract::Contract;
use crate::project::Project;
///
/// The input data.
///
#[derive(Debug, Serialize, Deserialize)]
pub struct Input {
/// The contract representation.
@@ -32,9 +27,7 @@ pub struct Input {
}
impl Input {
///
/// A shortcut constructor.
///
pub fn new(
contract: Contract,
project: Project,
-6
View File
@@ -1,6 +1,4 @@
//!
//! Process for compiling a single compilation unit.
//!
pub mod input;
pub mod output;
@@ -18,9 +16,7 @@ use self::output::Output;
/// The overriden executable name used when the compiler is run as a library.
pub static EXECUTABLE: OnceCell<PathBuf> = OnceCell::new();
///
/// Read input from `stdin`, compile a contract, and write the output to `stdout`.
///
pub fn run() -> anyhow::Result<()> {
let mut stdin = std::io::stdin();
let mut stdout = std::io::stdout();
@@ -60,9 +56,7 @@ pub fn run() -> anyhow::Result<()> {
}
}
///
/// Runs this process recursively to compile a single contract.
///
pub fn call(input: Input) -> anyhow::Result<Output> {
let input_json = serde_json::to_vec(&input).expect("Always valid");
-7
View File
@@ -1,17 +1,12 @@
//!
//! Process for compiling a single compilation unit.
//!
//! The output data.
//!
use serde::Deserialize;
use serde::Serialize;
use crate::build::contract::Contract as ContractBuild;
///
/// The output data.
///
#[derive(Debug, Serialize, Deserialize)]
pub struct Output {
/// The contract build.
@@ -19,9 +14,7 @@ pub struct Output {
}
impl Output {
///
/// A shortcut constructor.
///
pub fn new(build: ContractBuild) -> Self {
Self { build }
}
@@ -1,6 +1,4 @@
//!
//! The contract EVM legacy assembly source code.
//!
use std::collections::HashSet;
@@ -10,9 +8,7 @@ use serde::Serialize;
use crate::evmla::assembly::Assembly;
use crate::solc::standard_json::output::contract::evm::extra_metadata::ExtraMetadata;
///
/// The contract EVM legacy assembly source code.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
@@ -22,17 +18,13 @@ pub struct EVMLA {
}
impl EVMLA {
///
/// A shortcut constructor.
///
pub fn new(mut assembly: Assembly, extra_metadata: ExtraMetadata) -> Self {
assembly.extra_metadata = Some(extra_metadata);
Self { assembly }
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
self.assembly.get_missing_libraries()
}
@@ -1,13 +1,9 @@
//!
//! The contract LLVM IR source code.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The contract LLVM IR source code.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[allow(clippy::upper_case_acronyms)]
pub struct LLVMIR {
@@ -18,9 +14,7 @@ pub struct LLVMIR {
}
impl LLVMIR {
///
/// A shortcut constructor.
///
pub fn new(path: String, source: String) -> Self {
Self { path, source }
}
@@ -1,6 +1,4 @@
//!
//! The contract source code.
//!
pub mod evmla;
pub mod llvm_ir;
@@ -21,9 +19,7 @@ use self::llvm_ir::LLVMIR;
use self::yul::Yul;
use self::zkasm::ZKASM;
///
/// The contract source code.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
@@ -40,37 +36,27 @@ pub enum IR {
}
impl IR {
///
/// A shortcut constructor.
///
pub fn new_yul(source_code: String, object: Object) -> Self {
Self::Yul(Yul::new(source_code, object))
}
///
/// A shortcut constructor.
///
pub fn new_evmla(assembly: Assembly, extra_metadata: ExtraMetadata) -> Self {
Self::EVMLA(EVMLA::new(assembly, extra_metadata))
}
///
/// A shortcut constructor.
///
pub fn new_llvm_ir(path: String, source: String) -> Self {
Self::LLVMIR(LLVMIR::new(path, source))
}
///
/// A shortcut constructor.
///
pub fn new_zkasm(path: String, source: String) -> Self {
Self::ZKASM(ZKASM::new(path, source))
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
match self {
Self::Yul(inner) => inner.get_missing_libraries(),
@@ -1,6 +1,4 @@
//!
//! The contract Yul source code.
//!
use std::collections::HashSet;
@@ -9,9 +7,7 @@ use serde::Serialize;
use crate::yul::parser::statement::object::Object;
///
/// The contract Yul source code.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Yul {
/// The Yul source code.
@@ -21,9 +17,7 @@ pub struct Yul {
}
impl Yul {
///
/// A shortcut constructor.
///
pub fn new(source_code: String, object: Object) -> Self {
Self {
source_code,
@@ -31,9 +25,7 @@ impl Yul {
}
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
self.object.get_missing_libraries()
}
@@ -1,13 +1,9 @@
//!
//! The contract EraVM assembly source code.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The contract EraVM assembly source code.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[allow(clippy::upper_case_acronyms)]
pub struct ZKASM {
@@ -18,9 +14,7 @@ pub struct ZKASM {
}
impl ZKASM {
///
/// A shortcut constructor.
///
pub fn new(path: String, source: String) -> Self {
Self { path, source }
}
@@ -1,14 +1,9 @@
//!
//! The Solidity contract metadata.
//!
use serde::Serialize;
///
/// The Solidity contract metadata.
///
/// Is used to append the metadata hash to the contract bytecode.
///
#[derive(Debug, Serialize)]
pub struct Metadata {
/// The `solc` metadata.
@@ -24,9 +19,7 @@ pub struct Metadata {
}
impl Metadata {
///
/// A shortcut constructor.
///
pub fn new(
solc_metadata: serde_json::Value,
solc_version: semver::Version,
@@ -1,6 +1,4 @@
//!
//! The contract data.
//!
pub mod ir;
pub mod metadata;
@@ -20,9 +18,7 @@ use crate::solc::version::Version as SolcVersion;
use self::ir::IR;
use self::metadata::Metadata;
///
/// The contract data.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Contract {
/// The absolute file path.
@@ -34,9 +30,7 @@ pub struct Contract {
}
impl Contract {
///
/// A shortcut constructor.
///
pub fn new(
path: String,
source_hash: [u8; revive_common::BYTE_LENGTH_FIELD],
@@ -58,12 +52,10 @@ impl Contract {
}
}
///
/// Returns the contract identifier, which is:
/// - the Yul object identifier for Yul
/// - the full contract path for EVM legacy assembly
/// - the module name for LLVM IR
///
pub fn identifier(&self) -> &str {
match self.ir {
IR::Yul(ref yul) => yul.object.identifier.as_str(),
@@ -73,9 +65,7 @@ impl Contract {
}
}
///
/// Extract factory dependencies.
///
pub fn drain_factory_dependencies(&mut self) -> HashSet<String> {
match self.ir {
IR::Yul(ref mut yul) => yul.object.factory_dependencies.drain().collect(),
@@ -85,9 +75,7 @@ impl Contract {
}
}
///
/// Compiles the specified contract, setting its build artifacts.
///
pub fn compile(
mut self,
project: Project,
@@ -196,9 +184,7 @@ impl Contract {
))
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
self.ir.get_missing_libraries()
}
-19
View File
@@ -1,6 +1,4 @@
//!
//! The processed input data.
//!
pub mod contract;
@@ -27,9 +25,7 @@ use crate::yul::parser::statement::object::Object;
use self::contract::Contract;
///
/// The processes input data.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Project {
/// The source code version.
@@ -43,9 +39,7 @@ pub struct Project {
}
impl Project {
///
/// A shortcut constructor.
///
pub fn new(
version: SolcVersion,
contracts: BTreeMap<String, Contract>,
@@ -64,9 +58,7 @@ impl Project {
}
}
///
/// Compiles all contracts, returning their build artifacts.
///
pub fn compile(
self,
optimizer_settings: revive_llvm_context::OptimizerSettings,
@@ -141,9 +133,7 @@ impl Project {
Ok(build)
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> MissingLibraries {
let deployed_libraries = self
.libraries
@@ -168,9 +158,7 @@ impl Project {
MissingLibraries::new(missing_deployable_libraries)
}
///
/// Parses the Yul source code file and returns the source data.
///
pub fn try_from_yul_path(
path: &Path,
solc_validator: Option<&SolcCompiler>,
@@ -180,11 +168,8 @@ impl Project {
Self::try_from_yul_string(path, source_code.as_str(), solc_validator)
}
///
/// Parses the test Yul source code string and returns the source data.
///
/// Only for integration testing purposes.
///
pub fn try_from_yul_string(
path: &Path,
source_code: &str,
@@ -221,9 +206,7 @@ impl Project {
))
}
///
/// Parses the LLVM IR source code file and returns the source data.
///
pub fn try_from_llvm_ir_path(path: &Path) -> anyhow::Result<Self> {
let source_code = std::fs::read_to_string(path)
.map_err(|error| anyhow::anyhow!("LLVM IR file {:?} reading error: {}", path, error))?;
@@ -252,9 +235,7 @@ impl Project {
))
}
///
/// Parses the EraVM assembly source code file and returns the source data.
///
pub fn try_from_zkasm_path(path: &Path) -> anyhow::Result<Self> {
let source_code = std::fs::read_to_string(path).map_err(|error| {
anyhow::anyhow!("EraVM assembly file {:?} reading error: {}", path, error)
@@ -1,6 +1,4 @@
//!
//! The `solc --combined-json` contract.
//!
use std::collections::BTreeMap;
use std::collections::HashSet;
@@ -8,9 +6,7 @@ use std::collections::HashSet;
use serde::Deserialize;
use serde::Serialize;
///
/// The contract.
///
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Contract {
@@ -53,12 +49,9 @@ pub struct Contract {
}
impl Contract {
///
/// Returns the signature hash of the specified contract entry.
///
/// # Panics
/// If the hashes have not been requested in the `solc` call.
///
pub fn entry(&self, entry: &str) -> u32 {
self.hashes
.as_ref()
@@ -1,6 +1,4 @@
//!
//! The `solc --combined-json` output.
//!
pub mod contract;
@@ -14,9 +12,7 @@ use serde::Serialize;
use self::contract::Contract;
///
/// The `solc --combined-json` output.
///
#[derive(Debug, Serialize, Deserialize)]
pub struct CombinedJson {
/// The contract entries.
@@ -36,9 +32,7 @@ pub struct CombinedJson {
}
impl CombinedJson {
///
/// Returns the signature hash of the specified contract and entry.
///
pub fn entry(&self, path: &str, entry: &str) -> u32 {
self.contracts
.iter()
@@ -53,9 +47,7 @@ impl CombinedJson {
.entry(entry)
}
///
/// Returns the full contract path which can be found in `combined-json` output.
///
pub fn get_full_path(&self, name: &str) -> Option<String> {
self.contracts.iter().find_map(|(path, _value)| {
if let Some(last_slash_position) = path.rfind('/') {
@@ -70,9 +62,7 @@ impl CombinedJson {
})
}
///
/// Removes EVM artifacts to prevent their accidental usage.
///
pub fn remove_evm(&mut self) {
for (_, contract) in self.contracts.iter_mut() {
contract.bin = None;
@@ -80,9 +70,7 @@ impl CombinedJson {
}
}
///
/// Writes the JSON to the specified directory.
///
pub fn write_to_directory(
self,
output_directory: &Path,
-15
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler.
//!
pub mod combined_json;
pub mod pipeline;
@@ -17,9 +15,7 @@ use self::standard_json::input::Input as StandardJsonInput;
use self::standard_json::output::Output as StandardJsonOutput;
use self::version::Version;
///
/// The Solidity compiler.
///
pub struct Compiler {
/// The binary executable name.
pub executable: String,
@@ -43,12 +39,9 @@ impl Compiler {
/// The last supported version of `solc`.
pub const LAST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 25);
///
/// A shortcut constructor.
///
/// Different tools may use different `executable` names. For example, the integration tester
/// uses `solc-<version>` format.
///
pub fn new(executable: String) -> anyhow::Result<Self> {
if let Err(error) = which::which(executable.as_str()) {
anyhow::bail!(
@@ -62,9 +55,7 @@ impl Compiler {
})
}
///
/// Compiles the Solidity `--standard-json` input into Yul IR.
///
pub fn standard_json(
&mut self,
mut input: StandardJsonInput,
@@ -143,9 +134,7 @@ impl Compiler {
Ok(output)
}
///
/// The `solc --combined-json abi,hashes...` mirror.
///
pub fn combined_json(
&self,
paths: &[PathBuf],
@@ -217,9 +206,7 @@ impl Compiler {
Ok(combined_json)
}
///
/// The `solc` Yul validator.
///
pub fn validate_yul(&self, path: &Path) -> anyhow::Result<()> {
let mut command = std::process::Command::new(self.executable.as_str());
command.arg("--strict-assembly");
@@ -239,9 +226,7 @@ impl Compiler {
Ok(())
}
///
/// The `solc --version` mini-parser.
///
pub fn version(&mut self) -> anyhow::Result<Version> {
if let Some(version) = self.version.as_ref() {
return Ok(version.to_owned());
-6
View File
@@ -1,13 +1,9 @@
//!
//! The Solidity compiler pipeline type.
//!
use crate::solc::version::Version as SolcVersion;
use crate::solc::Compiler as SolcCompiler;
///
/// The Solidity compiler pipeline type.
///
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
@@ -19,9 +15,7 @@ pub enum Pipeline {
}
impl Pipeline {
///
/// We always use EVMLA for Solidity <=0.7, or if the user does not want to compile via Yul.
///
pub fn new(solc_version: &SolcVersion, force_evmla: bool) -> Self {
if solc_version.default < SolcCompiler::FIRST_YUL_VERSION || force_evmla {
Self::EVMLA
@@ -1,13 +1,9 @@
//!
//! The `solc --standard-json` input language.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The `solc --standard-json` input language.
///
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Language {
/// The Solidity language.
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` input.
//!
pub mod language;
pub mod settings;
@@ -25,9 +23,7 @@ use self::language::Language;
use self::settings::Settings;
use self::source::Source;
///
/// The `solc --standard-json` input.
///
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Input {
@@ -43,9 +39,7 @@ pub struct Input {
}
impl Input {
///
/// A shortcut constructor from stdin.
///
pub fn try_from_stdin(solc_pipeline: SolcPipeline) -> anyhow::Result<Self> {
let mut input: Self = serde_json::from_reader(std::io::BufReader::new(std::io::stdin()))?;
input
@@ -56,9 +50,7 @@ impl Input {
Ok(input)
}
///
/// A shortcut constructor from paths.
///
#[allow(clippy::too_many_arguments)]
pub fn try_from_paths(
language: Language,
@@ -100,11 +92,8 @@ impl Input {
})
}
///
/// A shortcut constructor from source code.
///
/// Only for the integration test purposes.
///
#[allow(clippy::too_many_arguments)]
pub fn try_from_sources(
evm_version: Option<revive_common::EVMVersion>,
@@ -138,9 +127,7 @@ impl Input {
})
}
///
/// Sets the necessary defaults.
///
pub fn normalize(&mut self, version: &semver::Version) {
self.settings.normalize(version);
}
@@ -1,13 +1,9 @@
//!
//! The `solc --standard-json` input settings metadata.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The `solc --standard-json` input settings metadata.
///
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Metadata {
@@ -17,9 +13,7 @@ pub struct Metadata {
}
impl Metadata {
///
/// A shortcut constructor.
///
pub fn new(bytecode_hash: revive_llvm_context::EraVMMetadataHash) -> Self {
Self {
bytecode_hash: Some(bytecode_hash),
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` input settings.
//!
pub mod metadata;
pub mod optimizer;
@@ -16,9 +14,7 @@ use self::metadata::Metadata;
use self::optimizer::Optimizer;
use self::selection::Selection;
///
/// The `solc --standard-json` input settings.
///
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Settings {
@@ -49,9 +45,7 @@ pub struct Settings {
}
impl Settings {
///
/// A shortcut constructor.
///
pub fn new(
evm_version: Option<revive_common::EVMVersion>,
libraries: BTreeMap<String, BTreeMap<String, String>>,
@@ -72,16 +66,12 @@ impl Settings {
}
}
///
/// Sets the necessary defaults.
///
pub fn normalize(&mut self, version: &semver::Version) {
self.optimizer.normalize(version);
}
///
/// Parses the library list and returns their double hashmap with path and name as keys.
///
pub fn parse_libraries(
input: Vec<String>,
) -> anyhow::Result<BTreeMap<String, BTreeMap<String, String>>> {
@@ -1,13 +1,9 @@
//!
//! The `solc --standard-json` input settings optimizer details.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The `solc --standard-json` input settings optimizer details.
///
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Details {
@@ -29,9 +25,7 @@ pub struct Details {
}
impl Details {
///
/// A shortcut constructor.
///
pub fn new(
peephole: bool,
inliner: Option<bool>,
@@ -52,9 +46,7 @@ impl Details {
}
}
///
/// Creates a set of disabled optimizations.
///
pub fn disabled(version: &semver::Version) -> Self {
let inliner = if version >= &semver::Version::new(0, 8, 5) {
Some(false)
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` input settings optimizer.
//!
pub mod details;
@@ -9,9 +7,7 @@ use serde::Serialize;
use self::details::Details;
///
/// The `solc --standard-json` input settings optimizer.
///
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Optimizer {
@@ -32,9 +28,7 @@ pub struct Optimizer {
}
impl Optimizer {
///
/// A shortcut constructor.
///
pub fn new(
enabled: bool,
mode: Option<char>,
@@ -51,9 +45,7 @@ impl Optimizer {
}
}
///
/// Sets the necessary defaults.
///
pub fn normalize(&mut self, version: &semver::Version) {
self.details = if version >= &semver::Version::new(0, 5, 5) {
Some(Details::disabled(version))
@@ -1,15 +1,11 @@
//!
//! The `solc --standard-json` expected output selection flag.
//!
use serde::Deserialize;
use serde::Serialize;
use crate::solc::pipeline::Pipeline as SolcPipeline;
///
/// The `solc --standard-json` expected output selection flag.
///
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output file selection.
//!
pub mod flag;
@@ -13,9 +11,7 @@ use crate::solc::pipeline::Pipeline as SolcPipeline;
use self::flag::Flag as SelectionFlag;
///
/// The `solc --standard-json` output file selection.
///
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct File {
/// The per-file output selections.
@@ -27,9 +23,7 @@ pub struct File {
}
impl File {
///
/// Creates the selection required by our compilation process.
///
pub fn new_required(pipeline: SolcPipeline) -> Self {
Self {
per_file: Some(HashSet::from_iter([SelectionFlag::AST])),
@@ -42,9 +36,7 @@ impl File {
}
}
///
/// Extends the user's output selection with flag required by our compilation process.
///
pub fn extend_with_required(&mut self, pipeline: SolcPipeline) -> &mut Self {
let required = Self::new_required(pipeline);
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output selection.
//!
pub mod file;
@@ -11,9 +9,7 @@ use crate::solc::pipeline::Pipeline as SolcPipeline;
use self::file::File as FileSelection;
///
/// The `solc --standard-json` output selection.
///
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Selection {
/// Only the 'all' wildcard is available for robustness reasons.
@@ -22,18 +18,14 @@ pub struct Selection {
}
impl Selection {
///
/// Creates the selection required by our compilation process.
///
pub fn new_required(pipeline: SolcPipeline) -> Self {
Self {
all: Some(FileSelection::new_required(pipeline)),
}
}
///
/// Extends the user's output selection with flag required by our compilation process.
///
pub fn extend_with_required(&mut self, pipeline: SolcPipeline) -> &mut Self {
self.all
.get_or_insert_with(|| FileSelection::new_required(pipeline))
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` input source.
//!
use std::io::Read;
use std::path::Path;
@@ -8,9 +6,7 @@ use std::path::Path;
use serde::Deserialize;
use serde::Serialize;
///
/// The `solc --standard-json` input source.
///
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Source {
@@ -1,6 +1,4 @@
//!
//! The `solc <input>.sol --standard-json`.
//!
pub mod input;
pub mod output;
@@ -1,13 +1,9 @@
//!
//! The `solc --standard-json` output contract EVM bytecode.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The `solc --standard-json` output contract EVM bytecode.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Bytecode {
@@ -16,17 +12,13 @@ pub struct Bytecode {
}
impl Bytecode {
///
/// A shortcut constructor.
///
pub fn new(object: String) -> Self {
Self { object }
}
}
///
/// The `solc --standard-json` output contract EVM deployed bytecode.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DeployedBytecode {
@@ -35,9 +27,7 @@ pub struct DeployedBytecode {
}
impl DeployedBytecode {
///
/// A shortcut constructor.
///
pub fn new(object: String) -> Self {
Self { object }
}
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output contract EVM extra metadata.
//!
pub mod recursive_function;
@@ -9,9 +7,7 @@ use serde::Serialize;
use self::recursive_function::RecursiveFunction;
///
/// The `solc --standard-json` output contract EVM extra metadata.
///
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ExtraMetadata {
@@ -21,9 +17,7 @@ pub struct ExtraMetadata {
}
impl ExtraMetadata {
///
/// Returns the recursive function reference for the specified tag.
///
pub fn get(
&self,
block_key: &revive_llvm_context::EraVMFunctionBlockKey,
@@ -1,13 +1,9 @@
//!
//! The `solc --standard-json` output contract EVM recursive function.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The `solc --standard-json` output contract EVM recursive function.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct RecursiveFunction {
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output contract EVM data.
//!
pub mod bytecode;
pub mod extra_metadata;
@@ -16,11 +14,8 @@ use self::bytecode::Bytecode;
use self::bytecode::DeployedBytecode;
use self::extra_metadata::ExtraMetadata;
///
/// The `solc --standard-json` output contract EVM data.
///
/// It is replaced by EraVM data after compiling.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct EVM {
@@ -44,9 +39,7 @@ pub struct EVM {
}
impl EVM {
///
/// Sets the EraVM assembly and bytecode.
///
pub fn modify(&mut self, assembly_text: String, bytecode: String) {
self.assembly_text = Some(assembly_text);
self.bytecode = Some(Bytecode::new(bytecode));
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output contract.
//!
pub mod evm;
@@ -12,9 +10,7 @@ use serde::Serialize;
use self::evm::EVM;
///
/// The `solc --standard-json` output contract.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Contract {
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output error.
//!
pub mod source_location;
@@ -11,9 +9,7 @@ use serde::Serialize;
use self::source_location::SourceLocation;
///
/// The `solc --standard-json` output error.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Error {
@@ -34,9 +30,7 @@ pub struct Error {
}
impl Error {
///
/// Returns the `ecrecover` function usage warning.
///
pub fn message_ecrecover(src: Option<&str>) -> Self {
let message = r#"
@@ -59,9 +53,7 @@ impl Error {
}
}
///
/// Returns the `<address payable>`'s `send` and `transfer` methods usage error.
///
pub fn message_send_and_transfer(src: Option<&str>) -> Self {
let message = r#"
@@ -87,9 +79,7 @@ impl Error {
}
}
///
/// Returns the `extcodesize` instruction usage warning.
///
pub fn message_extcodesize(src: Option<&str>) -> Self {
let message = r#"
@@ -114,9 +104,7 @@ impl Error {
}
}
///
/// Returns the `origin` instruction usage warning.
///
pub fn message_tx_origin(src: Option<&str>) -> Self {
let message = r#"
@@ -139,9 +127,7 @@ impl Error {
}
}
///
/// Returns the internal function pointer usage error.
///
pub fn message_internal_function_pointer(src: Option<&str>) -> Self {
let message = r#"
@@ -161,9 +147,7 @@ impl Error {
}
}
///
/// Appends the contract path to the message..
///
pub fn push_contract_path(&mut self, path: &str) {
self.formatted_message
.push_str(format!("\n--> {path}\n").as_str());
@@ -1,15 +1,11 @@
//!
//! The `solc --standard-json` output error source location.
//!
use std::str::FromStr;
use serde::Deserialize;
use serde::Serialize;
///
/// The `solc --standard-json` output error source location.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SourceLocation {
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output.
//!
pub mod contract;
pub mod error;
@@ -27,9 +25,7 @@ use self::contract::Contract;
use self::error::Error as SolcStandardJsonOutputError;
use self::source::Source;
///
/// The `solc --standard-json` output.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Output {
/// The file-contract hashmap.
@@ -53,9 +49,7 @@ pub struct Output {
}
impl Output {
///
/// Converts the `solc` JSON output into a convenient project.
///
pub fn try_to_project(
&mut self,
source_code_files: BTreeMap<String, String>,
@@ -144,9 +138,7 @@ impl Output {
))
}
///
/// Removes EVM artifacts to prevent their accidental usage.
///
pub fn remove_evm(&mut self) {
if let Some(files) = self.contracts.as_mut() {
for (_, file) in files.iter_mut() {
@@ -159,9 +151,7 @@ impl Output {
}
}
///
/// Traverses the AST and returns the list of additional errors and warnings.
///
pub fn preprocess_ast(
&mut self,
version: &SolcVersion,
@@ -196,9 +186,7 @@ impl Output {
Ok(())
}
///
/// The pass, which replaces with dependency indexes with actual data.
///
fn preprocess_dependencies(&mut self) -> anyhow::Result<()> {
let files = match self.contracts.as_mut() {
Some(files) => files,
@@ -242,9 +230,7 @@ impl Output {
Ok(())
}
///
/// Preprocesses an assembly JSON structure dependency data map.
///
fn preprocess_dependency_level(
full_path: &str,
assembly: &mut Assembly,
@@ -1,6 +1,4 @@
//!
//! The `solc --standard-json` output source.
//!
use serde::Deserialize;
use serde::Serialize;
@@ -10,9 +8,7 @@ use crate::solc::standard_json::output::error::Error as SolcStandardJsonOutputEr
use crate::solc::version::Version as SolcVersion;
use crate::warning::Warning;
///
/// The `solc --standard-json` output source.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Source {
@@ -23,9 +19,7 @@ pub struct Source {
}
impl Source {
///
/// Checks the AST node for the `ecrecover` function usage.
///
pub fn check_ecrecover(ast: &serde_json::Value) -> Option<SolcStandardJsonOutputError> {
let ast = ast.as_object()?;
@@ -46,9 +40,7 @@ impl Source {
))
}
///
/// Checks the AST node for the `<address payable>`'s `send` and `transfer` methods usage.
///
pub fn check_send_and_transfer(ast: &serde_json::Value) -> Option<SolcStandardJsonOutputError> {
let ast = ast.as_object()?;
@@ -70,9 +62,7 @@ impl Source {
))
}
///
/// Checks the AST node for the `extcodesize` assembly instruction usage.
///
pub fn check_assembly_extcodesize(
ast: &serde_json::Value,
) -> Option<SolcStandardJsonOutputError> {
@@ -96,9 +86,7 @@ impl Source {
))
}
///
/// Checks the AST node for the `origin` assembly instruction usage.
///
pub fn check_assembly_origin(ast: &serde_json::Value) -> Option<SolcStandardJsonOutputError> {
let ast = ast.as_object()?;
@@ -120,9 +108,7 @@ impl Source {
))
}
///
/// Checks the AST node for the `tx.origin` value usage.
///
pub fn check_tx_origin(ast: &serde_json::Value) -> Option<SolcStandardJsonOutputError> {
let ast = ast.as_object()?;
@@ -146,9 +132,7 @@ impl Source {
))
}
///
/// Checks the AST node for the internal function pointers value usage.
///
pub fn check_internal_function_pointer(
ast: &serde_json::Value,
) -> Option<SolcStandardJsonOutputError> {
@@ -174,9 +158,7 @@ impl Source {
)
}
///
/// Returns the list of messages for some specific parts of the AST.
///
pub fn get_messages(
ast: &serde_json::Value,
version: &SolcVersion,
@@ -240,9 +222,7 @@ impl Source {
messages
}
///
/// Returns the name of the last contract.
///
pub fn last_contract_name(&self) -> anyhow::Result<String> {
self.ast
.as_ref()
-8
View File
@@ -1,13 +1,9 @@
//!
//! The Solidity compiler version.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The Solidity compiler version.
///
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Version {
/// The long version string.
@@ -19,9 +15,7 @@ pub struct Version {
}
impl Version {
///
/// A shortcut constructor.
///
pub fn new(
long: String,
default: semver::Version,
@@ -34,9 +28,7 @@ impl Version {
}
}
///
/// A shortcut constructor for a simple version.
///
pub fn new_simple(version: semver::Version) -> Self {
Self {
long: version.to_string(),
-8
View File
@@ -14,9 +14,7 @@ use crate::solc::standard_json::output::Output as SolcStandardJsonOutput;
use crate::solc::Compiler as SolcCompiler;
use crate::warning::Warning;
///
/// Checks if the required executables are present in `${PATH}`.
///
fn check_dependencies() {
for executable in [
crate::r#const::DEFAULT_EXECUTABLE_NAME,
@@ -154,9 +152,7 @@ pub fn build_solidity_with_options_evm(
Ok(contracts)
}
///
/// Builds the Solidity project and returns the standard JSON output.
///
pub fn build_solidity_and_detect_missing_libraries(
sources: BTreeMap<String, String>,
libraries: BTreeMap<String, BTreeMap<String, String>>,
@@ -203,9 +199,7 @@ pub fn build_solidity_and_detect_missing_libraries(
Ok(output)
}
///
/// Checks if the Yul project can be built without errors.
///
pub fn build_yul(source_code: &str) -> anyhow::Result<()> {
check_dependencies();
@@ -220,9 +214,7 @@ pub fn build_yul(source_code: &str) -> anyhow::Result<()> {
Ok(())
}
///
/// Checks if the built Solidity project contains the given warning.
///
pub fn check_solidity_warning(
source_code: &str,
warning_substring: &str,
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests for factory dependencies.
//!
#![cfg(test)]
@@ -1,8 +1,5 @@
//!
//! The Solidity compiler unit tests for IR artifacts.
//!
//! The tests check if the IR artifacts are kept in the final output.
//!
#![cfg(test)]
-2
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests for libraries.
//!
#![cfg(test)]
-2
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests for messages.
//!
#![cfg(test)]
-2
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests.
//!
#![cfg(test)]
-2
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests for the optimizer.
//!
#![cfg(test)]
-2
View File
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests for remappings.
//!
#![cfg(test)]
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests for runtime code.
//!
#![cfg(test)]
@@ -1,6 +1,4 @@
//!
//! The Solidity compiler unit tests for unsupported opcodes.
//!
#![cfg(test)]
-6
View File
@@ -1,15 +1,11 @@
//!
//! The compiler warning.
//!
use std::str::FromStr;
use serde::Deserialize;
use serde::Serialize;
///
/// The compiler warning.
///
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Warning {
/// The warning for eponymous feature.
@@ -29,9 +25,7 @@ pub enum Warning {
}
impl Warning {
///
/// Converts string arguments into an array of warnings.
///
pub fn try_from_strings(strings: &[String]) -> Result<Vec<Self>, anyhow::Error> {
strings
.iter()
-4
View File
@@ -1,13 +1,9 @@
//!
//! The Yul IR error.
//!
use crate::yul::lexer::error::Error as LexerError;
use crate::yul::parser::error::Error as ParserError;
///
/// The Yul IR error.
///
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum Error {
/// The lexer error.
-4
View File
@@ -1,12 +1,8 @@
//!
//! The Yul IR lexer error.
//!
use crate::yul::lexer::token::location::Location;
///
/// The Yul IR lexer error.
///
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum Error {
/// The invalid lexeme error.
-10
View File
@@ -1,6 +1,4 @@
//!
//! The compiler lexer.
//!
pub mod error;
pub mod token;
@@ -18,9 +16,7 @@ use self::token::lexeme::Lexeme;
use self::token::location::Location;
use self::token::Token;
///
/// The compiler lexer.
///
pub struct Lexer {
/// The input source code.
input: String,
@@ -33,9 +29,7 @@ pub struct Lexer {
}
impl Lexer {
///
/// A shortcut constructor.
///
pub fn new(mut input: String) -> Self {
input.push('\n');
@@ -47,9 +41,7 @@ impl Lexer {
}
}
///
/// Advances the lexer, returning the next lexeme.
///
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Result<Token, Error> {
if let Some(peeked) = self.peeked.take() {
@@ -121,9 +113,7 @@ impl Lexer {
Ok(Token::new(self.location, Lexeme::EndOfFile, 0))
}
///
/// Peeks the next lexeme without advancing the iterator.
///
pub fn peek(&mut self) -> Result<Token, Error> {
match self.peeked {
Some(ref peeked) => Ok(peeked.clone()),
-2
View File
@@ -1,6 +1,4 @@
//!
//! The Yul IR lexer tests.
//!
use crate::yul::lexer::error::Error;
use crate::yul::lexer::token::lexeme::Lexeme;
@@ -1,6 +1,4 @@
//!
//! The comment lexeme.
//!
pub mod multi_line;
pub mod single_line;
@@ -10,9 +8,7 @@ use crate::yul::lexer::token::Token;
use self::multi_line::Comment as MultiLineComment;
use self::single_line::Comment as SingleLineComment;
///
/// The comment lexeme.
///
#[derive(Debug, Clone, PartialEq, Eq)]
#[allow(dead_code)]
pub enum Comment {
@@ -23,9 +19,7 @@ pub enum Comment {
}
impl Comment {
///
/// Returns the comment's length, including the trimmed whitespace around it.
///
pub fn parse(input: &str) -> Option<Token> {
if input.starts_with(SingleLineComment::START) {
Some(SingleLineComment::parse(input))
@@ -1,14 +1,10 @@
//!
//! The multi-line comment lexeme.
//!
use crate::yul::lexer::token::lexeme::Lexeme;
use crate::yul::lexer::token::location::Location;
use crate::yul::lexer::token::Token;
///
/// The multi-line comment lexeme.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Comment {}
@@ -18,9 +14,7 @@ impl Comment {
/// The end symbol.
pub const END: &'static str = "*/";
///
/// Returns the comment, including its length and number of lines.
///
pub fn parse(input: &str) -> Token {
let end_position = input.find(Self::END).unwrap_or(input.len());
let input = &input[..end_position];
@@ -1,14 +1,10 @@
//!
//! The single-line comment lexeme.
//!
use crate::yul::lexer::token::lexeme::Lexeme;
use crate::yul::lexer::token::location::Location;
use crate::yul::lexer::token::Token;
///
/// The single-line comment lexeme.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Comment {}
@@ -18,9 +14,7 @@ impl Comment {
/// The end symbol.
pub const END: &'static str = "\n";
///
/// Returns the comment's length, including the trimmed whitespace around it.
///
pub fn parse(input: &str) -> Token {
let end_position = input.find(Self::END).unwrap_or(input.len());
let length = end_position + Self::END.len();
@@ -1,15 +1,11 @@
//!
//! The identifier lexeme.
//!
use crate::yul::lexer::token::lexeme::keyword::Keyword;
use crate::yul::lexer::token::lexeme::Lexeme;
use crate::yul::lexer::token::location::Location;
use crate::yul::lexer::token::Token;
///
/// The identifier lexeme.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Identifier {
/// The inner string.
@@ -17,16 +13,12 @@ pub struct Identifier {
}
impl Identifier {
///
/// A shortcut constructor.
///
pub fn new(inner: String) -> Self {
Self { inner }
}
///
/// Parses the identifier, returning it as a token.
///
pub fn parse(input: &str) -> Option<Token> {
if !input.starts_with(Self::can_begin) {
return None;
@@ -47,16 +39,12 @@ impl Identifier {
))
}
///
/// Checks whether the character can begin an identifier.
///
pub fn can_begin(character: char) -> bool {
character.is_alphabetic() || character == '_' || character == '$'
}
///
/// Checks whether the character can continue an identifier.
///
pub fn can_continue(character: char) -> bool {
Self::can_begin(character)
|| character.is_numeric()
@@ -65,9 +53,7 @@ impl Identifier {
|| character == '.'
}
///
/// Checks whether the character cannot continue an identifier.
///
pub fn cannot_continue(character: char) -> bool {
!Self::can_continue(character)
}
@@ -1,6 +1,4 @@
//!
//! The keyword lexeme.
//!
use crate::yul::lexer::token::lexeme::literal::boolean::Boolean as BooleanLiteral;
use crate::yul::lexer::token::lexeme::literal::Literal;
@@ -8,9 +6,7 @@ use crate::yul::lexer::token::lexeme::Lexeme;
use crate::yul::lexer::token::location::Location;
use crate::yul::lexer::token::Token;
///
/// The keyword lexeme.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Keyword {
/// The `object` keyword.
@@ -50,9 +46,7 @@ pub enum Keyword {
}
impl Keyword {
///
/// Parses the keyword, returning it as a token.
///
pub fn parse(input: &str) -> Option<Token> {
let keyword = Self::parse_keyword(input)?;
let lexeme = match BooleanLiteral::try_from(keyword) {
@@ -68,9 +62,7 @@ impl Keyword {
Some(Token::new(Location::new(0, length), lexeme, length))
}
///
/// Parses the keyword itself.
///
fn parse_keyword(input: &str) -> Option<Self> {
if !input.starts_with(Self::can_begin) {
return None;
@@ -111,23 +103,17 @@ impl Keyword {
})
}
///
/// Checks whether the character can begin a keyword.
///
pub fn can_begin(character: char) -> bool {
character.is_alphabetic()
}
///
/// Checks whether the character can continue a keyword.
///
pub fn can_continue(character: char) -> bool {
Self::can_begin(character) || character.is_numeric()
}
///
/// Checks whether the character cannot continue a keyword.
///
pub fn cannot_continue(character: char) -> bool {
!Self::can_continue(character)
}
@@ -1,15 +1,11 @@
//!
//! The boolean literal lexeme.
//!
use serde::Deserialize;
use serde::Serialize;
use crate::yul::lexer::token::lexeme::keyword::Keyword;
///
/// The boolean literal lexeme.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Boolean {
/// Created from the `false` keyword.
@@ -19,16 +15,12 @@ pub enum Boolean {
}
impl Boolean {
///
/// Creates a `false` value.
///
pub fn r#false() -> Self {
Self::False
}
///
/// Creates a `true` value.
///
pub fn r#true() -> Self {
Self::True
}
@@ -1,6 +1,4 @@
//!
//! The integer literal lexeme.
//!
use serde::Deserialize;
use serde::Serialize;
@@ -10,9 +8,7 @@ use crate::yul::lexer::token::lexeme::Literal;
use crate::yul::lexer::token::location::Location;
use crate::yul::lexer::token::Token;
///
/// The integer literal lexeme.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Integer {
/// An integer literal, like `42`.
@@ -28,23 +24,17 @@ pub enum Integer {
}
impl Integer {
///
/// Creates a decimal value.
///
pub fn new_decimal(inner: String) -> Self {
Self::Decimal { inner }
}
///
/// Creates a hexadecimal value.
///
pub fn new_hexadecimal(inner: String) -> Self {
Self::Hexadecimal { inner }
}
///
/// Parses the value from the source code slice.
///
pub fn parse(input: &str) -> Option<Token> {
let (value, length) = if let Some(body) = input.strip_prefix("0x") {
let end = body
@@ -72,37 +62,27 @@ impl Integer {
Some(token)
}
///
/// Checks whether the character can begin a decimal number.
///
pub fn can_begin_decimal(character: char) -> bool {
Self::can_continue_decimal(character)
}
///
/// Checks whether the character can continue a decimal number.
///
pub fn can_continue_decimal(character: char) -> bool {
character.is_digit(revive_common::BASE_DECIMAL)
}
///
/// Checks whether the character cannot continue a decimal number.
///
pub fn cannot_continue_decimal(character: char) -> bool {
!Self::can_continue_decimal(character)
}
///
/// Checks whether the character can continue a hexadecimal number.
///
pub fn can_continue_hexadecimal(character: char) -> bool {
character.is_digit(revive_common::BASE_HEXADECIMAL)
}
///
/// Checks whether the character cannot continue a hexadecimal number.
///
pub fn cannot_continue_hexadecimal(character: char) -> bool {
!Self::can_continue_hexadecimal(character)
}
@@ -1,6 +1,4 @@
//!
//! The literal lexeme.
//!
pub mod boolean;
pub mod integer;
@@ -13,9 +11,7 @@ use self::boolean::Boolean;
use self::integer::Integer;
use self::string::String;
///
/// The literal lexeme.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Literal {
/// A boolean literal, like `true`, or `false`.
@@ -1,6 +1,4 @@
//!
//! The string literal lexeme.
//!
use serde::Deserialize;
use serde::Serialize;
@@ -10,9 +8,7 @@ use crate::yul::lexer::token::lexeme::Literal;
use crate::yul::lexer::token::location::Location;
use crate::yul::lexer::token::Token;
///
/// The string literal lexeme.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct String {
/// The inner string contents.
@@ -22,9 +18,7 @@ pub struct String {
}
impl String {
///
/// Creates a string literal value.
///
pub fn new(inner: ::std::string::String, is_hexadecimal: bool) -> Self {
Self {
inner,
@@ -32,9 +26,7 @@ impl String {
}
}
///
/// Parses the value from the source code slice.
///
pub fn parse(input: &str) -> Option<Token> {
let mut length = 0;
@@ -1,6 +1,4 @@
//!
//! The lexeme.
//!
pub mod comment;
pub mod identifier;
@@ -13,9 +11,7 @@ use self::keyword::Keyword;
use self::literal::Literal;
use self::symbol::Symbol;
///
/// The lexeme.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Lexeme {
/// The keyword lexeme.
@@ -1,14 +1,10 @@
//!
//! The symbol lexeme.
//!
use crate::yul::lexer::token::lexeme::Lexeme;
use crate::yul::lexer::token::location::Location;
use crate::yul::lexer::token::Token;
///
/// The symbol lexeme.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Symbol {
/// The `:=` symbol.
@@ -30,9 +26,7 @@ pub enum Symbol {
}
impl Symbol {
///
/// Parses the symbol, returning it as a token.
///
pub fn parse(input: &str) -> Option<Token> {
let (symbol, length) = match &input[..2] {
":=" => (Self::Assignment, 2),
@@ -1,13 +1,9 @@
//!
//! The lexical token location.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The token location in the source code file.
///
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Eq)]
pub struct Location {
/// The line number, starting from 1.
@@ -23,17 +19,13 @@ impl Default for Location {
}
impl Location {
///
/// Creates a default location.
///
pub fn new(line: usize, column: usize) -> Self {
Self { line, column }
}
///
/// Mutates the location by shifting the original one down by `lines` and
/// setting the column to `column`.
///
pub fn shift_down(&mut self, lines: usize, column: usize) {
if lines == 0 {
self.shift_right(column);
@@ -44,9 +36,7 @@ impl Location {
self.column = column;
}
///
/// Mutates the location by shifting the original one rightward by `columns`.
///
pub fn shift_right(&mut self, columns: usize) {
self.column += columns;
}
@@ -1,6 +1,4 @@
//!
//! The token.
//!
pub mod lexeme;
pub mod location;
@@ -8,11 +6,8 @@ pub mod location;
use self::lexeme::Lexeme;
use self::location::Location;
///
/// The token.
///
/// Contains a lexeme and its location.
///
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Token {
/// The token location.
@@ -24,9 +19,7 @@ pub struct Token {
}
impl Token {
///
/// A shortcut constructor.
///
pub fn new(location: Location, lexeme: Lexeme, length: usize) -> Self {
Self {
location,
-2
View File
@@ -1,6 +1,4 @@
//!
//! The Yul IR compiling tools.
//!
pub mod error;
pub mod lexer;
-4
View File
@@ -1,14 +1,10 @@
//!
//! The Yul IR parser error.
//!
use std::collections::BTreeSet;
use crate::yul::lexer::token::location::Location;
///
/// The Yul IR parser error.
///
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum Error {
/// An invalid token received from the lexer.
@@ -1,6 +1,4 @@
//!
//! The YUL source code identifier.
//!
use serde::Deserialize;
use serde::Serialize;
@@ -13,9 +11,7 @@ use crate::yul::lexer::token::Token;
use crate::yul::lexer::Lexer;
use crate::yul::parser::r#type::Type;
///
/// The YUL source code identifier.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Identifier {
/// The location.
@@ -27,9 +23,7 @@ pub struct Identifier {
}
impl Identifier {
///
/// A shortcut constructor.
///
pub fn new(location: Location, inner: String) -> Self {
Self {
location,
@@ -38,9 +32,7 @@ impl Identifier {
}
}
///
/// A shortcut constructor for a typed identifier.
///
pub fn new_with_type(location: Location, inner: String, r#type: Option<Type>) -> Self {
Self {
location,
@@ -49,9 +41,7 @@ impl Identifier {
}
}
///
/// Parses the identifier list where the types cannot be specified.
///
pub fn parse_list(
lexer: &mut Lexer,
mut initial: Option<Token>,
@@ -82,9 +72,7 @@ impl Identifier {
}
}
///
/// Parses the identifier list where the types may be optionally specified.
///
pub fn parse_typed_list(
lexer: &mut Lexer,
mut initial: Option<Token>,
-4
View File
@@ -1,6 +1,4 @@
//!
//! The YUL code block.
//!
pub mod error;
pub mod identifier;
@@ -11,9 +9,7 @@ use crate::yul::lexer::error::Error as LexerError;
use crate::yul::lexer::token::Token;
use crate::yul::lexer::Lexer;
///
/// Returns the `token` value if it is `Some(_)`, otherwise takes the next token from the `stream`.
///
pub fn take_or_next(mut token: Option<Token>, lexer: &mut Lexer) -> Result<Token, LexerError> {
match token.take() {
Some(token) => Ok(token),
@@ -1,6 +1,4 @@
//!
//! The assignment expression statement.
//!
use std::collections::HashSet;
@@ -18,9 +16,7 @@ use crate::yul::parser::error::Error as ParserError;
use crate::yul::parser::identifier::Identifier;
use crate::yul::parser::statement::expression::Expression;
///
/// The Yul assignment expression statement.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Assignment {
/// The location.
@@ -32,9 +28,7 @@ pub struct Assignment {
}
impl Assignment {
///
/// The element parser.
///
pub fn parse(lexer: &mut Lexer, initial: Option<Token>) -> Result<Self, Error> {
let token = crate::yul::parser::take_or_next(initial, lexer)?;
@@ -107,9 +101,7 @@ impl Assignment {
}
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
self.initializer.get_missing_libraries()
}
@@ -1,6 +1,4 @@
//!
//! The source code block.
//!
use std::collections::HashSet;
@@ -18,9 +16,7 @@ use crate::yul::parser::statement::assignment::Assignment;
use crate::yul::parser::statement::expression::Expression;
use crate::yul::parser::statement::Statement;
///
/// The Yul source code block.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Block {
/// The location.
@@ -30,9 +26,7 @@ pub struct Block {
}
impl Block {
///
/// The element parser.
///
pub fn parse(lexer: &mut Lexer, initial: Option<Token>) -> Result<Self, Error> {
let token = crate::yul::parser::take_or_next(initial, lexer)?;
@@ -124,9 +118,7 @@ impl Block {
})
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
let mut libraries = HashSet::new();
for statement in self.statements.iter() {
@@ -1,6 +1,4 @@
//!
//! The YUL code.
//!
use std::collections::HashSet;
@@ -16,9 +14,7 @@ use crate::yul::lexer::Lexer;
use crate::yul::parser::error::Error as ParserError;
use crate::yul::parser::statement::block::Block;
///
/// The YUL code entity, which is the first block of the object.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Code {
/// The location.
@@ -28,9 +24,7 @@ pub struct Code {
}
impl Code {
///
/// The element parser.
///
pub fn parse(lexer: &mut Lexer, initial: Option<Token>) -> Result<Self, Error> {
let token = crate::yul::parser::take_or_next(initial, lexer)?;
@@ -55,9 +49,7 @@ impl Code {
Ok(Self { location, block })
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
self.block.get_missing_libraries()
}
@@ -1,6 +1,4 @@
//!
//! The function call subexpression.
//!
pub mod name;
pub mod verbatim;
@@ -24,9 +22,7 @@ use crate::yul::parser::statement::expression::Expression;
use self::name::Name;
///
/// The Yul function call subexpression.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct FunctionCall {
/// The location.
@@ -38,9 +34,7 @@ pub struct FunctionCall {
}
impl FunctionCall {
///
/// The element parser.
///
pub fn parse(lexer: &mut Lexer, initial: Option<Token>) -> Result<Self, Error> {
let token = crate::yul::parser::take_or_next(initial, lexer)?;
@@ -98,9 +92,7 @@ impl FunctionCall {
})
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
let mut libraries = HashSet::new();
@@ -122,9 +114,7 @@ impl FunctionCall {
libraries
}
///
/// Converts the function call into an LLVM value.
///
pub fn into_llvm<'ctx, D>(
mut self,
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
@@ -1013,9 +1003,7 @@ impl FunctionCall {
}
}
///
/// Pops the specified number of arguments, converted into their LLVM values.
///
fn pop_arguments_llvm<'ctx, D, const N: usize>(
&mut self,
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
@@ -1032,9 +1020,7 @@ impl FunctionCall {
Ok(arguments.try_into().expect("Always successful"))
}
///
/// Pops the specified number of arguments.
///
fn pop_arguments<'ctx, D, const N: usize>(
&mut self,
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
@@ -1,13 +1,9 @@
//!
//! The function name.
//!
use serde::Deserialize;
use serde::Serialize;
///
/// The function name.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Name {
/// The user-defined function.
@@ -147,14 +143,12 @@ pub enum Name {
StaticCall,
/// create new contract with code `mem[p…(p+n))` and send `v` wei and return the new address
///
/// Passes bytecode to the system contracts.
Create,
/// create new contract with code `mem[p…(p+n))` at address
/// `keccak256(0xff . this . s . keccak256(mem[p…(p+n)))` and send `v` wei and return the
/// new address, where `0xff` is a 1-byte value, this is the current contracts address as a
/// 20-byte value and `s` is a big-endian 256-bit value
///
/// Passes bytecode to the system contracts.
Create2,
/// returns the size in the data area
@@ -230,9 +224,7 @@ pub enum Name {
}
impl Name {
///
/// Tries parsing the verbatim instruction.
///
fn parse_verbatim(input: &str) -> Option<Self> {
let verbatim = input.strip_prefix("verbatim")?;
let regex = regex::Regex::new(r"_(\d+)i_(\d+)o").expect("Always valid");
@@ -1,12 +1,8 @@
//!
//! Translates the verbatim simulations.
//!
use crate::yul::parser::statement::expression::function_call::FunctionCall;
///
/// Translates the verbatim simulations.
///
pub fn verbatim<'ctx, D>(
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
call: &mut FunctionCall,
@@ -1,6 +1,4 @@
//!
//! The YUL source code literal.
//!
use inkwell::values::BasicValue;
use num::Num;
@@ -21,9 +19,7 @@ use crate::yul::lexer::Lexer;
use crate::yul::parser::error::Error as ParserError;
use crate::yul::parser::r#type::Type;
///
/// Represents a literal in YUL without differentiating its type.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Literal {
/// The location.
@@ -35,9 +31,7 @@ pub struct Literal {
}
impl Literal {
///
/// The element parser.
///
pub fn parse(lexer: &mut Lexer, initial: Option<Token>) -> Result<Self, Error> {
let token = crate::yul::parser::take_or_next(initial, lexer)?;
@@ -75,9 +69,7 @@ impl Literal {
})
}
///
/// Converts the literal into its LLVM.
///
pub fn into_llvm<'ctx, D>(
self,
context: &revive_llvm_context::EraVMContext<'ctx, D>,
@@ -1,6 +1,4 @@
//!
//! The expression statement.
//!
pub mod function_call;
pub mod literal;
@@ -22,9 +20,7 @@ use crate::yul::parser::identifier::Identifier;
use self::function_call::FunctionCall;
use self::literal::Literal;
///
/// The Yul expression statement.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Expression {
/// The function call subexpression.
@@ -36,9 +32,7 @@ pub enum Expression {
}
impl Expression {
///
/// The element parser.
///
pub fn parse(lexer: &mut Lexer, initial: Option<Token>) -> Result<Self, Error> {
let token = crate::yul::parser::take_or_next(initial, lexer)?;
@@ -81,9 +75,7 @@ impl Expression {
}
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
match self {
Self::FunctionCall(inner) => inner.get_missing_libraries(),
@@ -92,9 +84,7 @@ impl Expression {
}
}
///
/// Returns the statement location.
///
pub fn location(&self) -> Location {
match self {
Self::FunctionCall(inner) => inner.location,
@@ -103,9 +93,7 @@ impl Expression {
}
}
///
/// Converts the expression into an LLVM value.
///
pub fn into_llvm<'ctx, D>(
self,
context: &mut revive_llvm_context::EraVMContext<'ctx, D>,
@@ -1,6 +1,4 @@
//!
//! The for-loop statement.
//!
use std::collections::HashSet;
@@ -14,9 +12,7 @@ use crate::yul::lexer::Lexer;
use crate::yul::parser::statement::block::Block;
use crate::yul::parser::statement::expression::Expression;
///
/// The Yul for-loop statement.
///
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct ForLoop {
/// The location.
@@ -32,9 +28,7 @@ pub struct ForLoop {
}
impl ForLoop {
///
/// The element parser.
///
pub fn parse(lexer: &mut Lexer, initial: Option<Token>) -> Result<Self, Error> {
let token = crate::yul::parser::take_or_next(initial, lexer)?;
let location = token.location;
@@ -56,9 +50,7 @@ impl ForLoop {
})
}
///
/// Get the list of missing deployable libraries.
///
pub fn get_missing_libraries(&self) -> HashSet<String> {
let mut libraries = self.initializer.get_missing_libraries();
libraries.extend(self.condition.get_missing_libraries());

Some files were not shown because too many files have changed in this diff Show More