mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #1245 from ethereum/1215
Allow multiple events of the same name
This commit is contained in:
		
						commit
						b52a60402d
					
				| @ -6,6 +6,7 @@ Features: | ||||
|  * AST: Use deterministic node identifiers. | ||||
|  * Type system: Introduce type identifier strings. | ||||
|  * Metadata: Do not include platform in the version number. | ||||
|  * Type checker: Allow multiple events of the same name (but with different arities or argument types) | ||||
| 
 | ||||
| ### 0.4.8 (2017-01-13) | ||||
| 
 | ||||
|  | ||||
| @ -42,20 +42,32 @@ Declaration const* DeclarationContainer::conflictingDeclaration( | ||||
| 	if (m_invisibleDeclarations.count(*_name)) | ||||
| 		declarations += m_invisibleDeclarations.at(*_name); | ||||
| 
 | ||||
| 	if (dynamic_cast<FunctionDefinition const*>(&_declaration)) | ||||
| 	if ( | ||||
| 		dynamic_cast<FunctionDefinition const*>(&_declaration) || | ||||
| 		dynamic_cast<EventDefinition const*>(&_declaration) | ||||
| 	) | ||||
| 	{ | ||||
| 		// check that all other declarations with the same name are functions or a public state variable
 | ||||
| 		// check that all other declarations with the same name are functions or a public state variable or events.
 | ||||
| 		// And then check that the signatures are different.
 | ||||
| 		for (Declaration const* declaration: declarations) | ||||
| 		{ | ||||
| 			if (dynamic_cast<FunctionDefinition const*>(declaration)) | ||||
| 				continue; | ||||
| 			if (auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(declaration)) | ||||
| 			{ | ||||
| 				if (variableDeclaration->isStateVariable() && !variableDeclaration->isConstant() && variableDeclaration->isPublic()) | ||||
| 					continue; | ||||
| 				return declaration; | ||||
| 			} | ||||
| 			return declaration; | ||||
| 			if ( | ||||
| 				dynamic_cast<FunctionDefinition const*>(&_declaration) && | ||||
| 				!dynamic_cast<FunctionDefinition const*>(declaration) | ||||
| 			) | ||||
| 				return declaration; | ||||
| 			if ( | ||||
| 				dynamic_cast<EventDefinition const*>(&_declaration) && | ||||
| 				!dynamic_cast<EventDefinition const*>(declaration) | ||||
| 			) | ||||
| 				return declaration; | ||||
| 			// Or, continue.
 | ||||
| 		} | ||||
| 	} | ||||
| 	else if (declarations.size() == 1 && declarations.front() == &_declaration) | ||||
|  | ||||
| @ -260,8 +260,8 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations( | ||||
| 	for (auto it = _declarations.begin(); it != _declarations.end(); ++it) | ||||
| 	{ | ||||
| 		solAssert(*it, ""); | ||||
| 		// the declaration is functionDefinition or a VariableDeclaration while declarations > 1
 | ||||
| 		solAssert(dynamic_cast<FunctionDefinition const*>(*it) || dynamic_cast<VariableDeclaration const*>(*it), | ||||
| 		// the declaration is functionDefinition, eventDefinition or a VariableDeclaration while declarations > 1
 | ||||
| 		solAssert(dynamic_cast<FunctionDefinition const*>(*it) || dynamic_cast<EventDefinition const*>(*it) || dynamic_cast<VariableDeclaration const*>(*it), | ||||
| 			"Found overloading involving something not a function or a variable"); | ||||
| 
 | ||||
| 		shared_ptr<FunctionType const> functionType { (*it)->functionType(false) }; | ||||
|  | ||||
| @ -2771,6 +2771,7 @@ BOOST_AUTO_TEST_CASE(event_no_arguments) | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
| 
 | ||||
| 	compileAndRun(sourceCode); | ||||
| 	callContractFunction("deposit()"); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs.size(), 1); | ||||
| @ -2802,6 +2803,104 @@ BOOST_AUTO_TEST_CASE(event_access_through_base_name) | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("x()"))); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(events_with_same_name) | ||||
| { | ||||
| 	char const* sourceCode = R"( | ||||
| 		contract ClientReceipt { | ||||
| 			event Deposit; | ||||
| 			event Deposit(address _addr); | ||||
| 			event Deposit(address _addr, uint _amount); | ||||
| 			function deposit() returns (uint) { | ||||
| 				Deposit(); | ||||
| 				return 1; | ||||
| 			} | ||||
| 			function deposit(address _addr) returns (uint) { | ||||
| 				Deposit(_addr); | ||||
| 				return 1; | ||||
| 			} | ||||
| 			function deposit(address _addr, uint _amount) returns (uint) { | ||||
| 				Deposit(_addr, _amount); | ||||
| 				return 1; | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
| 	u160 const c_loggedAddress = m_contractAddress; | ||||
| 
 | ||||
| 	compileAndRun(sourceCode); | ||||
| 	BOOST_CHECK(callContractFunction("deposit()") == encodeArgs(u256(1))); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); | ||||
| 	BOOST_CHECK(m_logs[0].data.empty()); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()"))); | ||||
| 
 | ||||
| 	BOOST_CHECK(callContractFunction("deposit(address)", c_loggedAddress) == encodeArgs(u256(1))); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); | ||||
| 	BOOST_CHECK(m_logs[0].data == encodeArgs(c_loggedAddress)); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address)"))); | ||||
| 
 | ||||
| 	BOOST_CHECK(callContractFunction("deposit(address,uint256)", c_loggedAddress, u256(100)) == encodeArgs(u256(1))); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); | ||||
| 	BOOST_CHECK(m_logs[0].data == encodeArgs(c_loggedAddress, 100)); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,uint256)"))); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(events_with_same_name_inherited) | ||||
| { | ||||
| 	char const* sourceCode = R"( | ||||
| 		contract A { | ||||
| 			event Deposit; | ||||
| 		} | ||||
| 
 | ||||
| 		contract B { | ||||
| 			event Deposit(address _addr); | ||||
| 		} | ||||
| 
 | ||||
| 		contract ClientReceipt is A, B { | ||||
| 			event Deposit(address _addr, uint _amount); | ||||
| 			function deposit() returns (uint) { | ||||
| 				Deposit(); | ||||
| 				return 1; | ||||
| 			} | ||||
| 			function deposit(address _addr) returns (uint) { | ||||
| 				Deposit(_addr); | ||||
| 				return 1; | ||||
| 			} | ||||
| 			function deposit(address _addr, uint _amount) returns (uint) { | ||||
| 				Deposit(_addr, _amount); | ||||
| 				return 1; | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
| 	u160 const c_loggedAddress = m_contractAddress; | ||||
| 
 | ||||
| 	compileAndRun(sourceCode); | ||||
| 	BOOST_CHECK(callContractFunction("deposit()") == encodeArgs(u256(1))); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); | ||||
| 	BOOST_CHECK(m_logs[0].data.empty()); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()"))); | ||||
| 
 | ||||
| 	BOOST_CHECK(callContractFunction("deposit(address)", c_loggedAddress) == encodeArgs(u256(1))); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); | ||||
| 	BOOST_CHECK(m_logs[0].data == encodeArgs(c_loggedAddress)); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address)"))); | ||||
| 
 | ||||
