mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #5817 from ethereum/refactoring
Refactoring in TypeChecker and ContractDefinition
This commit is contained in:
		
						commit
						7b759866cb
					
				| @ -262,7 +262,7 @@ bool SyntaxChecker::visit(PlaceholderStatement const&) | ||||
| 
 | ||||
| bool SyntaxChecker::visit(ContractDefinition const& _contract) | ||||
| { | ||||
| 	m_isInterface = _contract.contractKind() == ContractDefinition::ContractKind::Interface; | ||||
| 	m_isInterface = _contract.isInterface(); | ||||
| 
 | ||||
| 	ASTString const& contractName = _contract.name(); | ||||
| 	for (FunctionDefinition const* function: _contract.definedFunctions()) | ||||
|  | ||||
| @ -236,7 +236,7 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) | ||||
| 	auto base = dynamic_cast<ContractDefinition const*>(&dereference(_inheritance.name())); | ||||
| 	solAssert(base, "Base contract not available."); | ||||
| 
 | ||||
| 	if (m_scope->contractKind() == ContractDefinition::ContractKind::Interface) | ||||
| 	if (m_scope->isInterface()) | ||||
| 		m_errorReporter.typeError(_inheritance.location(), "Interfaces cannot inherit."); | ||||
| 
 | ||||
| 	if (base->isLibrary()) | ||||
| @ -244,7 +244,7 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) | ||||
| 
 | ||||
| 	auto const& arguments = _inheritance.arguments(); | ||||
| 	TypePointers parameterTypes; | ||||
| 	if (base->contractKind() != ContractDefinition::ContractKind::Interface) | ||||
| 	if (!base->isInterface()) | ||||
| 		// Interfaces do not have constructors, so there are zero parameters.
 | ||||
| 		parameterTypes = ContractType(*base).newExpressionType()->parameterTypes(); | ||||
| 
 | ||||
| @ -331,33 +331,40 @@ bool TypeChecker::visit(FunctionDefinition const& _function) | ||||
| 		if (!_function.isConstructor() && !_function.isFallback() && !_function.isPartOfExternalInterface()) | ||||
| 			m_errorReporter.typeError(_function.location(), "Internal functions cannot be payable."); | ||||
| 	} | ||||
| 	for (ASTPointer<VariableDeclaration> const& var: _function.parameters() + _function.returnParameters()) | ||||
| 	{ | ||||
| 		if (type(*var)->category() == Type::Category::Mapping) | ||||
| 	auto checkArgumentAndReturnParameter = [&](VariableDeclaration const& var) { | ||||
| 		if (type(var)->category() == Type::Category::Mapping) | ||||
| 		{ | ||||
| 			if (!type(*var)->dataStoredIn(DataLocation::Storage)) | ||||
| 				m_errorReporter.typeError(var->location(), "Mapping types can only have a data location of \"storage\"." ); | ||||
| 			if (!type(var)->dataStoredIn(DataLocation::Storage)) | ||||
| 				m_errorReporter.typeError(var.location(), "Mapping types can only have a data location of \"storage\"." ); | ||||
| 			else if (!isLibraryFunction && _function.isPublic()) | ||||
| 				m_errorReporter.typeError(var->location(), "Mapping types for parameters or return variables can only be used in internal or library functions."); | ||||
| 				m_errorReporter.typeError(var.location(), "Mapping types for parameters or return variables can only be used in internal or library functions."); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (!type(*var)->canLiveOutsideStorage() && _function.isPublic()) | ||||
| 				m_errorReporter.typeError(var->location(), "Type is required to live outside storage."); | ||||
| 			if (_function.isPublic() && !(type(*var)->interfaceType(isLibraryFunction))) | ||||
| 				m_errorReporter.fatalTypeError(var->location(), "Internal or recursive type is not allowed for public or external functions."); | ||||
| 			if (!type(var)->canLiveOutsideStorage() && _function.isPublic()) | ||||
| 				m_errorReporter.typeError(var.location(), "Type is required to live outside storage."); | ||||
| 			if (_function.isPublic() && !(type(var)->interfaceType(isLibraryFunction))) | ||||
| 				m_errorReporter.fatalTypeError(var.location(), "Internal or recursive type is not allowed for public or external functions."); | ||||
| 		} | ||||
| 		if ( | ||||
| 			_function.isPublic() && | ||||
| 			!_function.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2) && | ||||
| 			!typeSupportedByOldABIEncoder(*type(*var)) | ||||
| 			!typeSupportedByOldABIEncoder(*type(var)) | ||||
| 		) | ||||
| 			m_errorReporter.typeError( | ||||
| 				var->location(), | ||||
| 				var.location(), | ||||
| 				"This type is only supported in the new experimental ABI encoder. " | ||||
| 				"Use \"pragma experimental ABIEncoderV2;\" to enable the feature." | ||||
| 			); | ||||
| 
 | ||||
| 	}; | ||||
| 	for (ASTPointer<VariableDeclaration> const& var: _function.parameters()) | ||||
| 	{ | ||||
| 		checkArgumentAndReturnParameter(*var); | ||||
| 		var->accept(*this); | ||||
| 	} | ||||
| 	for (ASTPointer<VariableDeclaration> const& var: _function.returnParameters()) | ||||
| 	{ | ||||
| 		checkArgumentAndReturnParameter(*var); | ||||
| 		var->accept(*this); | ||||
| 	} | ||||
| 	set<Declaration const*> modifiers; | ||||
| @ -378,7 +385,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) | ||||
| 		else | ||||
| 			modifiers.insert(decl); | ||||
| 	} | ||||
| 	if (m_scope->contractKind() == ContractDefinition::ContractKind::Interface) | ||||
| 	if (m_scope->isInterface()) | ||||
| 	{ | ||||
| 		if (_function.isImplemented()) | ||||
| 			m_errorReporter.typeError(_function.location(), "Functions in interfaces cannot have an implementation."); | ||||
| @ -407,7 +414,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) | ||||
| 	// * a function's input/output parameters,
 | ||||
