Browse Source

Merge pull request #738 from LefterisJP/sol_abiFunctionHash

Canonical Function signature creation in solidity
cl-refactor
Gav Wood 10 years ago
parent
commit
16c0e14f2d
  1. 5
      libsolidity/AST.cpp
  2. 5
      libsolidity/AST.h
  3. 10
      libsolidity/Types.cpp
  4. 1
      libsolidity/Types.h
  5. 38
      test/SolidityNameAndTypeResolution.cpp

5
libsolidity/AST.cpp

@ -110,6 +110,11 @@ void FunctionDefinition::checkTypeRequirements()
m_body->checkTypeRequirements();
}
string FunctionDefinition::getCanonicalSignature() const
{
return getName() + FunctionType(*this).getCanonicalSignature();
}
void Block::checkTypeRequirements()
{
for (shared_ptr<Statement> const& statement: m_statements)

5
libsolidity/AST.h

@ -277,6 +277,11 @@ public:
/// Checks that all parameters have allowed types and calls checkTypeRequirements on the body.
void checkTypeRequirements();
/// @returns the canonical signature of the function
/// That consists of the name of the function followed by the types of the
/// arguments separated by commas all enclosed in parentheses without any spaces.
std::string getCanonicalSignature() const;
private:
bool m_isPublic;
ASTPointer<ParameterList> m_parameters;

10
libsolidity/Types.cpp

@ -484,6 +484,16 @@ unsigned FunctionType::getSizeOnStack() const
}
}
string FunctionType::getCanonicalSignature() const
{
string ret = "(";
for (auto it = m_parameterTypes.cbegin(); it != m_parameterTypes.cend(); ++it)
ret += (*it)->toString() + (it + 1 == m_parameterTypes.cend() ? "" : ",");
return ret + ")";
}
bool MappingType::operator==(Type const& _other) const
{
if (_other.getCategory() != getCategory())

1
libsolidity/Types.h

@ -338,6 +338,7 @@ public:
virtual unsigned getSizeOnStack() const override;
Location const& getLocation() const { return m_location; }
std::string getCanonicalSignature() const;
private:
TypePointers m_parameterTypes;

38
test/SolidityNameAndTypeResolution.cpp

@ -38,7 +38,7 @@ namespace test
namespace
{
void parseTextAndResolveNames(std::string const& _source)
ASTPointer<SourceUnit> parseTextAndResolveNames(std::string const& _source)
{
Parser parser;
ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
@ -50,6 +50,8 @@ void parseTextAndResolveNames(std::string const& _source)
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
resolver.checkTypeRequirements(*contract);
return sourceUnit;
}
}
@ -321,6 +323,40 @@ BOOST_AUTO_TEST_CASE(comparison_bitop_precedence)
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(function_canonical_signature)
{
ASTPointer<SourceUnit> sourceUnit;
char const* text = "contract Test {\n"
" function foo(uint256 arg1, uint64 arg2, bool arg3) returns (uint256 ret) {\n"
" ret = arg1 + arg2;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(sourceUnit = parseTextAndResolveNames(text));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
BOOST_CHECK_EQUAL("foo(uint256,uint64,bool)", functions[0]->getCanonicalSignature());
}
}
BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases)
{
ASTPointer<SourceUnit> sourceUnit;
char const* text = "contract Test {\n"
" function boo(uint arg1, hash arg2, address arg3) returns (uint ret) {\n"
" ret = 5;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(sourceUnit = parseTextAndResolveNames(text));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
BOOST_CHECK_EQUAL("boo(uint256,hash256,address)", functions[0]->getCanonicalSignature());
}
}
BOOST_AUTO_TEST_SUITE_END()
}

Loading…
Cancel
Save