Expand description
§syn-solidity
syn
-powered parser for Solidity-like TokenStream
s.
The parsed root element is the File
, which contains a list of Item
s.
Item
s also support outer attributes, as shown below.
§Design
This parser is specifically designed for Rust procedural macros. It aims to
mimic the behavior of the official Solidity compiler (Solc) when it comes to
parsing valid Solidity code. This means that all valid Solidity code, as
recognized by Solc v0.5.*1 and above, will also be recognized and parsed
correctly by syn-solidity
.
However, syn-solidity
is more permissive and lenient compared to the official
Solidity compiler and grammar specifications. Some examples of code patterns
that are valid in syn-solidity
but not in the official compiler include:
- identifiers are Rust identifiers (
syn::Ident
), and as such cannot contain the dollar sign ($
), but can contain unicode characters - trailing punctuation, like commas (
,
) in function arguments or enums definitions - certain variable and function attributes in certain contexts, like
internal
functions or functions with implementations ({ ... }
) in interfaces - parameter storage locations in item definitions, like
uint256[] memory
in a struct or error definition - the tuple type
(T, U, ..)
is allowed wherever a type is expected, and can optionally be preceded by thetuple
keyword. This is the same asethers.js
’s Human-Readable ABI
This lenient behavior is intentionally designed to facilitate usage within procedural macros, and to reduce general code complexity in the parser and AST.
§Known limitations
This parser is limited to only valid Rust tokens, meaning that certain Solidity constructs are not supported. Some examples include, but are not limited to:
- dollar signs (
$
) inside of identifiers - single quote strings
hex
andunicode
string literal prefixes. Literal prefixes are reserved in Rust edition 2021 and above."\uXXXX"
unicode escapes. Rust uses"\u{XXXX}"
for unicode codepoints- invalid nested block comments. For example,
/*/*/
does not parse.
For the most part, you can copy-paste Solidity code and expect it to parse correctly most of the time. You can see a few examples of Solidity code that parses correctly (after some very light patching) in the tests directory.
§Examples
Basic usage:
use quote::quote;
use syn_solidity::{Expr, File, Item, Lit, Stmt};
// Create a Solidity `TokenStream`
let tokens = quote! {
/// @name HelloWorld
/// @notice A hello world example in Solidity.
contract HelloWorld {
/// @notice Returns the string "Hello, World!".
function helloWorld() external pure returns (string memory) {
return "Hello, World!";
}
}
};
// Parse the tokens into a `File`
let ast: File = syn_solidity::parse2(tokens)?;
let items: &[Item] = &ast.items;
let Some(Item::Contract(contract)) = items.first() else {
unreachable!()
};
assert_eq!(contract.name, "HelloWorld");
assert_eq!(contract.attrs.len(), 2); // doc comments
let body: &[Item] = &contract.body;
let Some(Item::Function(function)) = body.first() else {
unreachable!()
};
assert_eq!(function.attrs.len(), 1); // doc comment
assert_eq!(function.name.as_ref().unwrap(), "helloWorld");
assert!(function.parameters.is_empty()); // ()
assert_eq!(function.attributes.len(), 2); // external pure
assert!(function.returns.is_some());
let Some([Stmt::Return(ret)]) = function.body() else {
unreachable!()
};
let Some(Expr::Lit(Lit::Str(s))) = &ret.expr else {
unreachable!()
};
assert_eq!(s.value(), "Hello, World!");
Older versions may still parse successfully, but this is not guaranteed. ↩
Re-exports§
Modules§
- kw
- Solidity keywords.
- spanned
- Helper trait and methods to manipulate syntax tree nodes’ spans.
- visit
visit
- Syntax tree traversal to walk a shared borrow of a syntax tree.
- visit_
mut visit-mut
- Syntax tree traversal to mutate an exclusive borrow of a syntax tree in place.
Macros§
Structs§
- ArgList
- A list of named or unnamed arguments:
{ foo: 42, bar: 64 }
or(42, 64)
. - Assembly
Flags - A list of flags of an assembly statement.
- Block
- A curly-braced block of statements:
{ ... }
. - Catch
Clause - A catch clause of a
StmtTry
:catch { ... }
. - Event
Parameter - An event parameter.
- Expr
Array - An array literal expression:
[a, b, c, d]
. - Expr
Binary - A binary operation:
a + b
,a += b
. - Expr
Call - A function call expression:
foo(42)
orfoo({ bar: 42 })
. - Expr
Call Options - Function call options:
foo.bar{ value: 1, gas: 2 }
. - Expr
Delete - A unary
delete
expression:delete vector
. - Expr
Index - A square bracketed indexing expression:
vector[2]
. - Expr
Member - Access of a named member:
obj.k
. - ExprNew
- A
new
expression:new Contract
. - Expr
Payable - A
payable
expression:payable(address(0x...))
. - Expr
Postfix - A postfix unary expression:
foo++
. - Expr
Ternary - A ternary (AKA conditional) expression:
foo ? bar : baz
. - Expr
Tuple - A tuple expression:
(a, b, c, d)
. - Expr
Type Call - A
type()
expression:type(uint256)
- Expr
Unary - A unary operation:
!x
,-x
. - File
- A Solidity file. The root of the AST.
- Function
Attributes - A list of unique function attributes. Used in ItemFunction.
- HexStr
- A hex string.
- Import
Alias - An import alias.
- Import
Aliases - A list of import aliases:
{ Foo as Bar, Baz } from "foo.sol"
. - Import
Directive - An import directive:
import "foo.sol";
. - Import
Glob - A glob import directive:
* as Foo from "foo.sol"
. - Import
Plain - A plain import directive:
import "foo.sol" as Foo;
. - Inheritance
- A list of inheritance specifiers of an
ItemContract
:is ERC20("Token", "TKN"), Ownable
. - Item
Contract - A contract, abstract contract, interface, or library definition:
contract Foo is Bar("foo"), Baz { ... }
. - Item
Enum - An enum definition:
enum Foo { A, B, C }
. - Item
Error - An error definition:
error Foo(uint256 a, uint256 b);
. - Item
Event - Item
Function - A function, constructor, fallback, receive, or modifier definition:
function helloWorld() external pure returns(string memory);
. - Item
Struct - A struct definition:
struct Foo { uint256 bar; }
. - ItemUdt
- A user-defined value type definition:
type Foo is uint256;
. - LitDenominated
- LitHex
Str - LitStr
- LitUnicode
Str - Modifier
- A modifier invocation, or an inheritance specifier.
- Named
Arg - A named argument in an argument list:
foo: uint256(42)
. - Named
ArgList - A named argument list:
{ foo: uint256(42), bar: true }
. - Override
- The
override
attribute. - Parameters
- A list of VariableDeclarations, separated by
P
. - Pragma
Directive - A pragma directive:
pragma solidity ^0.8.0;
- Returns
- The
returns
attribute of a function. - SolIdent
- A Solidity identifier.
- SolPath
- A list of identifiers, separated by dots.
- Stmt
Assembly - An assembly block, with optional flags:
assembly "evmasm" { ... }
. - Stmt
Break - A break statement:
break;
. - Stmt
Continue - A continue statement:
continue;
. - Stmt
DoWhile - A do-while statement:
do { ... } while (condition);
. - Stmt
Emit - An emit statement:
emit FooBar(42);
. - Stmt
Expr - An expression with a trailing semicolon.
- StmtFor
- A for statement:
for (uint256 i; i < 42; ++i) { ... }
. - StmtIf
- An
if
statement with an optionalelse
block:if (expr) { ... } else { ... }
. - Stmt
Return - A return statement:
return 42;
. - Stmt
Revert - A revert statement:
revert("error");
. - StmtTry
- A try statement:
try fooBar(42) catch { ... }
. - Stmt
VarDecl - A variable declaration statement:
uint256 foo = 42;
. - Stmt
While - A while statement:
while (i < 42) { ... }
. - Type
Array - An array type.
- Type
Function - A function type:
function() returns (string memory)
. - Type
Mapping - A mapping type:
mapping(uint key => string value)
- Type
Tuple - A tuple type.
- Unchecked
Block - An unchecked block:
unchecked { ... }
. - Unicode
Str - A unicode string.
- Using
Directive - A
using
directive:using { A, B.mul as * } for uint256 global;
. - Using
List Item - VarDecl
Tuple - A declaration of variables in a tuple:
(,,uint256 foo,string memory bar)
. - Variable
Attributes - A list of unique variable attributes.
- Variable
Declaration - A variable declaration:
string memory hello
. - Variable
Definition - Variant
- An enum variant.
- Walrus
Token - Represents the walrus operator
:=
. - YulBlock
- A Yul block contains
YulStmt
between curly braces. - YulCase
Branch - Represents a non-default case of a Yul switch statement.
- YulFn
Call - Yul function call.
- YulFor
- Yul for loop e.g
for {let i := 0} lt(i,10) {i := add(i,1)} {mstore(i,7)}
. - YulFunction
Def - Yul function definition:
function f() -> a, b { ... }
. - YulIdent
- A Yul identifier.
- YulIf
- A Yul if statement:
if lt(a, b) { sstore(0, 1) }
. - YulPath
- In inline assembly, only dot-less identifiers can be declared, but dotted paths can reference declarations made outside the assembly block.
- YulReturns
- The return attribute of a Yul function definition.
- YulSwitch
- A Yul switch statement can consist of only a default-case or one or more non-default cases optionally followed by a default-case.
- YulSwitch
Default - Represents the default case of a Yul switch statement.
- YulVar
Assign - Yul variable assignment.
x := 0
orx, y := foo()
. Assigning values to multiple variables requires a function call. - YulVar
Decl - Declares Yul variables, which may or may not have initial values. E.x.
let x := 0
let x
let x, y := foo()
let x, y, z
Enums§
- ArgList
Impl - A list of either unnamed or named arguments.
- BinOp
- A binary operator:
+
,+=
,&
. - Contract
Kind - The kind of contract.
- Expr
- An expression.
- ForInit
Stmt - A for statement initializer.
- Function
Attribute - A function attribute.
- Function
Body - The body of a function.
- Function
Kind - The kind of function.
- Import
Path - The path of an import directive.
- Item
- An AST item. A more expanded version of a Solidity source unit.
- Lit
- A Solidity literal such as a string or integer or boolean.
- LitNumber
- An integer or fixed-point number literal:
1
or1.0
. - Mutability
- A mutability attribute.
- Post
UnOp - Postfix unary operators.
- Pragma
Tokens - Stmt
- A statement, usually ending in a semicolon.
- Storage
- A storage location.
- SubDenomination
- A sub-denomination suffix for a number literal.
- Type
- A type name.
- UnOp
- Unary operators.
- User
Definable Operator - A user-definable operator:
+
,*
,|
, etc. - Using
List - Using
Type - VarDecl
Decl - The declaration of the variable(s) in a variable declaration statement.
- Variable
Attribute - A variable attribute.
- Visibility
- A visibility attribute.
- YulEVM
Built In - Representation of an EVM builtin opcode.
- YulExpr
- A Yul expression.
- YulFn
Type - What type of function is called.
- YulStmt
- A Yul statement.
Functions§
- parse
- Parse a Solidity
proc_macro::TokenStream
into aFile
. - parse2
- Parse a Solidity
proc_macro2::TokenStream
into aFile
.
Type Aliases§
- Field
List - A list of semicolon-separated VariableDeclarations.
- Parameter
List - A list of comma-separated VariableDeclarations.