| 	// * or inside of a struct definition.
 | ||||
| 	if ( | ||||
| 		m_scope->contractKind() == ContractDefinition::ContractKind::Interface | ||||
| 		m_scope->isInterface() | ||||
| 		&& !_variable.isCallableParameter() | ||||
| 		&& !m_insideStruct | ||||
| 	) | ||||
| @ -1906,7 +1913,7 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) | ||||
| 
 | ||||
| 		if (!contract) | ||||
| 			m_errorReporter.fatalTypeError(_newExpression.location(), "Identifier is not a contract."); | ||||
| 		if (contract->contractKind() == ContractDefinition::ContractKind::Interface) | ||||
| 		if (contract->isInterface()) | ||||
| 			m_errorReporter.fatalTypeError(_newExpression.location(), "Cannot instantiate an interface."); | ||||
| 		if (!contract->annotation().unimplementedFunctions.empty()) | ||||
| 		{ | ||||
|  | ||||
| @ -394,6 +394,7 @@ public: | ||||
| 	std::vector<FunctionDefinition const*> definedFunctions() const { return filteredNodes<FunctionDefinition>(m_subNodes); } | ||||
| 	std::vector<EventDefinition const*> events() const { return filteredNodes<EventDefinition>(m_subNodes); } | ||||
| 	std::vector<EventDefinition const*> const& interfaceEvents() const; | ||||
| 	bool isInterface() const { return m_contractKind == ContractKind::Interface; } | ||||
| 	bool isLibrary() const { return m_contractKind == ContractKind::Library; } | ||||
| 
 | ||||
| 	/// @returns a map of canonical function signatures to FunctionDefinitions
 | ||||
|  | ||||
| @ -2525,7 +2525,7 @@ FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _c | ||||
| 	strings parameterNames; | ||||
| 	StateMutability stateMutability = StateMutability::NonPayable; | ||||
| 
 | ||||
| 	solAssert(_contract.contractKind() != ContractDefinition::ContractKind::Interface, ""); | ||||
| 	solAssert(!_contract.isInterface(), ""); | ||||
| 
 | ||||
| 	if (constructor) | ||||
| 	{ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user