Kaynağa Gözat

Parse revert statements with named arguments

	revert Foo({bar: 1});

These can only be used with custom errors, which are not supported yet.
However, amend the parser so that we can give a nicer error message.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 3 yıl önce
ebeveyn
işleme
3616e42080

+ 2 - 0
solang-parser/src/pt.rs

@@ -641,6 +641,7 @@ pub enum Statement {
     Break(Loc),
     Return(Loc, Option<Expression>),
     Revert(Loc, Option<Expression>, Vec<Expression>),
+    RevertNamedArgs(Loc, Option<Expression>, Vec<NamedArgument>),
     Emit(Loc, Expression),
     Try(
         Loc,
@@ -759,6 +760,7 @@ impl CodeLocation for Statement {
             | Statement::Break(loc)
             | Statement::Return(loc, ..)
             | Statement::Revert(loc, ..)
+            | Statement::RevertNamedArgs(loc, ..)
             | Statement::Emit(loc, ..)
             | Statement::Try(loc, ..) => *loc,
             Statement::DocComment(comment) => comment.loc,

+ 3 - 0
solang-parser/src/solidity.lalrpop

@@ -812,6 +812,9 @@ NonIfStatement: Statement = {
     <l:@L> "revert" <error:SolIdentifierNamespace?> "(" <v:Comma<Expression>> ")" <r:@R> ";" => {
         Statement::Revert(Loc::File(file_no, l, r), error, v)
     },
+    <l:@L> "revert" <error:SolIdentifierNamespace?> "(" "{" <v:Comma<NamedArgument>> "}" ")" <r:@R> ";" => {
+        Statement::RevertNamedArgs(Loc::File(file_no, l, r), error, v)
+    },
 }
 
 YulIdentifier: Identifier = {

+ 7 - 0
src/sema/statements.rs

@@ -868,6 +868,13 @@ fn statement(
 
             Ok(reachable)
         }
+        pt::Statement::RevertNamedArgs(loc, _, _) => {
+            ns.diagnostics.push(Diagnostic::error(
+                *loc,
+                "revert with custom errors or named arguments not supported yet".to_string(),
+            ));
+            Err(())
+        }
         pt::Statement::DocComment(..) => Ok(true),
     }
 }

+ 12 - 8
tests/contract_testcases/solana/import_contracts_via_object.dot

@@ -4,21 +4,25 @@ strict digraph "tests/contract_testcases/solana/import_contracts_via_object.sol"
 	base [label="base A\ntests/contract_testcases/solana/import_contracts_via_object.sol:3:15-20"]
 	using [label="library L"]
 	node_6 [label="constructor \ncontract: C\ntests/contract_testcases/solana/import_contracts_via_object.sol:5:2-23\nsignature ()\nvisibility public\nmutability nonpayable"]
-	contract_7 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-12"]
-	contract_8 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:11"]
+	foo [label="function foo\ncontract: C\ntests/contract_testcases/solana/import_contracts_via_object.sol:8:2-23\nsignature foo()\nvisibility public\nmutability nonpayable"]
+	contract_8 [label="contract A\ntests/contract_testcases/solana/simple.sol:1:1-12"]
+	contract_9 [label="contract L\ntests/contract_testcases/solana/simple.sol:1:14-2:11"]
 	diagnostic [label="found contract 'A'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:1-12"]
-	diagnostic_11 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:11"]
-	diagnostic_12 [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/import_contracts_via_object.sol:2:1-3:20"]
-	diagnostic_13 [label="revert with custom error 'IMP.E' not supported yet\nlevel Error\ntests/contract_testcases/solana/import_contracts_via_object.sol:6:10-15"]
+	diagnostic_12 [label="found library 'L'\nlevel Debug\ntests/contract_testcases/solana/simple.sol:1:14-2:11"]
+	diagnostic_13 [label="found contract 'C'\nlevel Debug\ntests/contract_testcases/solana/import_contracts_via_object.sol:2:1-3:20"]
+	diagnostic_14 [label="revert with custom error 'IMP.E' not supported yet\nlevel Error\ntests/contract_testcases/solana/import_contracts_via_object.sol:6:10-15"]
+	diagnostic_15 [label="revert with custom errors or named arguments not supported yet\nlevel Error\ntests/contract_testcases/solana/import_contracts_via_object.sol:9:3-25"]
 	structs -> S
 	contracts -> contract
 	contract -> base [label="base"]
 	contract -> using [label="base"]
 	contract -> node_6 [label="constructor"]
-	contracts -> contract_7
+	contract -> foo [label="function"]
 	contracts -> contract_8
+	contracts -> contract_9
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_11 [label="Debug"]
 	diagnostics -> diagnostic_12 [label="Debug"]
-	diagnostics -> diagnostic_13 [label="Error"]
+	diagnostics -> diagnostic_13 [label="Debug"]
+	diagnostics -> diagnostic_14 [label="Error"]
+	diagnostics -> diagnostic_15 [label="Error"]
 }

+ 3 - 0
tests/contract_testcases/solana/import_contracts_via_object.sol

@@ -5,4 +5,7 @@ contract C is IMP.A {
 	constructor() IMP.A() {
 		revert IMP.E();
 	}
+	function foo() public {
+		revert IMP.E({foo: 1});
+	}
 }