| 	BOOST_CHECK(callContractFunction("deposit(address,uint256)", c_loggedAddress, u256(100)) == encodeArgs(u256(1))); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); | ||||
| 	BOOST_CHECK(m_logs[0].data == encodeArgs(c_loggedAddress, 100)); | ||||
| 	BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); | ||||
| 	BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,uint256)"))); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(event_anonymous) | ||||
| { | ||||
| 	char const* sourceCode = R"( | ||||
|  | ||||
| @ -1365,6 +1365,17 @@ BOOST_AUTO_TEST_CASE(anonymous_event_too_many_indexed) | ||||
| 	CHECK_ERROR(text, TypeError, ""); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(events_with_same_name) | ||||
| { | ||||
| 	char const* text = R"( | ||||
| 		contract TestIt { | ||||
| 			event A(); | ||||
| 			event A(uint i); | ||||
| 		} | ||||
| 	)"; | ||||
| 	BOOST_CHECK(success(text)); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(event_call) | ||||
| { | ||||
| 	char const* text = R"( | ||||
| @ -1376,6 +1387,53 @@ BOOST_AUTO_TEST_CASE(event_call) | ||||
| 	CHECK_SUCCESS(text); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(event_function_inheritance_clash) | ||||
| { | ||||
| 	char const* text = R"( | ||||
| 		contract A { | ||||
| 			function dup() returns (uint) { | ||||
| 				return 1; | ||||
| 			} | ||||
| 		} | ||||
| 		contract B { | ||||
| 			event dup(); | ||||
| 		} | ||||
| 		contract C is A, B { | ||||
| 		} | ||||
| 	)"; | ||||
| 	CHECK_ERROR(text, DeclarationError, "Identifier already declared."); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(function_event_inheritance_clash) | ||||
| { | ||||
| 	char const* text = R"( | ||||
| 		contract B { | ||||
| 			event dup(); | ||||
| 		} | ||||
| 		contract A { | ||||
| 			function dup() returns (uint) { | ||||
| 				return 1; | ||||
| 			} | ||||
| 		} | ||||
| 		contract C is B, A { | ||||
| 		} | ||||
| 	)"; | ||||
| 	CHECK_ERROR(text, DeclarationError, "Identifier already declared."); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(function_event_in_contract_clash) | ||||
| { | ||||
| 	char const* text = R"( | ||||
| 		contract A { | ||||
| 			event dup(); | ||||
| 			function dup() returns (uint) { | ||||
| 				return 1; | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
| 	CHECK_ERROR(text, DeclarationError, "Identifier already declared."); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(event_inheritance) | ||||
| { | ||||
| 	char const* text = R"( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user