Fix ticket #151 (Handling of namespaces)
http://apps.sourceforge.net/trac/cppcheck/ticket/151
This commit is contained in:
parent
4c28882a12
commit
3c4704a00c
|
@ -66,6 +66,33 @@ void Token::deleteNext()
|
||||||
_next->previous(this);
|
_next->previous(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Token::deleteThis()
|
||||||
|
{
|
||||||
|
if (_next)
|
||||||
|
{
|
||||||
|
_str = _next->_str;
|
||||||
|
_isName = _next->_isName;
|
||||||
|
_isNumber = _next->_isNumber;
|
||||||
|
_isBoolean = _next->_isBoolean;
|
||||||
|
_varId = _next->_varId;
|
||||||
|
_fileIndex = _next->_fileIndex;
|
||||||
|
_linenr = _next->_linenr;
|
||||||
|
deleteNext();
|
||||||
|
}
|
||||||
|
else if (_previous)
|
||||||
|
{
|
||||||
|
// This should never be used for tokens
|
||||||
|
// at the end of the list
|
||||||
|
str(";");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We are the last token in the list, we can't delete
|
||||||
|
// ourselves, so just make us ;
|
||||||
|
str(";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Token::replace(Token *replaceThis, Token *start, Token *end)
|
void Token::replace(Token *replaceThis, Token *start, Token *end)
|
||||||
{
|
{
|
||||||
// Fix the whole in the old location of start and end
|
// Fix the whole in the old location of start and end
|
||||||
|
|
|
@ -188,6 +188,13 @@ public:
|
||||||
/** Stringify a token list (with or without varId) */
|
/** Stringify a token list (with or without varId) */
|
||||||
std::string stringifyList(const bool varid = true, const char *title = 0) const;
|
std::string stringifyList(const bool varid = true, const char *title = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is intended to be used for the first token in the list
|
||||||
|
* Do not use this for the tokens at the end of the list unless the
|
||||||
|
* token is the last token in the list.
|
||||||
|
*/
|
||||||
|
void deleteThis();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void next(Token *next);
|
void next(Token *next);
|
||||||
void previous(Token *previous);
|
void previous(Token *previous);
|
||||||
|
|
|
@ -494,7 +494,7 @@ void Tokenizer::tokenize(std::istream &code, const char FileName[])
|
||||||
const std::string type(tok->strAt(3));
|
const std::string type(tok->strAt(3));
|
||||||
const std::string name(tok->strAt(6));
|
const std::string name(tok->strAt(6));
|
||||||
|
|
||||||
const bool isfunc(tok->strAt(7)[0] == '(');
|
const bool isfunc(tok->strAt(7)[0] == '(');
|
||||||
|
|
||||||
// locate template usage..
|
// locate template usage..
|
||||||
const std::string pattern(name + " < %type% > " + (isfunc ? "(" : "%var%"));
|
const std::string pattern(name + " < %type% > " + (isfunc ? "(" : "%var%"));
|
||||||
|
@ -637,8 +637,66 @@ void Tokenizer::setVarId()
|
||||||
// Simplify token list
|
// Simplify token list
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tokenizer::simplifyNamespaces()
|
||||||
|
{
|
||||||
|
for (Token *token = _tokens; token; token = token->next())
|
||||||
|
{
|
||||||
|
while (token->str() == "namespace" &&
|
||||||
|
(!token->previous() || token->previous()->str() != "using"))
|
||||||
|
{
|
||||||
|
// Token is namespace and there is no "using" before it.
|
||||||
|
Token *start = token;
|
||||||
|
Token *tok = token->next();
|
||||||
|
if (!tok)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int indent = 0;
|
||||||
|
for (tok = tok->next(); tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (tok->str() == "{")
|
||||||
|
indent++;
|
||||||
|
else if (tok->str() == "}")
|
||||||
|
{
|
||||||
|
indent--;
|
||||||
|
if (indent == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tok)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tok->str() == "}")
|
||||||
|
{
|
||||||
|
tok = tok->previous();
|
||||||
|
tok->deleteNext();
|
||||||
|
start->deleteNext();
|
||||||
|
start->deleteNext();
|
||||||
|
token = start->next();
|
||||||
|
if (start->previous())
|
||||||
|
{
|
||||||
|
start = start->previous();
|
||||||
|
start->deleteNext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// First token in the list, don't delete
|
||||||
|
// as _tokens is attached to it.
|
||||||
|
start->deleteThis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Tokenizer::simplifyTokenList()
|
void Tokenizer::simplifyTokenList()
|
||||||
{
|
{
|
||||||
|
simplifyNamespaces();
|
||||||
|
|
||||||
// Combine strings
|
// Combine strings
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
|
|
|
@ -157,6 +157,12 @@ private:
|
||||||
*/
|
*/
|
||||||
bool simplifyFunctionParameters();
|
bool simplifyFunctionParameters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplify namespaces by removing them, e.g.
|
||||||
|
* "namespace b{ void f(){} }" becomes "void f(){}"
|
||||||
|
*/
|
||||||
|
void simplifyNamespaces();
|
||||||
|
|
||||||
void InsertTokens(Token *dest, Token *src, unsigned int n);
|
void InsertTokens(Token *dest, Token *src, unsigned int n);
|
||||||
|
|
||||||
Token *_tokensBack;
|
Token *_tokensBack;
|
||||||
|
|
|
@ -79,6 +79,7 @@ private:
|
||||||
|
|
||||||
TEST_CASE(template1);
|
TEST_CASE(template1);
|
||||||
TEST_CASE(template2);
|
TEST_CASE(template2);
|
||||||
|
TEST_CASE(namespaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tok(const char code[])
|
std::string tok(const char code[])
|
||||||
|
@ -477,6 +478,25 @@ private:
|
||||||
|
|
||||||
ASSERT_EQUALS(expected, sizeof_(code));
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void namespaces()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const char code[] = "using namespace std; namespace a{ namespace b{ void f(){} } }";
|
||||||
|
|
||||||
|
const std::string expected(" using namespace std ; void f ( ) { }");
|
||||||
|
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "namespace b{ void f(){} }";
|
||||||
|
|
||||||
|
const std::string expected(" void f ( ) { }");
|
||||||
|
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestSimplifyTokens)
|
REGISTER_TEST(TestSimplifyTokens)
|
||||||
|
|
Loading…
Reference in New Issue