Initial work for class and member function/variable list in tokenizer.
This commit is contained in:
parent
bcab694a74
commit
4f8a06ed0d
|
@ -87,6 +87,7 @@
|
||||||
<Unit filename="src/checkstl.h" />
|
<Unit filename="src/checkstl.h" />
|
||||||
<Unit filename="src/checkunusedfunctions.cpp" />
|
<Unit filename="src/checkunusedfunctions.cpp" />
|
||||||
<Unit filename="src/checkunusedfunctions.h" />
|
<Unit filename="src/checkunusedfunctions.h" />
|
||||||
|
<Unit filename="src/classinfo.h" />
|
||||||
<Unit filename="src/cppcheck.cpp" />
|
<Unit filename="src/cppcheck.cpp" />
|
||||||
<Unit filename="src/cppcheck.h" />
|
<Unit filename="src/cppcheck.h" />
|
||||||
<Unit filename="src/cppcheckexecutor.cpp" />
|
<Unit filename="src/cppcheckexecutor.cpp" />
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Cppcheck - A tool for static C/C++ code analysis
|
||||||
|
* Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#ifndef classInfoH
|
||||||
|
#define classInfoH
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
/// @addtogroup Core
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/** @brief Holds information about a single class in checked source code. Contains member function and member variable lists. */
|
||||||
|
class ClassInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum MemberType {PRIVATE, PROTECTED, PUBLIC};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for both member functions and member variables.
|
||||||
|
* Contains variable name, token where name was declared and type
|
||||||
|
* private/protected/public.
|
||||||
|
*/
|
||||||
|
class MemberInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
MemberInfo() : _declaration(0), _name(), _type(ClassInfo::PRIVATE)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~MemberInfo() {}
|
||||||
|
|
||||||
|
const Token *_declaration;
|
||||||
|
std::string _name;
|
||||||
|
ClassInfo::MemberType _type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a single member function of a class.
|
||||||
|
*/
|
||||||
|
class MemberFunctionInfo : public MemberInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemberFunctionInfo() : _implementation(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const Token *_implementation;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a single member variable of a class.
|
||||||
|
*/
|
||||||
|
class MemberVariableInfo : public MemberInfo
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of member functions
|
||||||
|
*/
|
||||||
|
std::vector<MemberFunctionInfo> _memberFunctions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of member variables
|
||||||
|
*/
|
||||||
|
std::vector<MemberVariableInfo> _memberVariables;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#endif
|
|
@ -725,6 +725,70 @@ void Tokenizer::simplifyTemplates()
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tokenizer::updateClassList()
|
||||||
|
{
|
||||||
|
const char pattern_class[] = "class %var% [{:]";
|
||||||
|
_classInfoList.clear();
|
||||||
|
|
||||||
|
// Locate class
|
||||||
|
const Token *tok1 = tokens();
|
||||||
|
while ((tok1 = Token::findmatch(tok1, pattern_class)))
|
||||||
|
{
|
||||||
|
const char *className;
|
||||||
|
className = tok1->strAt(1);
|
||||||
|
tok1 = tok1->next();
|
||||||
|
|
||||||
|
ClassInfo::MemberType memberType = ClassInfo::PRIVATE;
|
||||||
|
int indentlevel = 0;
|
||||||
|
for (const Token *tok = tok1; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
// Indentation
|
||||||
|
if (tok->str() == "{")
|
||||||
|
{
|
||||||
|
++indentlevel;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (tok->str() == "}")
|
||||||
|
{
|
||||||
|
--indentlevel;
|
||||||
|
if (indentlevel <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse class contents (indentlevel == 1)..
|
||||||
|
if (indentlevel == 1)
|
||||||
|
{
|
||||||
|
if (tok->str() == "private:")
|
||||||
|
memberType = ClassInfo::PRIVATE;
|
||||||
|
else if (tok->str() == "protected:")
|
||||||
|
memberType = ClassInfo::PROTECTED;
|
||||||
|
else if (tok->str() == "public:")
|
||||||
|
memberType = ClassInfo::PUBLIC;
|
||||||
|
|
||||||
|
else if (Token::Match(tok, "typedef %type% ("))
|
||||||
|
tok = tok->tokAt(2);
|
||||||
|
|
||||||
|
else if (Token::Match(tok, "[:,] %var% ("))
|
||||||
|
tok = tok->tokAt(2);
|
||||||
|
|
||||||
|
else if (Token::Match(tok, "%var% ("))
|
||||||
|
{
|
||||||
|
// member function
|
||||||
|
ClassInfo::MemberFunctionInfo func;
|
||||||
|
func._declaration = tok;
|
||||||
|
func._name = tok->str();
|
||||||
|
func._type = memberType;
|
||||||
|
|
||||||
|
_classInfoList[className]._memberFunctions.push_back(func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Tokenizer::setVarId()
|
void Tokenizer::setVarId()
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "classinfo.h"
|
||||||
|
|
||||||
class Token;
|
class Token;
|
||||||
class ErrorLogger;
|
class ErrorLogger;
|
||||||
|
@ -105,6 +106,12 @@ public:
|
||||||
*/
|
*/
|
||||||
static const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel);
|
static const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of classes in currently checked source code and
|
||||||
|
* their member functions and member variables.
|
||||||
|
*/
|
||||||
|
std::map<std::string, ClassInfo> _classInfoList;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -280,6 +287,12 @@ private:
|
||||||
|
|
||||||
void syntaxError(const Token *tok, char c);
|
void syntaxError(const Token *tok, char c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update _classInfoList to contain class names and member
|
||||||
|
* functions and member variables.
|
||||||
|
*/
|
||||||
|
void updateClassList();
|
||||||
|
|
||||||
Token *_tokens, *_tokensBack;
|
Token *_tokens, *_tokensBack;
|
||||||
std::map<std::string, unsigned int> _typeSize;
|
std::map<std::string, unsigned int> _typeSize;
|
||||||
std::vector<std::string> _files;
|
std::vector<std::string> _files;
|
||||||
|
|
|
@ -143,6 +143,7 @@ private:
|
||||||
|
|
||||||
// unsigned i; => unsigned int i;
|
// unsigned i; => unsigned int i;
|
||||||
TEST_CASE(unsigned1);
|
TEST_CASE(unsigned1);
|
||||||
|
TEST_CASE(testUpdateClassList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2387,6 +2388,38 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tokenizeAndUpdateClassList(const char code[])
|
||||||
|
{
|
||||||
|
// tokenize..
|
||||||
|
Tokenizer tokenizer;
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
|
tokenizer.updateClassList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void testUpdateClassList()
|
||||||
|
{
|
||||||
|
const char code[] = "class A{\n"
|
||||||
|
" void f() {}\n"
|
||||||
|
" public:\n"
|
||||||
|
" void g() {}\n"
|
||||||
|
"};";
|
||||||
|
Tokenizer tokenizer;
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
|
tokenizer.updateClassList();
|
||||||
|
ASSERT_EQUALS(2, tokenizer._classInfoList["A"]._memberFunctions.size());
|
||||||
|
if (tokenizer._classInfoList["A"]._memberFunctions.size() > 1)
|
||||||
|
{
|
||||||
|
ASSERT_EQUALS(std::string("f"), tokenizer._classInfoList["A"]._memberFunctions[0]._name);
|
||||||
|
ASSERT_EQUALS(std::string("f"), tokenizer._classInfoList["A"]._memberFunctions[0]._declaration->str());
|
||||||
|
ASSERT_EQUALS(ClassInfo::PRIVATE, tokenizer._classInfoList["A"]._memberFunctions[0]._type);
|
||||||
|
ASSERT_EQUALS(std::string("g"), tokenizer._classInfoList["A"]._memberFunctions[1]._name);
|
||||||
|
ASSERT_EQUALS(std::string("g"), tokenizer._classInfoList["A"]._memberFunctions[1]._declaration->str());
|
||||||
|
ASSERT_EQUALS(ClassInfo::PUBLIC, tokenizer._classInfoList["A"]._memberFunctions[1]._type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestTokenizer)
|
REGISTER_TEST(TestTokenizer)
|
||||||
|
|
Loading…
Reference in New Issue