mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fixes #4718: High CPU usage when using large variable names
This commit is contained in:
parent
f82893450d
commit
3fa8829845
@ -98,6 +98,7 @@ Bugfixes:
|
||||
* References Resolver: Enforce ``storage`` as data location for mappings.
|
||||
* References Resolver: Properly handle invalid references used together with ``_slot`` and ``_offset``.
|
||||
* References Resolver: Report error instead of assertion fail when FunctionType has an undeclared type as parameter.
|
||||
* References Resolver: Fix high CPU usage when using large variable names issue. Only suggest similar name if identifiers shorter than 80 characters.
|
||||
* Type Checker: Default data location for type conversions (e.g. from literals) is memory and not storage.
|
||||
* Type Checker: Disallow assignments to mappings within tuple assignments as well.
|
||||
* Type Checker: Disallow packed encoding of arrays of structs.
|
||||
|
@ -29,13 +29,16 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
|
||||
bool dev::stringWithinDistance(string const& _str1, string const& _str2, size_t _maxDistance)
|
||||
bool dev::stringWithinDistance(string const& _str1, string const& _str2, size_t _maxDistance, size_t _lenThreshold)
|
||||
{
|
||||
if (_str1 == _str2)
|
||||
return true;
|
||||
|
||||
size_t n1 = _str1.size();
|
||||
size_t n2 = _str2.size();
|
||||
if (_lenThreshold > 0 && n1 * n2 > _lenThreshold)
|
||||
return false;
|
||||
|
||||
size_t distance = stringDistance(_str1, _str2);
|
||||
|
||||
// if distance is not greater than _maxDistance, and distance is strictly less than length of both names, they can be considered similar
|
||||
|
@ -30,7 +30,8 @@ namespace dev
|
||||
{
|
||||
|
||||
// Calculates the Damerau–Levenshtein distance between _str1 and _str2 and returns true if that distance is not greater than _maxDistance
|
||||
bool stringWithinDistance(std::string const& _str1, std::string const& _str2, size_t _maxDistance);
|
||||
// if _lenThreshold > 0 and the product of the strings length is greater than _lenThreshold, the function will return false
|
||||
bool stringWithinDistance(std::string const& _str1, std::string const& _str2, size_t _maxDistance, size_t _lenThreshold = 0);
|
||||
// Calculates the Damerau–Levenshtein distance between _str1 and _str2
|
||||
size_t stringDistance(std::string const& _str1, std::string const& _str2);
|
||||
// Return a string having elements of suggestions as quoted, alternative suggestions. e.g. "a", "b" or "c"
|
||||
|
@ -138,19 +138,22 @@ vector<Declaration const*> DeclarationContainer::resolveName(ASTString const& _n
|
||||
vector<ASTString> DeclarationContainer::similarNames(ASTString const& _name) const
|
||||
{
|
||||
static size_t const MAXIMUM_EDIT_DISTANCE = 2;
|
||||
// because the function below has quadratic runtime - it will not magically improve once a better algorithm is discovered ;)
|
||||
// since 80 is the suggested line length limit, we use 80^2 as length threshold
|
||||
static size_t const MAXIMUM_LENGTH_THRESHOLD = 80 * 80;
|
||||
|
||||
vector<ASTString> similar;
|
||||
|
||||
for (auto const& declaration: m_declarations)
|
||||
{
|
||||
string const& declarationName = declaration.first;
|
||||
if (stringWithinDistance(_name, declarationName, MAXIMUM_EDIT_DISTANCE))
|
||||
if (stringWithinDistance(_name, declarationName, MAXIMUM_EDIT_DISTANCE, MAXIMUM_LENGTH_THRESHOLD))
|
||||
similar.push_back(declarationName);
|
||||
}
|
||||
for (auto const& declaration: m_invisibleDeclarations)
|
||||
{
|
||||
string const& declarationName = declaration.first;
|
||||
if (stringWithinDistance(_name, declarationName, MAXIMUM_EDIT_DISTANCE))
|
||||
if (stringWithinDistance(_name, declarationName, MAXIMUM_EDIT_DISTANCE, MAXIMUM_LENGTH_THRESHOLD))
|
||||
similar.push_back(declarationName);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ BOOST_AUTO_TEST_CASE(test_similarity)
|
||||
BOOST_CHECK_EQUAL(stringWithinDistance("abc", "abcdef", 2), false);
|
||||
BOOST_CHECK_EQUAL(stringWithinDistance("abcd", "wxyz", 2), false);
|
||||
BOOST_CHECK_EQUAL(stringWithinDistance("", "", 2), true);
|
||||
BOOST_CHECK_EQUAL(stringWithinDistance("YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY", "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZ", 2, 6400), false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_dldistance)
|
||||
|
@ -0,0 +1,7 @@
|
||||
contract test {
|
||||
function f() public {
|
||||
int YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError: (146-236): Undeclared identifier.
|
@ -0,0 +1,7 @@
|
||||
contract test {
|
||||
function f() public {
|
||||
int YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError: (137-216): Undeclared identifier. Did you mean "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"?
|
Loading…
Reference in New Issue
Block a user