data: Extended CxxParser to detect elements

Detects most elements in the code, currently classes, structs, global variables, fields, functions, methods, namespaces
and enums. The structs ParseLocation and ParseVariable are helper objects to transmit information to the ParserClient.
Currently the parsed information only gets logged in the Storage.

review id = 15

fortune cookie message = In dreams and in life, nothing is impossible.
This commit is contained in:
Eberhard Graether
2014-05-19 12:51:00 +02:00
parent bb6640369a
commit 38c8aaebe8
15 changed files with 738 additions and 68 deletions
+51 -2
View File
@@ -1,12 +1,61 @@
#include "test_header.h"
char* name;
H g;
int ceil(float a)
{
return static_cast<int>(a) + 1;
}
namespace X
{
class A;
struct A;
enum E
{
P,
Q
};
}
class B
{
public:
class C;
class C
{
static const int amount;
};
B();
virtual ~B()
{
}
protected:
virtual void process() = 0;
private:
int getCount() const
{
return count;
}
const int count;
H h;
};
B::B()
: count(0)
{
}
namespace
{
int sum(int a, int b)
{
int c = a + b;
return c;
}
}
+5 -1
View File
@@ -1 +1,5 @@
class H;
class H
{
private:
int width;
};
+4 -1
View File
@@ -42,11 +42,14 @@ add_files(
data/access/GraphAccess.cpp
data/access/GraphAccess.h
data/parser/ParseObject.h
data/parser/ParseLocation.cpp
data/parser/ParseLocation.h
data/parser/Parser.cpp
data/parser/Parser.h
data/parser/ParserClient.cpp
data/parser/ParserClient.h
data/parser/ParseVariable.cpp
data/parser/ParseVariable.h
data/Edge.cpp
data/Edge.h
+56 -3
View File
@@ -2,6 +2,8 @@
#include <sstream>
#include "data/parser/ParseLocation.h"
#include "data/parser/ParseVariable.h"
#include "utility/logging/logging.h"
Storage::Storage()
@@ -12,10 +14,61 @@ Storage::~Storage()
{
}
void Storage::addClass(const ParseObject& object)
void Storage::onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
{
log("class", fullName, location);
}
void Storage::onStructParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
{
log("struct", fullName, location);
}
void Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable)
{
log("global", variable.fullName, location);
}
void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access)
{
log("field", variable.fullName, location);
}
void Storage::onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
const std::vector<ParseVariable>& parameters
)
{
log("function", fullName, location);
}
void Storage::onMethodParsed(
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
const std::vector<ParseVariable>& parameters, AccessType access, AbstractionType abstraction,
bool isConst, bool isStatic
)
{
log("method", fullName, location);
}
void Storage::onNamespaceParsed(const ParseLocation& location, const std::string& fullName)
{
log("namespace", fullName, location);
}
void Storage::onEnumParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
{
log("enum", fullName, location);
}
void Storage::onEnumFieldParsed(const ParseLocation& location, const std::string& fullName)
{
log("enum field", fullName, location);
}
void Storage::log(std::string type, std::string str, const ParseLocation& location) const
{
std::stringstream info;
info << "class " << object.name
<< " <" << object.fileName << " " << object.lineNumber << ":" << object.columnNumber << ">";
info << type << ": " << str << " <" << location.file << " " << location.line << ":" << location.column << ">";
LOG_INFO(info.str());
}
+21 -2
View File
@@ -12,11 +12,30 @@ class Storage: public ParserClient
{
public:
Storage();
~Storage();
virtual ~Storage();
virtual void addClass(const ParseObject& object);
virtual void onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access);
virtual void onStructParsed(const ParseLocation& location, const std::string& fullName, AccessType access);
virtual void onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable);
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access);
virtual void onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
const std::vector<ParseVariable>& parameters);
virtual void onMethodParsed(
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
const std::vector<ParseVariable>& parameters, AccessType access, AbstractionType abstraction,
bool isConst, bool isStatic);
virtual void onNamespaceParsed(const ParseLocation& location, const std::string& fullName);
virtual void onEnumParsed(const ParseLocation& location, const std::string& fullName, AccessType access);
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName);
private:
void log(std::string type, std::string str, const ParseLocation& location) const;
Graph m_graph;
std::vector<std::shared_ptr<TextLocationFile> > m_textLocationFiles;
+8
View File
@@ -0,0 +1,8 @@
#include "data/parser/ParseLocation.h"
ParseLocation::ParseLocation(const std::string& file, unsigned int line, unsigned int column)
: file(file)
, line(line)
, column(column)
{
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef PARSE_LOCATION_H
#define PARSE_LOCATION_H
#include <string>
struct ParseLocation
{
ParseLocation(const std::string& file, unsigned int line, unsigned int column);
const std::string file;
const unsigned int line;
const unsigned int column;
};
#endif // PARSE_LOCATION_H
-25
View File
@@ -1,25 +0,0 @@
#ifndef PARSE_OBJECT_H
#define PARSE_OBJECT_H
struct ParseObject
{
ParseObject(
const std::string& name,
const std::string& fileName,
unsigned int lineNumber,
unsigned int columnNumber
)
: name(name)
, fileName(fileName)
, lineNumber(lineNumber)
, columnNumber(columnNumber)
{
}
const std::string name;
const std::string fileName;
const unsigned int lineNumber;
const unsigned int columnNumber;
};
#endif // PARSE_OBJECT_H
+9
View File
@@ -0,0 +1,9 @@
#include "data/parser/ParseVariable.h"
ParseVariable::ParseVariable(const std::string& typeName, const std::string& fullName, bool isConst, bool isStatic)
: typeName(typeName)
, fullName(fullName)
, isConst(isConst)
, isStatic(isStatic)
{
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef PARSE_VARIABLE_H
#define PARSE_VARIABLE_H
#include <string>
struct ParseVariable
{
ParseVariable(const std::string& typeName, const std::string& fullName, bool isConst, bool isStatic);
const std::string typeName;
const std::string fullName;
const bool isConst;
const bool isStatic;
};
#endif // PARSE_VARIABLE_H
+33 -2
View File
@@ -2,16 +2,47 @@
#define PARSER_CLIENT_H
#include <string>
#include <vector>
#include "data/parser/ParseObject.h"
struct ParseLocation;
struct ParseVariable;
class ParserClient
{
public:
enum AccessType {
ACCESS_PUBLIC,
ACCESS_PROTECTED,
ACCESS_PRIVATE,
ACCESS_NONE
};
enum AbstractionType {
ABSTRACTION_VIRTUAL,
ABSTRACTION_PURE_VIRTUAL,
ABSTRACTION_NONE
};
ParserClient();
virtual ~ParserClient();
virtual void addClass(const ParseObject& object) = 0;
virtual void onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access) = 0;
virtual void onStructParsed(const ParseLocation& location, const std::string& fullName, AccessType access) = 0;
virtual void onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable) = 0;
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0;
virtual void onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
const std::vector<ParseVariable>& parameters) = 0;
virtual void onMethodParsed(const ParseLocation& location, const std::string& fullName,
const std::string& returnTypeName, const std::vector<ParseVariable>& parameters, AccessType access,
AbstractionType abstraction, bool isConst, bool isStatic) = 0;
virtual void onNamespaceParsed(const ParseLocation& location, const std::string& fullName) = 0;
virtual void onEnumParsed(const ParseLocation& location, const std::string& fullName, AccessType access) = 0;
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName) = 0;
};
#endif // PARSER_CLIENT_H
+243 -11
View File
@@ -1,5 +1,8 @@
#include "data/parser/cxx/ASTVisitor.h"
#include "data/parser/ParseLocation.h"
#include "data/parser/ParseVariable.h"
ASTVisitor::ASTVisitor(clang::ASTContext* context, std::shared_ptr<ParserClient> client)
: m_context(context)
, m_client(client)
@@ -10,21 +13,250 @@ ASTVisitor::~ASTVisitor()
{
}
bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl *declaration)
bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration)
{
clang::FullSourceLoc location = m_context->getFullLoc(declaration->getLocStart());
const clang::SourceLocation& location = declaration->getLocStart();
if (location.isValid() && m_context->getSourceManager().isWrittenInMainFile(location))
if (isValidLocation(location))
{
ParseObject parseObject(
declaration->getQualifiedNameAsString(),
m_context->getSourceManager().getFilename(location),
location.getSpellingLineNumber(),
location.getSpellingColumnNumber()
);
m_client->addClass(parseObject);
if (declaration->isClass())
{
m_client->onClassParsed(
getParseLocation(location),
declaration->getQualifiedNameAsString(),
convertAccessType(declaration->getAccess())
);
}
else if (declaration->isStruct())
{
m_client->onStructParsed(
getParseLocation(location),
declaration->getQualifiedNameAsString(),
convertAccessType(declaration->getAccess())
);
}
}
return true;
}
bool ASTVisitor::VisitVarDecl(clang::VarDecl* declaration)
{
// Abort on local variables and parameters.
if (declaration->isFunctionOrMethodVarDecl() || clang::isa<clang::ParmVarDecl>(declaration))
{
return true;
}
const clang::SourceLocation& location = declaration->getLocStart();
if (isValidLocation(location))
{
clang::AccessSpecifier access = declaration->getAccess();
if (access == clang::AS_none)
{
m_client->onGlobalVariableParsed(getParseLocation(location), getParseVariable(declaration));
}
else
{
m_client->onFieldParsed(
getParseLocation(location),
getParseVariable(declaration),
convertAccessType(declaration->getAccess())
);
}
}
return true;
}
bool ASTVisitor::VisitFieldDecl(clang::FieldDecl* declaration)
{
const clang::SourceLocation& location = declaration->getLocStart();
if (isValidLocation(location))
{
m_client->onFieldParsed(
getParseLocation(location),
getParseVariable(declaration),
convertAccessType(declaration->getAccess())
);
}
return true;
}
bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
{
// Abort for CXXMethodDecls to avoid duplicate call.
if (clang::isa<clang::CXXMethodDecl>(declaration))
{
return true;
}
const clang::SourceLocation& location = declaration->getLocStart();
if (isValidLocation(location))
{
m_client->onFunctionParsed(
getParseLocation(location),
declaration->getQualifiedNameAsString(),
getTypeName(declaration->getReturnType()),
getParameters(declaration)
);
}
return true;
}
bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
{
const clang::SourceLocation& location = declaration->getLocStart();
if (isValidLocation(location))
{
ParserClient::AbstractionType abstraction = ParserClient::ABSTRACTION_NONE;
if (declaration->isPure())
{
abstraction = ParserClient::ABSTRACTION_PURE_VIRTUAL;
}
else if (declaration->isVirtual())
{
abstraction = ParserClient::ABSTRACTION_VIRTUAL;
}
m_client->onMethodParsed(
getParseLocation(location),
declaration->getQualifiedNameAsString(),
getTypeName(declaration->getReturnType()),
getParameters(declaration),
convertAccessType(declaration->getAccess()),
abstraction,
declaration->isConst(),
declaration->isStatic()
);
}
return true;
}
bool ASTVisitor::VisitNamespaceDecl(clang::NamespaceDecl* declaration)
{
const clang::SourceLocation& location = declaration->getLocStart();
if (isValidLocation(location))
{
m_client->onNamespaceParsed(getParseLocation(location), declaration->getQualifiedNameAsString());
}
return true;
}
bool ASTVisitor::VisitEnumDecl(clang::EnumDecl* declaration)
{
const clang::SourceLocation& location = declaration->getLocStart();
if (isValidLocation(location))
{
m_client->onEnumParsed(
getParseLocation(location),
declaration->getQualifiedNameAsString(),
convertAccessType(declaration->getAccess())
);
}
return true;
}
bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
{
const clang::SourceLocation& location = declaration->getLocStart();
if (isValidLocation(location))
{
m_client->onEnumFieldParsed(getParseLocation(location), declaration->getQualifiedNameAsString());
}
return true;
}
bool ASTVisitor::isValidLocation(const clang::SourceLocation& location) const
{
return location.isValid() && m_context->getSourceManager().isWrittenInMainFile(location);
}
ParseLocation ASTVisitor::getParseLocation(const clang::SourceLocation& location) const
{
clang::FullSourceLoc fullLocation = m_context->getFullLoc(location);
return ParseLocation(
m_context->getSourceManager().getFilename(location),
fullLocation.getSpellingLineNumber(),
fullLocation.getSpellingColumnNumber()
);
}
ParseVariable ASTVisitor::getParseVariable(clang::ValueDecl* declaration) const
{
clang::QualType type = declaration->getType();
bool isStatic = false;
if (clang::isa<clang::VarDecl>(declaration))
{
isStatic = static_cast<clang::VarDecl*>(declaration)->isStaticDataMember();
}
return ParseVariable(
getTypeName(type),
declaration->getQualifiedNameAsString(),
type.isConstQualified(),
isStatic
);
}
std::vector<ParseVariable> ASTVisitor::getParameters(clang::FunctionDecl* declaration) const
{
std::vector<ParseVariable> parameters;
for (unsigned i = 0; i < declaration->getNumParams(); i++)
{
parameters.push_back(getParseVariable(declaration->getParamDecl(i)));
}
return parameters;
}
std::string ASTVisitor::getTypeName(const clang::QualType& type) const
{
std::string typeName = type.getUnqualifiedType().getAsString();
// Remove keywords from type.
std::string keyword;
size_t pos = typeName.find_first_of(' ');
if (pos != std::string::npos)
{
keyword = typeName.substr(0, pos);
}
if (keyword == "class" || keyword == "struct" || keyword == "enum")
{
typeName = typeName.substr(pos + 1);
}
return typeName;
}
ParserClient::AccessType ASTVisitor::convertAccessType(clang::AccessSpecifier access) const
{
switch (access)
{
case clang::AS_public:
return ParserClient::ACCESS_PUBLIC;
case clang::AS_protected:
return ParserClient::ACCESS_PROTECTED;
case clang::AS_private:
return ParserClient::ACCESS_PRIVATE;
case clang::AS_none:
return ParserClient::ACCESS_NONE;
}
}
+23 -1
View File
@@ -14,9 +14,31 @@ public:
ASTVisitor(clang::ASTContext* context, std::shared_ptr<ParserClient> client);
virtual ~ASTVisitor();
virtual bool VisitCXXRecordDecl(clang::CXXRecordDecl *declaration);
// Left for debugging purposes. Uncomment to see a colored ast-dump of the parsed file.
// virtual bool VisitDecl(clang::Decl* declaration)
// {
// // declaration->print(llvm::outs());
// declaration->dump();
// return false;
// }
virtual bool VisitCXXRecordDecl(clang::CXXRecordDecl* declaration); // classes and structs
virtual bool VisitVarDecl(clang::VarDecl* declaration); // global variables and static fields
virtual bool VisitFieldDecl(clang::FieldDecl* declaration); // fields
virtual bool VisitFunctionDecl(clang::FunctionDecl* declaration); // functions
virtual bool VisitCXXMethodDecl(clang::CXXMethodDecl* declaration); // methods
virtual bool VisitNamespaceDecl(clang::NamespaceDecl* declaration); // namespaces
virtual bool VisitEnumDecl(clang::EnumDecl* declaration); // enums
virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* declaration); // enum fields
private:
bool isValidLocation(const clang::SourceLocation& location) const;
ParseLocation getParseLocation(const clang::SourceLocation& location) const;
ParseVariable getParseVariable(clang::ValueDecl* declaration) const;
std::vector<ParseVariable> getParameters(clang::FunctionDecl* declaration) const;
std::string getTypeName(const clang::QualType& type) const;
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
clang::ASTContext* m_context;
std::shared_ptr<ParserClient> m_client;
};
+4 -2
View File
@@ -14,8 +14,10 @@ CxxParser::~CxxParser()
void CxxParser::parseFiles(const std::vector<std::string>& filePaths)
{
const char* argv[] = { "app", "--" };
int argc = 2;
// Fake commandline flags passed to the programm. Everything after '--' will be interpreted by the ClangTool.
// The option '-x c++' treats subsequent input files as C++.
const char* argv[] = { "app", "--", "-x", "c++" };
int argc = 4;
std::shared_ptr<clang::tooling::FixedCompilationDatabase> compilationDatabase(
clang::tooling::FixedCompilationDatabase::loadFromCommandLine(argc, argv)
+250 -18
View File
@@ -1,18 +1,9 @@
#include "cxxtest/TestSuite.h"
#include "data/parser/cxx/CxxParser.h"
#include "data/parser/ParseLocation.h"
#include "data/parser/ParserClient.h"
class TestParserClient: public ParserClient
{
public:
virtual void addClass(const ParseObject& object)
{
classes.push_back(object.name);
}
std::vector<std::string> classes;
};
#include "data/parser/ParseVariable.h"
class CxxParserTestSuite: public CxxTest::TestSuite
{
@@ -20,15 +11,256 @@ public:
void test_cxx_parser_finds_classes()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
std::vector<std::string> filePaths;
filePaths.push_back("data/test_code.cpp");
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->classes[0], "X::A");
TS_ASSERT_EQUALS(client->classes[1], "B");
TS_ASSERT_EQUALS(client->classes[2], "B::C");
TS_ASSERT_EQUALS(client->classes.size(), 2);
TS_ASSERT_EQUALS(client->classes[0], "B");
TS_ASSERT_EQUALS(client->classes[1], "public B::C");
}
void test_cxx_parser_finds_structs()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->structs.size(), 1);
TS_ASSERT_EQUALS(client->structs[0], "X::A");
}
void test_cxx_parser_finds_globals()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->globals.size(), 2);
TS_ASSERT_EQUALS(client->globals[0], "char * name");
TS_ASSERT_EQUALS(client->globals[1], "H g");
}
void test_cxx_parser_finds_fields()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->fields.size(), 3);
TS_ASSERT_EQUALS(client->fields[0], "private static const int B::C::amount");
TS_ASSERT_EQUALS(client->fields[1], "private const int B::count");
TS_ASSERT_EQUALS(client->fields[2], "private H B::h");
}
void test_cxx_parser_finds_functions()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->functions.size(), 2);
TS_ASSERT_EQUALS(client->functions[0], "int ceil(float a)");
TS_ASSERT_EQUALS(client->functions[1], "int (anonymous namespace)::sum(int a, int b)");
}
void test_cxx_parser_finds_methods()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->methods.size(), 5);
TS_ASSERT_EQUALS(client->methods[0], "public void B::B()");
TS_ASSERT_EQUALS(client->methods[1], "public virtual void B::~B()");
TS_ASSERT_EQUALS(client->methods[2], "protected pure virtual void B::process()");
TS_ASSERT_EQUALS(client->methods[3], "private int B::getCount() const");
TS_ASSERT_EQUALS(client->methods[4], "public void B::B()");
}
void test_cxx_parser_finds_namespaces()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->namespaces.size(), 2);
TS_ASSERT_EQUALS(client->namespaces[0], "X");
TS_ASSERT_EQUALS(client->namespaces[1], "(anonymous)");
}
void test_cxx_parser_finds_enums()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->enums.size(), 1);
TS_ASSERT_EQUALS(client->enums[0], "X::E");
}
void test_cxx_parser_finds_enum_fields()
{
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
CxxParser parser(client);
std::vector<std::string> filePaths(1, "data/test_code.cpp");
parser.parseFiles(filePaths);
TS_ASSERT_EQUALS(client->enumFields.size(), 2);
TS_ASSERT_EQUALS(client->enumFields[0], "X::E::P");
TS_ASSERT_EQUALS(client->enumFields[1], "X::E::Q");
}
private:
class TestParserClient: public ParserClient
{
public:
virtual void onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
{
classes.push_back(addAccessPrefix(fullName, access));
}
virtual void onStructParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
{
structs.push_back(addAccessPrefix(fullName, access));
}
virtual void onGlobalVariableParsed(const ParseLocation& location, const ParseVariable& variable)
{
globals.push_back(variableStr(variable));
}
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access)
{
fields.push_back(addAccessPrefix(variableStr(variable), access));
}
virtual void onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
const std::vector<ParseVariable>& parameters
)
{
functions.push_back(returnTypeName + " " + fullName + parameterStr(parameters));
}
virtual void onMethodParsed(
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
const std::vector<ParseVariable>& parameters, AccessType access, AbstractionType abstraction,
bool isConst, bool isStatic
)
{
std::string str = returnTypeName + " " + fullName + parameterStr(parameters);
str = addStaticPrefix(addAbstractionPrefix(str, abstraction), isStatic);
str = addConstPrefix(addAccessPrefix(str, access), isConst, false);
methods.push_back(str);
}
virtual void onNamespaceParsed(const ParseLocation& location, const std::string& fullName)
{
namespaces.push_back(fullName);
}
virtual void onEnumParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
{
enums.push_back(addAccessPrefix(fullName, access));
}
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName)
{
enumFields.push_back(fullName);
}
std::vector<std::string> classes;
std::vector<std::string> enums;
std::vector<std::string> enumFields;
std::vector<std::string> functions;
std::vector<std::string> fields;
std::vector<std::string> globals;
std::vector<std::string> methods;
std::vector<std::string> namespaces;
std::vector<std::string> structs;
private:
std::string addAccessPrefix(const std::string& str, AccessType access)
{
switch (access)
{
case ACCESS_PUBLIC:
return "public " + str;
case ACCESS_PROTECTED:
return "protected " + str;
case ACCESS_PRIVATE:
return "private " + str;
case ACCESS_NONE:
return str;
}
}
std::string addAbstractionPrefix(const std::string& str, AbstractionType abstraction)
{
switch (abstraction)
{
case ABSTRACTION_VIRTUAL:
return "virtual " + str;
case ABSTRACTION_PURE_VIRTUAL:
return "pure virtual " + str;
case ABSTRACTION_NONE:
return str;
}
}
std::string addStaticPrefix(const std::string& str, bool isStatic)
{
if (isStatic)
{
return "static " + str;
}
return str;
}
std::string addConstPrefix(const std::string& str, bool isConst, bool atFront)
{
if (isConst)
{
return atFront ? "const " + str : str + " const";
}
return str;
}
std::string variableStr(const ParseVariable& variable)
{
std::string str = variable.typeName + " " + variable.fullName;
return addStaticPrefix(addConstPrefix(str, variable.isConst, true), variable.isStatic);
}
std::string parameterStr(const std::vector<ParseVariable> parameters)
{
std::string str = "(";
for (size_t i = 0; i < parameters.size(); i++)
{
str += variableStr(parameters[i]);
if (i < parameters.size() - 1)
{
str += ", ";
}
}
return str + ")";
}
};
};