data: parse typedefs
- added callbacks that will be called when clang encounters typedefs. - added tests for this feature. review id = 20 fortune cookie message = New ideas could be profitable.
This commit is contained in:
@@ -14,6 +14,14 @@ Storage::~Storage()
|
||||
{
|
||||
}
|
||||
|
||||
void Storage::onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
AccessType access
|
||||
)
|
||||
{
|
||||
log("typedef", fullName + " -> " + underlyingFullName, location);
|
||||
}
|
||||
|
||||
void Storage::onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
|
||||
{
|
||||
log("class", fullName, location);
|
||||
|
||||
@@ -14,6 +14,10 @@ public:
|
||||
Storage();
|
||||
virtual ~Storage();
|
||||
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
AccessType access
|
||||
);
|
||||
virtual void onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access);
|
||||
virtual void onStructParsed(const ParseLocation& location, const std::string& fullName, AccessType access);
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "data/parser/ParserClient.h"
|
||||
|
||||
class TextAccess;
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
@@ -14,6 +16,7 @@ public:
|
||||
virtual ~Parser();
|
||||
|
||||
virtual void parseFiles(const std::vector<std::string>& filePaths) = 0;
|
||||
virtual void parseFile(std::shared_ptr<TextAccess> textAccess) = 0;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ParserClient> m_client;
|
||||
|
||||
@@ -26,6 +26,10 @@ public:
|
||||
ParserClient();
|
||||
virtual ~ParserClient();
|
||||
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
AccessType access
|
||||
) = 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;
|
||||
|
||||
|
||||
@@ -13,6 +13,23 @@ ASTVisitor::~ASTVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitTypedefDecl(const clang::TypedefDecl* declaration)
|
||||
{
|
||||
const clang::SourceLocation& location = declaration->getLocStart();
|
||||
|
||||
if (isValidLocation(location))
|
||||
{
|
||||
m_client->onTypedefParsed(
|
||||
getParseLocation(location),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
declaration->getUnderlyingType().getAsString(),
|
||||
convertAccessType(declaration->getAccess())
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* declaration)
|
||||
{
|
||||
const clang::SourceLocation& location = declaration->getLocStart();
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
// return false;
|
||||
// }
|
||||
|
||||
virtual bool VisitTypedefDecl(const clang::TypedefDecl* declaration); // typedefs
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "data/parser/cxx/ASTActionFactory.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
|
||||
CxxParser::CxxParser(std::shared_ptr<ParserClient> client)
|
||||
: Parser(client)
|
||||
@@ -35,3 +36,9 @@ void CxxParser::parseFiles(const std::vector<std::string>& filePaths)
|
||||
|
||||
tool.run(&actionFactory);
|
||||
}
|
||||
|
||||
void CxxParser::parseFile(std::shared_ptr<TextAccess> textAccess)
|
||||
{
|
||||
ASTActionFactory actionFactory(m_client);
|
||||
clang::tooling::runToolOnCode(actionFactory.create(), textAccess->getText());
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ public:
|
||||
~CxxParser();
|
||||
|
||||
virtual void parseFiles(const std::vector<std::string>& filePaths);
|
||||
virtual void parseFile(std::shared_ptr<TextAccess> textAccess);
|
||||
};
|
||||
|
||||
#endif // CXX_PARSER_H
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
|
||||
class CxxParserTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
@@ -127,10 +128,63 @@ public:
|
||||
TS_ASSERT_EQUALS(client->enumFields[1], "X::E::Q");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_typedef_in_global_namespace()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
|
||||
CxxParser parser(client);
|
||||
std::string text = "typedef unsigned int uint;\n";
|
||||
|
||||
parser.parseFile(TextAccess::createFromString(text));
|
||||
|
||||
TS_ASSERT_EQUALS(client->typedefs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->typedefs[0], "unsigned int -> uint");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_typedef_in_named_namespace()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
|
||||
CxxParser parser(client);
|
||||
std::string text =
|
||||
"namespace test\n"
|
||||
"{\n"
|
||||
" typedef unsigned int uint;\n"
|
||||
"}\n";
|
||||
|
||||
parser.parseFile(TextAccess::createFromString(text));
|
||||
|
||||
TS_ASSERT_EQUALS(client->typedefs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->typedefs[0], "unsigned int -> test::uint");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_typedef_that_uses_type_defined_in_named_namespace()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
|
||||
CxxParser parser(client);
|
||||
std::string text =
|
||||
"namespace test\n"
|
||||
"{\n"
|
||||
" struct TestStruct{};\n"
|
||||
"}\n"
|
||||
"typedef test::TestStruct globalTestStruct;\n";
|
||||
|
||||
parser.parseFile(TextAccess::createFromString(text));
|
||||
|
||||
TS_ASSERT_EQUALS(client->typedefs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->typedefs[0], "test::TestStruct -> globalTestStruct");
|
||||
}
|
||||
|
||||
private:
|
||||
class TestParserClient: public ParserClient
|
||||
{
|
||||
public:
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
AccessType access
|
||||
)
|
||||
{
|
||||
typedefs.push_back(addAccessPrefix(underlyingFullName + " -> " + fullName, access));
|
||||
}
|
||||
|
||||
virtual void onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
|
||||
{
|
||||
classes.push_back(addAccessPrefix(fullName, access));
|
||||
@@ -186,6 +240,7 @@ private:
|
||||
enumFields.push_back(fullName);
|
||||
}
|
||||
|
||||
std::vector<std::string> typedefs;
|
||||
std::vector<std::string> classes;
|
||||
std::vector<std::string> enums;
|
||||
std::vector<std::string> enumFields;
|
||||
|
||||
Reference in New Issue
Block a user