mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
further optimization, splitting function into pieces
generating strings on the fly, changed name, and added two tests
This commit is contained in:
parent
d2c0712f36
commit
9b67969fd6
@ -117,9 +117,9 @@ u256 const& MemberList::storageSize() const
|
|||||||
|
|
||||||
TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
|
TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
|
||||||
{
|
{
|
||||||
string tokenString = _type.toString();
|
|
||||||
solAssert(Token::isElementaryTypeName(_type.token()),
|
solAssert(Token::isElementaryTypeName(_type.token()),
|
||||||
"Expected an elementary type name but got " + tokenString);
|
"Expected an elementary type name but got " + _type.toString()
|
||||||
|
);
|
||||||
|
|
||||||
Token::Value token = _type.token();
|
Token::Value token = _type.token();
|
||||||
unsigned int m = _type.firstNumber();
|
unsigned int m = _type.firstNumber();
|
||||||
|
@ -53,7 +53,6 @@ namespace solidity
|
|||||||
void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second)
|
void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second)
|
||||||
{
|
{
|
||||||
solAssert(Token::isElementaryTypeName(_baseType), "");
|
solAssert(Token::isElementaryTypeName(_baseType), "");
|
||||||
string tokenString = Token::toString(_baseType);
|
|
||||||
if (_baseType == Token::BytesM)
|
if (_baseType == Token::BytesM)
|
||||||
{
|
{
|
||||||
solAssert(_second == 0, "There should not be a second size argument to type bytesM.");
|
solAssert(_second == 0, "There should not be a second size argument to type bytesM.");
|
||||||
@ -61,10 +60,10 @@ void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned con
|
|||||||
}
|
}
|
||||||
else if (_baseType == Token::UIntM || _baseType == Token::IntM)
|
else if (_baseType == Token::UIntM || _baseType == Token::IntM)
|
||||||
{
|
{
|
||||||
solAssert(_second == 0, "There should not be a second size argument to type " + tokenString + ".");
|
solAssert(_second == 0, "There should not be a second size argument to type " + string(Token::toString(_baseType)) + ".");
|
||||||
solAssert(
|
solAssert(
|
||||||
_first <= 256 && _first % 8 == 0,
|
_first <= 256 && _first % 8 == 0,
|
||||||
"No elementary type " + tokenString + to_string(_first) + "."
|
"No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
m_token = _baseType;
|
m_token = _baseType;
|
||||||
@ -120,26 +119,30 @@ tuple<Token::Value, unsigned short, unsigned short> Token::fromIdentifierOrKeywo
|
|||||||
if (positionM != _literal.end())
|
if (positionM != _literal.end())
|
||||||
{
|
{
|
||||||
string baseType(_literal.begin(), positionM);
|
string baseType(_literal.begin(), positionM);
|
||||||
auto positionX = find(positionM, _literal.end(), 'x');
|
auto positionX = find_if_not(positionM, _literal.end(), ::isdigit);
|
||||||
unsigned short m = extractM(string(positionM, positionX));
|
unsigned short m = extractM(string(positionM, positionX));
|
||||||
if (baseType == toString(Token::Bytes))
|
Token::Value keyword = keywordByName(baseType);
|
||||||
|
if (keyword == Token::Bytes)
|
||||||
{
|
{
|
||||||
if (0 < m && m <= 32)
|
if (0 < m && m <= 32 && positionX == _literal.end())
|
||||||
return make_tuple(Token::BytesM, m, 0);
|
return make_tuple(Token::BytesM, m, 0);
|
||||||
return make_tuple(Token::Identifier, 0, 0);
|
|
||||||
}
|
}
|
||||||
else if (baseType == toString(Token::UInt) || baseType == toString(Token::Int))
|
else if (keyword == Token::UInt || keyword == Token::Int)
|
||||||
{
|
{
|
||||||
if (0 < m && m <= 256 && m % 8 == 0)
|
if (0 < m && m <= 256 && m % 8 == 0 && positionX == _literal.end())
|
||||||
{
|
{
|
||||||
if (baseType == toString(Token::UInt))
|
if (keyword == Token::UInt)
|
||||||
return make_tuple(Token::UIntM, m, 0);
|
return make_tuple(Token::UIntM, m, 0);
|
||||||
else
|
else
|
||||||
return make_tuple(Token::IntM, m, 0);
|
return make_tuple(Token::IntM, m, 0);
|
||||||
}
|
}
|
||||||
return make_tuple(Token::Identifier, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
return make_tuple(Token::Identifier, 0, 0);
|
||||||
}
|
}
|
||||||
|
return make_tuple(keywordByName(_literal), 0, 0);
|
||||||
|
}
|
||||||
|
Token::Value Token::keywordByName(string const& _name)
|
||||||
|
{
|
||||||
// The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored
|
// The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored
|
||||||
// and keywords to be put inside the keywords variable.
|
// and keywords to be put inside the keywords variable.
|
||||||
#define KEYWORD(name, string, precedence) {string, Token::name},
|
#define KEYWORD(name, string, precedence) {string, Token::name},
|
||||||
@ -147,12 +150,11 @@ tuple<Token::Value, unsigned short, unsigned short> Token::fromIdentifierOrKeywo
|
|||||||
static const map<string, Token::Value> keywords({TOKEN_LIST(TOKEN, KEYWORD)});
|
static const map<string, Token::Value> keywords({TOKEN_LIST(TOKEN, KEYWORD)});
|
||||||
#undef KEYWORD
|
#undef KEYWORD
|
||||||
#undef TOKEN
|
#undef TOKEN
|
||||||
auto it = keywords.find(_literal);
|
auto it = keywords.find(_name);
|
||||||
return it == keywords.end() ? make_tuple(Token::Identifier, 0, 0) : make_tuple(it->second, 0, 0);
|
return it == keywords.end() ? Token::Identifier : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef KT
|
#undef KT
|
||||||
#undef KK
|
#undef KK
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,6 +307,8 @@ private:
|
|||||||
// if out_of_range error is thrown, they returns 0s, therefore securing
|
// if out_of_range error is thrown, they returns 0s, therefore securing
|
||||||
// the variable's identity as an identifier.
|
// the variable's identity as an identifier.
|
||||||
static unsigned extractM(std::string const& _literal);
|
static unsigned extractM(std::string const& _literal);
|
||||||
|
// @returns the keyword with name @a _name or Token::Identifier of no such keyword exists.
|
||||||
|
static Token::Value keywordByName(std::string const& _name);
|
||||||
static char const* const m_name[NUM_TOKENS];
|
static char const* const m_name[NUM_TOKENS];
|
||||||
static char const* const m_string[NUM_TOKENS];
|
static char const* const m_string[NUM_TOKENS];
|
||||||
static int8_t const m_precedence[NUM_TOKENS];
|
static int8_t const m_precedence[NUM_TOKENS];
|
||||||
|
@ -3207,6 +3207,31 @@ BOOST_AUTO_TEST_CASE(long_uint_variable_fails)
|
|||||||
BOOST_CHECK(!success(text));
|
BOOST_CHECK(!success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(bytes10abc_is_identifier)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
bytes32 bytes10abc = "abc";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK(success(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(int10abc_is_identifier)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
uint uint10abc = 3;
|
||||||
|
int int10abc = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK(success(text));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user