refactoring namespace handling. ticket: #2001
This commit is contained in:
parent
15b4cab4bb
commit
4153b7d24b
|
@ -70,7 +70,7 @@ static bool isFunction(const Token *tok, const Token **argStart)
|
||||||
else if (tok->str() == "operator")
|
else if (tok->str() == "operator")
|
||||||
{
|
{
|
||||||
// operator[] or operator()?
|
// operator[] or operator()?
|
||||||
if ((Token::Match(tok->next(), "( ) (") || Token::Match(tok->next(), "[ ] (")) &&
|
if ((Token::simpleMatch(tok->next(), "( ) (") || Token::simpleMatch(tok->next(), "[ ] (")) &&
|
||||||
Token::Match(tok->tokAt(3)->link(), ") const| ;|{|=|:"))
|
Token::Match(tok->tokAt(3)->link(), ") const| ;|{|=|:"))
|
||||||
{
|
{
|
||||||
*argStart = tok->tokAt(3);
|
*argStart = tok->tokAt(3);
|
||||||
|
@ -260,80 +260,7 @@ void CheckClass::createSymbolDatabase()
|
||||||
if (Token::Match(next, ") const| ;") ||
|
if (Token::Match(next, ") const| ;") ||
|
||||||
Token::Match(next, ") const| = 0 ;"))
|
Token::Match(next, ") const| = 0 ;"))
|
||||||
{
|
{
|
||||||
// find implementation using names on stack
|
// find the function implementation later
|
||||||
SpaceInfo *nest = info;
|
|
||||||
unsigned int depth = 0;
|
|
||||||
|
|
||||||
std::string classPattern;
|
|
||||||
std::string classPath;
|
|
||||||
std::string searchPattern;
|
|
||||||
const Token *funcArgs = function.tokenDef->tokAt(2);
|
|
||||||
int offset = 1;
|
|
||||||
|
|
||||||
if (function.isOperator)
|
|
||||||
{
|
|
||||||
if (Token::Match(function.tokenDef, "(|["))
|
|
||||||
{
|
|
||||||
classPattern = "operator " + function.tokenDef->str() + " " + function.tokenDef->next()->str() + " (";
|
|
||||||
offset = 2;
|
|
||||||
}
|
|
||||||
else if (Token::Match(function.tokenDef, "new|delete ["))
|
|
||||||
{
|
|
||||||
classPattern = "operator " + function.tokenDef->str() + " " + function.tokenDef->next()->str() + " " + function.tokenDef->next()->strAt(2) + " (";
|
|
||||||
offset = 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
classPattern = "operator " + function.tokenDef->str() + " (";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
classPattern = function.tokenDef->str() + " (";
|
|
||||||
|
|
||||||
// look for an implementation outside of class
|
|
||||||
while (!function.hasBody && nest)
|
|
||||||
{
|
|
||||||
classPath = nest->className + std::string(" :: ") + classPath;
|
|
||||||
searchPattern = classPath + classPattern;
|
|
||||||
depth++;
|
|
||||||
nest = nest->nestedIn;
|
|
||||||
|
|
||||||
// start looking at end of class
|
|
||||||
SpaceInfo *top = info;
|
|
||||||
const Token *found = top->classEnd;
|
|
||||||
while ((found = Token::findmatch(found, searchPattern.c_str(), nest ? nest->classEnd : 0)) != NULL)
|
|
||||||
{
|
|
||||||
// skip other classes
|
|
||||||
if (found->previous()->str() == "::")
|
|
||||||
break;
|
|
||||||
|
|
||||||
// goto function name
|
|
||||||
while (found->next()->str() != "(")
|
|
||||||
found = found->next();
|
|
||||||
|
|
||||||
if (Token::Match(found->tokAt(offset)->link(), function.isConst ? ") const {" : ") {") ||
|
|
||||||
(function.type == Func::Constructor && Token::Match(found->next()->link(), ") :|{")))
|
|
||||||
{
|
|
||||||
if (argsMatch(funcArgs, found->tokAt(offset + 1), classPath, depth))
|
|
||||||
{
|
|
||||||
function.token = found;
|
|
||||||
function.hasBody = true;
|
|
||||||
function.arg = found->tokAt(offset);
|
|
||||||
|
|
||||||
info->functionList.push_back(function);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip function body
|
|
||||||
while (found->str() != "{")
|
|
||||||
found = found->next();
|
|
||||||
|
|
||||||
found = found->link();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!function.hasBody)
|
|
||||||
info->functionList.push_back(function);
|
|
||||||
|
|
||||||
tok = next->next();
|
tok = next->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,8 +271,6 @@ void CheckClass::createSymbolDatabase()
|
||||||
function.hasBody = true;
|
function.hasBody = true;
|
||||||
function.arg = function.argDef;
|
function.arg = function.argDef;
|
||||||
|
|
||||||
info->functionList.push_back(function);
|
|
||||||
|
|
||||||
// skip over function body
|
// skip over function body
|
||||||
tok = next->next();
|
tok = next->next();
|
||||||
while (tok && tok->str() != "{")
|
while (tok && tok->str() != "{")
|
||||||
|
@ -354,6 +279,8 @@ void CheckClass::createSymbolDatabase()
|
||||||
return;
|
return;
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info->functionList.push_back(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
// friend class declaration?
|
// friend class declaration?
|
||||||
|
@ -373,7 +300,6 @@ void CheckClass::createSymbolDatabase()
|
||||||
|
|
||||||
std::multimap<std::string, SpaceInfo *>::iterator it;
|
std::multimap<std::string, SpaceInfo *>::iterator it;
|
||||||
|
|
||||||
// finish filling in base class info
|
|
||||||
for (it = spaceInfoMMap.begin(); it != spaceInfoMMap.end(); ++it)
|
for (it = spaceInfoMMap.begin(); it != spaceInfoMMap.end(); ++it)
|
||||||
{
|
{
|
||||||
info = it->second;
|
info = it->second;
|
||||||
|
@ -382,6 +308,7 @@ void CheckClass::createSymbolDatabase()
|
||||||
if (info->isNamespace)
|
if (info->isNamespace)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// finish filling in base class info
|
||||||
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
|
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
|
||||||
{
|
{
|
||||||
std::multimap<std::string, SpaceInfo *>::iterator it1;
|
std::multimap<std::string, SpaceInfo *>::iterator it1;
|
||||||
|
@ -398,7 +325,8 @@ void CheckClass::createSymbolDatabase()
|
||||||
{
|
{
|
||||||
// are they in the same namespace or different namespaces with same name?
|
// are they in the same namespace or different namespaces with same name?
|
||||||
if ((spaceInfo->nestedIn == info->nestedIn) ||
|
if ((spaceInfo->nestedIn == info->nestedIn) ||
|
||||||
((spaceInfo->nestedIn->isNamespace && info->nestedIn->isNamespace) &&
|
((spaceInfo->nestedIn && spaceInfo->nestedIn->isNamespace) &&
|
||||||
|
(info->nestedIn && info->nestedIn->isNamespace) &&
|
||||||
(spaceInfo->nestedIn->className == info->nestedIn->className)))
|
(spaceInfo->nestedIn->className == info->nestedIn->className)))
|
||||||
{
|
{
|
||||||
info->derivedFrom[i].spaceInfo = spaceInfo;
|
info->derivedFrom[i].spaceInfo = spaceInfo;
|
||||||
|
@ -408,6 +336,84 @@ void CheckClass::createSymbolDatabase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::list<Func>::iterator func;
|
||||||
|
|
||||||
|
// find the function body if not implemented inline
|
||||||
|
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
|
||||||
|
{
|
||||||
|
if (!func->hasBody)
|
||||||
|
{
|
||||||
|
// find implementation using names on stack
|
||||||
|
SpaceInfo *nest = info;
|
||||||
|
unsigned int depth = 0;
|
||||||
|
|
||||||
|
std::string classPattern;
|
||||||
|
std::string classPath;
|
||||||
|
std::string searchPattern;
|
||||||
|
const Token *funcArgs = func->tokenDef->tokAt(2);
|
||||||
|
int offset = 1;
|
||||||
|
|
||||||
|
if (func->isOperator)
|
||||||
|
{
|
||||||
|
if (Token::Match(func->tokenDef, "(|["))
|
||||||
|
{
|
||||||
|
classPattern = "operator " + func->tokenDef->str() + " " + func->tokenDef->next()->str() + " (";
|
||||||
|
offset = 2;
|
||||||
|
}
|
||||||
|
else if (Token::Match(func->tokenDef, "new|delete ["))
|
||||||
|
{
|
||||||
|
classPattern = "operator " + func->tokenDef->str() + " " + func->tokenDef->next()->str() + " " + func->tokenDef->next()->strAt(2) + " (";
|
||||||
|
offset = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
classPattern = "operator " + func->tokenDef->str() + " (";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
classPattern = func->tokenDef->str() + " (";
|
||||||
|
|
||||||
|
// look for an implementation outside of class
|
||||||
|
while (!func->hasBody && nest)
|
||||||
|
{
|
||||||
|
classPath = nest->className + std::string(" :: ") + classPath;
|
||||||
|
searchPattern = classPath + classPattern;
|
||||||
|
depth++;
|
||||||
|
nest = nest->nestedIn;
|
||||||
|
|
||||||
|
// start looking at end of class
|
||||||
|
SpaceInfo *top = info;
|
||||||
|
const Token *found = top->classEnd;
|
||||||
|
while ((found = Token::findmatch(found, searchPattern.c_str(), nest ? nest->classEnd : 0)) != NULL)
|
||||||
|
{
|
||||||
|
// skip other classes
|
||||||
|
if (found->previous()->str() == "::")
|
||||||
|
break;
|
||||||
|
|
||||||
|
// goto function name
|
||||||
|
while (found->next()->str() != "(")
|
||||||
|
found = found->next();
|
||||||
|
|
||||||
|
if (Token::Match(found->tokAt(offset)->link(), func->isConst ? ") const {" : ") {") ||
|
||||||
|
(func->type == Func::Constructor && Token::Match(found->next()->link(), ") :|{")))
|
||||||
|
{
|
||||||
|
if (argsMatch(funcArgs, found->tokAt(offset + 1), classPath, depth))
|
||||||
|
{
|
||||||
|
func->token = found;
|
||||||
|
func->hasBody = true;
|
||||||
|
func->arg = found->tokAt(offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip function body
|
||||||
|
while (found->str() != "{")
|
||||||
|
found = found->next();
|
||||||
|
|
||||||
|
found = found->link();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +493,8 @@ const Token *CheckClass::initBaseInfo(SpaceInfo *info, const Token *tok)
|
||||||
CheckClass::SpaceInfo::SpaceInfo(CheckClass *check_, const Token *classDef_, CheckClass::SpaceInfo *nestedIn_) :
|
CheckClass::SpaceInfo::SpaceInfo(CheckClass *check_, const Token *classDef_, CheckClass::SpaceInfo *nestedIn_) :
|
||||||
check(check_),
|
check(check_),
|
||||||
classDef(classDef_),
|
classDef(classDef_),
|
||||||
|
classStart(NULL),
|
||||||
|
classEnd(NULL),
|
||||||
nestedIn(nestedIn_),
|
nestedIn(nestedIn_),
|
||||||
numConstructors(0)
|
numConstructors(0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3951,6 +3951,34 @@ private:
|
||||||
" };\n"
|
" };\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:12]: (style) The function 'N::Derived::getResourceName' can be const\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:12]: (style) The function 'N::Derived::getResourceName' can be const\n", errout.str());
|
||||||
|
|
||||||
|
checkConst("namespace N\n"
|
||||||
|
"{\n"
|
||||||
|
" class Base\n"
|
||||||
|
" {\n"
|
||||||
|
" public:\n"
|
||||||
|
" int getResourceName();\n"
|
||||||
|
" int var;\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n"
|
||||||
|
"int N::Base::getResourceName() { return var; }\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:10] -> [test.cpp:6]: (style) The function 'N::Base::getResourceName' can be const\n", errout.str());
|
||||||
|
|
||||||
|
checkConst("namespace N\n"
|
||||||
|
"{\n"
|
||||||
|
" class Base\n"
|
||||||
|
" {\n"
|
||||||
|
" public:\n"
|
||||||
|
" int getResourceName();\n"
|
||||||
|
" int var;\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n"
|
||||||
|
"namespace N\n"
|
||||||
|
"{\n"
|
||||||
|
" int Base::getResourceName() { return var; }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
TODO_ASSERT_EQUALS("[test.cpp:12] -> [test.cpp:6]: (style) The function 'N::Base::getResourceName' can be const\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void const36() // ticket #2003
|
void const36() // ticket #2003
|
||||||
|
|
Loading…
Reference in New Issue