mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	AST for try and catch.
This commit is contained in:
		
							parent
							
								
									9ecd51c54d
								
							
						
					
					
						commit
						a66c354698
					
				| @ -448,12 +448,16 @@ bool VariableDeclaration::isLocalVariable() const | ||||
| 		dynamic_cast<FunctionTypeName const*>(s) || | ||||
| 		dynamic_cast<CallableDeclaration const*>(s) || | ||||
| 		dynamic_cast<Block const*>(s) || | ||||
| 		dynamic_cast<TryCatchClause const*>(s) || | ||||
| 		dynamic_cast<ForStatement const*>(s); | ||||
| } | ||||
| 
 | ||||
| bool VariableDeclaration::isCallableParameter() const | ||||
| { | ||||
| 	if (isReturnParameter()) | ||||
| 	// TODO Adjust for catch params.
 | ||||
| 	// I think catch params should return true here.
 | ||||
| 	// some of the error strings would need to be adjusted.
 | ||||
| 	if (isReturnParameter() || dynamic_cast<TryCatchClause const*>(scope())) | ||||
| 		return true; | ||||
| 
 | ||||
| 	vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr; | ||||
| @ -472,6 +476,7 @@ bool VariableDeclaration::isCallableParameter() const | ||||
| 
 | ||||
| bool VariableDeclaration::isLocalOrReturn() const | ||||
| { | ||||
| 	// TODO adjust for catch params
 | ||||
| 	return isReturnParameter() || (isLocalVariable() && !isCallableParameter()); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -553,7 +553,7 @@ public: | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Parameter list, used as function parameter list and return list. | ||||
|  * Parameter list, used as function parameter list, return list and for try and catch. | ||||
|  * None of the parameters is allowed to contain mappings (not even recursively | ||||
|  * inside structs). | ||||
|  */ | ||||
| @ -1174,6 +1174,76 @@ private: | ||||
| 	ASTPointer<Statement> m_falseBody; ///< "else" part, optional
 | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Clause of a try-catch block. Includes both the successful case and the | ||||
|  * unsuccessful cases. | ||||
|  * Names are only allowed for the unsuccessful cases. | ||||
|  */ | ||||
| class TryCatchClause: public ASTNode, public Scopable | ||||
| { | ||||
| public: | ||||
| 	TryCatchClause( | ||||
| 		SourceLocation const& _location, | ||||
| 		ASTPointer<ASTString> const& _errorName, | ||||
| 		ASTPointer<ParameterList> const& _parameters, | ||||
| 		ASTPointer<Block> const& _block | ||||
| 	): | ||||
| 		ASTNode(_location), | ||||
| 		m_errorName(_errorName), | ||||
| 		m_parameters(_parameters), | ||||
| 		m_block(_block) | ||||
| 	{} | ||||
| 	void accept(ASTVisitor& _visitor) override; | ||||
| 	void accept(ASTConstVisitor& _visitor) const override; | ||||
| 
 | ||||
| 	ASTString const& errorName() const { return *m_errorName; } | ||||
| 	ParameterList const* parameters() const { return m_parameters.get(); } | ||||
| 	Block const& block() const { return *m_block; } | ||||
| 
 | ||||
| private: | ||||
| 	ASTPointer<ASTString> m_errorName; | ||||
| 	ASTPointer<ParameterList> m_parameters; | ||||
| 	ASTPointer<Block> m_block; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Try-statement with a variable number of catch statements. | ||||
|  * Syntax: | ||||
|  * try <call> returns (uint x, uint y) { | ||||
|  *   // success code
 | ||||
|  * } catch Error(string memory cause) { | ||||
|  *   // error code, reason provided
 | ||||
|  * } catch (bytes memory lowLevelData) { | ||||
|  *   // error code, no reason provided or non-matching error signature.
 | ||||
|  * } | ||||
|  * | ||||
|  * The last statement given above can also be specified as | ||||
|  * } catch () { | ||||
|  */ | ||||
| class TryStatement: public Statement | ||||
| { | ||||
| public: | ||||
| 	TryStatement( | ||||
| 		SourceLocation const& _location, | ||||
| 		ASTPointer<ASTString> const& _docString, | ||||
| 		ASTPointer<Expression> const& _externalCall, | ||||
| 		std::vector<ASTPointer<TryCatchClause>> const& _clauses | ||||
| 	): | ||||
| 		Statement(_location, _docString), | ||||
| 		m_externalCall(_externalCall), | ||||
| 		m_clauses(_clauses) | ||||
| 	{} | ||||
| 	void accept(ASTVisitor& _visitor) override; | ||||
| 	void accept(ASTConstVisitor& _visitor) const override; | ||||
| 
 | ||||
| 	Expression const& externalCall() const { return *m_externalCall; } | ||||
| 	std::vector<ASTPointer<TryCatchClause>> const& clauses() const { return m_clauses; } | ||||
| 
 | ||||
| private: | ||||
| 	ASTPointer<Expression> m_externalCall; | ||||
| 	std::vector<ASTPointer<TryCatchClause>> m_clauses; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Statement in which a break statement is legal (abstract class). | ||||
|  */ | ||||
|  | ||||
| @ -218,6 +218,8 @@ enum class FunctionCallKind | ||||
| struct FunctionCallAnnotation: ExpressionAnnotation | ||||
| { | ||||
| 	FunctionCallKind kind = FunctionCallKind::Unset; | ||||
| 	/// If true, this is the external call of a try statement.
 | ||||
| 	bool tryCall = false; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -64,6 +64,8 @@ class Statement; | ||||
| class Block; | ||||
| class PlaceholderStatement; | ||||
| class IfStatement; | ||||
| class TryCatchClause; | ||||
| class TryStatement; | ||||
| class BreakableStatement; | ||||
| class WhileStatement; | ||||
| class ForStatement; | ||||
|  | ||||
| @ -499,6 +499,25 @@ bool ASTJsonConverter::visit(IfStatement const& _node) | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool ASTJsonConverter::visit(TryCatchClause const& _node) | ||||
| { | ||||
| 	setJsonNode(_node, "TryCatchClause", { | ||||
| 		make_pair("errorName", _node.errorName()), | ||||
| 		make_pair("parameters", toJsonOrNull(_node.parameters())), | ||||
| 		make_pair("block", toJson(_node.block())) | ||||
| 	}); | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool ASTJsonConverter::visit(TryStatement const& _node) | ||||
| { | ||||
| 	setJsonNode(_node, "TryStatement", { | ||||
| 		make_pair("externalCall", toJson(_node.externalCall())), | ||||
| 		make_pair("clauses", toJson(_node.clauses())) | ||||
| 	}); | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool ASTJsonConverter::visit(WhileStatement const& _node) | ||||
| { | ||||
| 	setJsonNode( | ||||
| @ -647,7 +666,8 @@ bool ASTJsonConverter::visit(FunctionCall const& _node) | ||||
| 	std::vector<pair<string, Json::Value>> attributes = { | ||||
| 		make_pair("expression", toJson(_node.expression())), | ||||
| 		make_pair("names", std::move(names)), | ||||
| 		make_pair("arguments", toJson(_node.arguments())) | ||||
| 		make_pair("arguments", toJson(_node.arguments())), | ||||
| 		make_pair("tryCall", _node.annotation().tryCall) | ||||
| 	}; | ||||
| 	if (m_legacy) | ||||
| 	{ | ||||
|  | ||||
| @ -93,6 +93,8 @@ public: | ||||
| 	bool visit(Block const& _node) override; | ||||
| 	bool visit(PlaceholderStatement const& _node) override; | ||||
| 	bool visit(IfStatement const& _node) override; | ||||
| 	bool visit(TryCatchClause const& _node) override; | ||||
| 	bool visit(TryStatement const& _node) override; | ||||
| 	bool visit(WhileStatement const& _node) override; | ||||
| 	bool visit(ForStatement const& _node) override; | ||||
| 	bool visit(Continue const& _node) override; | ||||
|  | ||||
| @ -69,6 +69,8 @@ public: | ||||
| 	virtual bool visit(Block& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(PlaceholderStatement& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(IfStatement& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(TryCatchClause& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(TryStatement& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(WhileStatement& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(ForStatement& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(Continue& _node) { return visitNode(_node); } | ||||
| @ -117,6 +119,8 @@ public: | ||||
| 	virtual void endVisit(Block& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(PlaceholderStatement& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(IfStatement& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(TryCatchClause& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(TryStatement& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(WhileStatement& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(ForStatement& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(Continue& _node) { endVisitNode(_node); } | ||||
| @ -177,6 +181,8 @@ public: | ||||
| 	virtual bool visit(Block const& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(PlaceholderStatement const& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(IfStatement const& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(TryCatchClause const& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(TryStatement const& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(WhileStatement const& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(ForStatement const& _node) { return visitNode(_node); } | ||||
| 	virtual bool visit(Continue const& _node) { return visitNode(_node); } | ||||
| @ -225,6 +231,8 @@ public: | ||||
| 	virtual void endVisit(Block const& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(PlaceholderStatement const& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(IfStatement const& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(TryCatchClause const& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(TryStatement const& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(WhileStatement const& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(ForStatement const& _node) { endVisitNode(_node); } | ||||
| 	virtual void endVisit(Continue const& _node) { endVisitNode(_node); } | ||||
|  | ||||
| @ -461,6 +461,48 @@ void IfStatement::accept(ASTConstVisitor& _visitor) const | ||||
| 	_visitor.endVisit(*this); | ||||
| } | ||||
| 
 | ||||
| void TryCatchClause::accept(ASTVisitor& _visitor) | ||||
| { | ||||
| 	if (_visitor.visit(*this)) | ||||
| 	{ | ||||
| 		if (m_parameters) | ||||
| 			m_parameters->accept(_visitor); | ||||
| 		m_block->accept(_visitor); | ||||
| 	} | ||||
| 	_visitor.endVisit(*this); | ||||
| } | ||||
| 
 | ||||
| void TryCatchClause::accept(ASTConstVisitor& _visitor) const | ||||
| { | ||||
| 	if (_visitor.visit(*this)) | ||||
| 	{ | ||||
| 		if (m_parameters) | ||||
| 			m_parameters->accept(_visitor); | ||||
| 		m_block->accept(_visitor); | ||||
| 	} | ||||
| 	_visitor.endVisit(*this); | ||||
| } | ||||
| 
 | ||||
| void TryStatement::accept(ASTVisitor& _visitor) | ||||
| { | ||||
| 	if (_visitor.visit(*this)) | ||||
| 	{ | ||||
| 		m_externalCall->accept(_visitor); | ||||
| 		listAccept(m_clauses, _visitor); | ||||
| 	} | ||||
| 	_visitor.endVisit(*this); | ||||
| } | ||||
| 
 | ||||
| void TryStatement::accept(ASTConstVisitor& _visitor) const | ||||
| { | ||||
| 	if (_visitor.visit(*this)) | ||||
| 	{ | ||||
| 		m_externalCall->accept(_visitor); | ||||
| 		listAccept(m_clauses, _visitor); | ||||
| 	} | ||||
| 	_visitor.endVisit(*this); | ||||
| } | ||||
| 
 | ||||
| void WhileStatement::accept(ASTVisitor& _visitor) | ||||
| { | ||||
| 	if (_visitor.visit(*this)) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user