data: Parsing functions with ParseFunction for signature comparing

This change switches function and method parsing to use the structure ParseFunction, which holds all important values of
the function. This structure is then used also in call and usage parsing to allow distinction between signatures.
This commit is contained in:
Eberhard Graether
2014-07-30 13:32:38 +02:00
parent acfc4934c2
commit dc09860680
19 changed files with 397 additions and 215 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
ConfigManager.cpp ERROR: value path/to/nowhere is not present in config. ConfigManager.cpp ERROR: value path/to/nowhere is not present in config.
Token.cpp ERROR: Location Id was not referenced by this Token. Token.cpp ERROR: Location Id was not referenced by this Token.
Node.cpp WARNING: Changing NodeType after it was already set, from namespace to class Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class
Edge.cpp ERROR: Nodes are not plain copies. Edge.cpp ERROR: Nodes are not plain copies.
Graph.cpp ERROR: Can't remove member edge, without removing the child node. Graph.cpp ERROR: Can't remove member edge, without removing the child node.
TextAccess.cpp WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 3 > 2 TextAccess.cpp WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 3 > 2
+2
View File
@@ -102,6 +102,8 @@ add_files(
data/location/TokenLocationLine.cpp data/location/TokenLocationLine.cpp
data/location/TokenLocationLine.h data/location/TokenLocationLine.h
data/parser/ParseFunction.cpp
data/parser/ParseFunction.h
data/parser/ParseLocation.cpp data/parser/ParseLocation.cpp
data/parser/ParseLocation.h data/parser/ParseLocation.h
data/parser/Parser.cpp data/parser/Parser.cpp
+46 -33
View File
@@ -6,6 +6,7 @@
#include "data/location/TokenLocation.h" #include "data/location/TokenLocation.h"
#include "data/location/TokenLocationFile.h" #include "data/location/TokenLocationFile.h"
#include "data/location/TokenLocationLine.h" #include "data/location/TokenLocationLine.h"
#include "data/parser/ParseFunction.h"
#include "data/parser/ParseLocation.h" #include "data/parser/ParseLocation.h"
#include "data/parser/ParseTypeUsage.h" #include "data/parser/ParseTypeUsage.h"
#include "data/parser/ParseVariable.h" #include "data/parser/ParseVariable.h"
@@ -109,45 +110,40 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable&
} }
void Storage::onFunctionParsed( void Storage::onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation ){
) log("function", function.fullName, location);
{
log("function", fullName, location);
Node* node = m_graph.createNodeHierarchyWithDistinctSignature( Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
Node::NODE_FUNCTION, fullName, Node::NODE_FUNCTION, function.fullName, ParserClient::functionSignatureStr(function)
ParserClient::functionSignatureStr(returnType.dataType, fullName, parameters, false)
); );
addTokenLocation(node, location); addTokenLocation(node, location);
addTokenLocation(node, scopeLocation, true); addTokenLocation(node, scopeLocation, true);
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType); addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, function.returnType);
for (const ParseTypeUsage& parameter : parameters) for (const ParseTypeUsage& parameter : function.parameters)
{ {
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter); addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
} }
} }
void Storage::onMethodParsed( void Storage::onMethodParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction, const ParseLocation& scopeLocation
bool isConst, bool isStatic, const ParseLocation& scopeLocation ){
) log("method", method.fullName, location);
{
log("method", fullName, location);
Node* node = m_graph.createNodeHierarchyWithDistinctSignature( Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
Node::NODE_METHOD, fullName, Node::NODE_METHOD, method.fullName, ParserClient::functionSignatureStr(method)
ParserClient::functionSignatureStr(returnType.dataType, fullName, parameters, isConst)
); );
if (isConst) if (method.isConst)
{ {
node->addComponentConst(std::make_shared<TokenComponentConst>()); node->addComponentConst(std::make_shared<TokenComponentConst>());
} }
if (isStatic) if (method.isStatic)
{ {
node->addComponentStatic(std::make_shared<TokenComponentStatic>()); node->addComponentStatic(std::make_shared<TokenComponentStatic>());
} }
@@ -162,8 +158,8 @@ void Storage::onMethodParsed(
addTokenLocation(node, location); addTokenLocation(node, location);
addTokenLocation(node, scopeLocation, true); addTokenLocation(node, scopeLocation, true);
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType); addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, method.returnType);
for (const ParseTypeUsage& parameter : parameters) for (const ParseTypeUsage& parameter : method.parameters)
{ {
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter); addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
} }
@@ -212,23 +208,40 @@ void Storage::onInheritanceParsed(
addTokenLocation(edge, location); addTokenLocation(edge, location);
} }
void Storage::onCallParsed(const ParseLocation& location, const std::string& callerName, const std::string& calleeName) void Storage::onCallParsed(const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee)
{ {
log("call", callerName + " -> " + calleeName, location); log("call", caller.fullName + " -> " + callee.fullName, location);
Node* callerNode = m_graph.createNodeHierarchy(callerName); Node* callerNode =
Node* calleeNode = m_graph.createNodeHierarchy(calleeName); m_graph.createNodeHierarchyWithDistinctSignature(caller.fullName, ParserClient::functionSignatureStr(caller));
Node* calleeNode =
m_graph.createNodeHierarchyWithDistinctSignature(callee.fullName, ParserClient::functionSignatureStr(callee));
Edge* edge = m_graph.createEdge(Edge::EDGE_CALL, callerNode, calleeNode); Edge* edge = m_graph.createEdge(Edge::EDGE_CALL, callerNode, calleeNode);
addTokenLocation(edge, location); addTokenLocation(edge, location);
} }
void Storage::onFieldUsageParsed(const ParseLocation& location, const std::string& userName, const std::string& usedName) void Storage::onCallParsed(const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee)
{ {
log("usage", userName + " -> " + usedName, location); log("call", caller.fullName + " -> " + callee.fullName, location);
Node* userNode = m_graph.createNodeHierarchy(userName); Node* callerNode =
m_graph.createNodeHierarchy(caller.fullName);
Node* calleeNode =
m_graph.createNodeHierarchyWithDistinctSignature(callee.fullName, ParserClient::functionSignatureStr(callee));
Edge* edge = m_graph.createEdge(Edge::EDGE_CALL, callerNode, calleeNode);
addTokenLocation(edge, location);
}
void Storage::onFieldUsageParsed(const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
{
log("usage", user.fullName + " -> " + usedName, location);
Node* userNode =
m_graph.createNodeHierarchyWithDistinctSignature(user.fullName, ParserClient::functionSignatureStr(user));
Node* usedNode = m_graph.createNodeHierarchy(usedName); Node* usedNode = m_graph.createNodeHierarchy(usedName);
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode); Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
@@ -236,12 +249,12 @@ void Storage::onFieldUsageParsed(const ParseLocation& location, const std::strin
} }
void Storage::onGlobalVariableUsageParsed( void Storage::onGlobalVariableUsageParsed(
const ParseLocation& location, const std::string& userName, const std::string& usedName const ParseLocation& location, const ParseFunction& user, const std::string& usedName
) ){
{ log("usage", user.fullName + " -> " + usedName, location);
log("usage", userName + " -> " + usedName, location);
Node* userNode = m_graph.createNodeHierarchy(userName); Node* userNode =
m_graph.createNodeHierarchyWithDistinctSignature(user.fullName, ParserClient::functionSignatureStr(user));;
Node* usedNode = m_graph.createNodeHierarchy(usedName); Node* usedNode = m_graph.createNodeHierarchy(usedName);
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode); Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
+10 -16
View File
@@ -28,8 +28,7 @@ public:
// ParserClient implementation // ParserClient implementation
virtual void onTypedefParsed( virtual void onTypedefParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType, const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType,
AccessType access AccessType access);
);
virtual void onClassParsed( virtual void onClassParsed(
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation); const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation);
virtual void onStructParsed( virtual void onStructParsed(
@@ -39,14 +38,10 @@ public:
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access); virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access);
virtual void onFunctionParsed( virtual void onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation);
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation
);
virtual void onMethodParsed( virtual void onMethodParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction, const ParseLocation& scopeLocation);
bool isConst, bool isStatic, const ParseLocation& scopeLocation
);
virtual void onNamespaceParsed( virtual void onNamespaceParsed(
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation); const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation);
@@ -56,16 +51,15 @@ public:
virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName); virtual void onEnumFieldParsed(const ParseLocation& location, const std::string& fullName);
virtual void onInheritanceParsed( virtual void onInheritanceParsed(
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access);
);
virtual void onCallParsed( virtual void onCallParsed(
const ParseLocation& location, const std::string& callerName, const std::string& calleeName const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee);
); virtual void onCallParsed(
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee);
virtual void onFieldUsageParsed( virtual void onFieldUsageParsed(
const ParseLocation& location, const std::string& userName, const std::string& usedName const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
);
virtual void onGlobalVariableUsageParsed( virtual void onGlobalVariableUsageParsed(
const ParseLocation& location, const std::string& userName, const std::string& usedName); const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
// GraphAccess implementation // GraphAccess implementation
virtual Id getIdForNodeWithName(const std::string& fullName) const; virtual Id getIdForNodeWithName(const std::string& fullName) const;
+2 -2
View File
@@ -90,7 +90,7 @@ Node* Graph::createNodeHierarchy(Node::NodeType type, const std::string& fullNam
Node* Graph::createNodeHierarchyWithDistinctSignature(const std::string& fullName, const std::string& signature) Node* Graph::createNodeHierarchyWithDistinctSignature(const std::string& fullName, const std::string& signature)
{ {
return createNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED, fullName, signature); return createNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, fullName, signature);
} }
Node* Graph::createNodeHierarchyWithDistinctSignature( Node* Graph::createNodeHierarchyWithDistinctSignature(
@@ -103,7 +103,7 @@ Node* Graph::createNodeHierarchyWithDistinctSignature(
TokenComponentSignature* sigComponent = node->getComponent<TokenComponentSignature>(); TokenComponentSignature* sigComponent = node->getComponent<TokenComponentSignature>();
if (sigComponent && sigComponent->getSignature() == signature) if (sigComponent && sigComponent->getSignature() == signature)
{ {
if (type != Node::NODE_UNDEFINED) if (type != Node::NODE_UNDEFINED && type != Node::NODE_UNDEFINED_FUNCTION)
{ {
node->setType(type); node->setType(type);
} }
+5 -3
View File
@@ -31,10 +31,10 @@ Node::NodeType Node::getType() const
void Node::setType(NodeType type) void Node::setType(NodeType type)
{ {
if (type != m_type && m_type != NODE_UNDEFINED) if (type != m_type && m_type != NODE_UNDEFINED && m_type != NODE_UNDEFINED_FUNCTION)
{ {
LOG_WARNING( LOG_WARNING(
"Changing NodeType after it was already set, from " + getTypeString(m_type) + " to " + getTypeString(type) "Cannot change NodeType after it was already set from " + getTypeString(m_type) + " to " + getTypeString(type)
); );
return; return;
} }
@@ -229,7 +229,7 @@ void Node::addComponentSignature(std::shared_ptr<TokenComponentSignature> compon
{ {
LOG_ERROR("TokenComponentSignature has been set before!"); LOG_ERROR("TokenComponentSignature has been set before!");
} }
else if (m_type != NODE_FUNCTION && m_type != NODE_METHOD) else if (m_type != NODE_UNDEFINED_FUNCTION && m_type != NODE_FUNCTION && m_type != NODE_METHOD)
{ {
LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString(m_type)); LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString(m_type));
} }
@@ -245,6 +245,8 @@ std::string Node::getTypeString(NodeType type) const
{ {
case NODE_UNDEFINED: case NODE_UNDEFINED:
return "undefined"; return "undefined";
case NODE_UNDEFINED_FUNCTION:
return "undefined function";
case NODE_CLASS: case NODE_CLASS:
return "class"; return "class";
case NODE_STRUCT: case NODE_STRUCT:
+1
View File
@@ -19,6 +19,7 @@ public:
enum NodeType enum NodeType
{ {
NODE_UNDEFINED, NODE_UNDEFINED,
NODE_UNDEFINED_FUNCTION,
NODE_CLASS, NODE_CLASS,
NODE_STRUCT, NODE_STRUCT,
NODE_GLOBAL_VARIABLE, NODE_GLOBAL_VARIABLE,
+16
View File
@@ -0,0 +1,16 @@
#include "data/parser/ParseFunction.h"
ParseFunction::ParseFunction(
const ParseTypeUsage& returnType,
const std::string& fullName,
const std::vector<ParseTypeUsage>& parameters,
bool isStatic,
bool isConst
)
: returnType(returnType)
, fullName(fullName)
, parameters(parameters)
, isStatic(isStatic)
, isConst(isConst)
{
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef PARSE_FUNCTION_H
#define PARSE_FUNCTION_H
#include <string>
#include "data/parser/ParseTypeUsage.h"
struct ParseFunction
{
ParseFunction(
const ParseTypeUsage& returnType,
const std::string& fullName,
const std::vector<ParseTypeUsage>& parameters,
bool isStatic = false,
bool isConst = false
);
const ParseTypeUsage returnType;
const std::string fullName;
const std::vector<ParseTypeUsage> parameters;
const bool isStatic;
const bool isConst;
};
#endif // PARSE_FUNCTION_H
+1 -1
View File
@@ -16,7 +16,7 @@ struct ParseLocation
bool isValid() const; bool isValid() const;
const std::string filePath; std::string filePath;
uint startLineNumber; uint startLineNumber;
uint startColumnNumber; uint startColumnNumber;
uint endLineNumber; uint endLineNumber;
+9 -18
View File
@@ -2,6 +2,7 @@
#include <sstream> #include <sstream>
#include "data/parser/ParseFunction.h"
#include "data/parser/ParseLocation.h" #include "data/parser/ParseLocation.h"
#include "data/parser/ParseTypeUsage.h" #include "data/parser/ParseTypeUsage.h"
#include "data/parser/ParseVariable.h" #include "data/parser/ParseVariable.h"
@@ -103,26 +104,16 @@ std::string ParserClient::parameterStr(const std::vector<ParseTypeUsage> paramet
return str + ")"; return str + ")";
} }
std::string ParserClient::functionStr( std::string ParserClient::functionStr(const ParseFunction& function)
const DataType& returnType, {
const std::string& fullName, std::string str =
const std::vector<ParseTypeUsage>& parameters, function.returnType.dataType.getFullTypeName() + " " + function.fullName + parameterStr(function.parameters);
bool isConst return addConstPrefix(addStaticPrefix(str, function.isStatic), function.isConst, false);
){
return addConstPrefix(
returnType.getFullTypeName() + " " + fullName + parameterStr(parameters),
isConst,
false
);
} }
std::string ParserClient::functionSignatureStr( std::string ParserClient::functionSignatureStr(const ParseFunction& function)
const DataType& returnType, {
const std::string& fullName, return addConstPrefix(function.fullName + parameterStr(function.parameters), function.isConst, false);
const std::vector<ParseTypeUsage>& parameters,
bool isConst
){
return addConstPrefix(fullName + parameterStr(parameters), isConst, false);
} }
ParserClient::ParserClient() ParserClient::ParserClient()
+11 -20
View File
@@ -4,6 +4,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
struct ParseFunction;
struct ParseLocation; struct ParseLocation;
struct ParseTypeUsage; struct ParseTypeUsage;
struct ParseVariable; struct ParseVariable;
@@ -35,18 +36,8 @@ public:
static std::string variableStr(const ParseVariable& variable); static std::string variableStr(const ParseVariable& variable);
static std::string parameterStr(const std::vector<ParseTypeUsage> parameters); static std::string parameterStr(const std::vector<ParseTypeUsage> parameters);
static std::string functionStr( static std::string functionStr(const ParseFunction& function);
const DataType& returnType, static std::string functionSignatureStr(const ParseFunction& function);
const std::string& fullName,
const std::vector<ParseTypeUsage>& parameters,
bool isConst
);
static std::string functionSignatureStr(
const DataType& returnType,
const std::string& fullName,
const std::vector<ParseTypeUsage>& parameters,
bool isConst
);
ParserClient(); ParserClient();
virtual ~ParserClient(); virtual ~ParserClient();
@@ -65,12 +56,10 @@ public:
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0; virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0;
virtual void onFunctionParsed( virtual void onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation) = 0;
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation) = 0;
virtual void onMethodParsed( virtual void onMethodParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction, const ParseLocation& scopeLocation) = 0;
bool isConst, bool isStatic, const ParseLocation& scopeLocation) = 0;
virtual void onNamespaceParsed( virtual void onNamespaceParsed(
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation) = 0; const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation) = 0;
@@ -83,11 +72,13 @@ public:
virtual void onInheritanceParsed( virtual void onInheritanceParsed(
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access) = 0; const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access) = 0;
virtual void onCallParsed( virtual void onCallParsed(
const ParseLocation& location, const std::string& callerName, const std::string& calleeName) = 0; const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee) = 0;
virtual void onCallParsed(
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee) = 0;
virtual void onFieldUsageParsed( virtual void onFieldUsageParsed(
const ParseLocation& location, const std::string& userName, const std::string& usedName) = 0; const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
virtual void onGlobalVariableUsageParsed( virtual void onGlobalVariableUsageParsed(
const ParseLocation& location, const std::string& userName, const std::string& usedName) = 0; const ParseLocation& location, const ParseFunction& user, const std::string& usedName) = 0;
}; };
#endif // PARSER_CLIENT_H #endif // PARSER_CLIENT_H
+28 -6
View File
@@ -1,8 +1,16 @@
#include "data/parser/cxx/ASTBodyVisitor.h" #include "data/parser/cxx/ASTBodyVisitor.h"
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl) ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::FunctionDecl* functionDecl)
: m_client(client) : m_client(client)
, m_parentDecl(parentDecl) , m_functionDecl(functionDecl)
, m_varDecl(nullptr)
{
}
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::VarDecl* varDecl)
: m_client(client)
, m_functionDecl(nullptr)
, m_varDecl(varDecl)
{ {
} }
@@ -28,14 +36,28 @@ void ASTBodyVisitor::VisitChildren(clang::Stmt* stmt)
void ASTBodyVisitor::VisitCallExpr(clang::CallExpr* expr) void ASTBodyVisitor::VisitCallExpr(clang::CallExpr* expr)
{ {
m_client->VisitCallExprInDeclBody(m_parentDecl, expr); if (m_functionDecl)
{
m_client->VisitCallExprInDeclBody(m_functionDecl, expr);
}
else
{
m_client->VisitCallExprInDeclBody(m_varDecl, expr);
}
VisitStmt(expr); VisitStmt(expr);
} }
void ASTBodyVisitor::VisitCXXConstructExpr(clang::CXXConstructExpr* expr) void ASTBodyVisitor::VisitCXXConstructExpr(clang::CXXConstructExpr* expr)
{ {
m_client->VisitCXXConstructExprInDeclBody(m_parentDecl, expr); if (m_functionDecl)
{
m_client->VisitCXXConstructExprInDeclBody(m_functionDecl, expr);
}
else
{
m_client->VisitCXXConstructExprInDeclBody(m_varDecl, expr);
}
VisitStmt(expr); VisitStmt(expr);
} }
@@ -44,7 +66,7 @@ void ASTBodyVisitor::VisitMemberExpr(clang::make_ptr<clang::MemberExpr>::type ex
{ {
if (expr->getMemberDecl()->getKind() == clang::Decl::Kind::Field) if (expr->getMemberDecl()->getKind() == clang::Decl::Kind::Field)
{ {
m_client->VisitFieldUsageExprInDeclBody(m_parentDecl, expr); m_client->VisitFieldUsageExprInDeclBody(m_functionDecl, expr);
} }
VisitStmt(expr); VisitStmt(expr);
} }
@@ -53,7 +75,7 @@ void ASTBodyVisitor::VisitDeclRefExpr(clang::make_ptr<clang::DeclRefExpr>::type
{ {
if (expr->getDecl()->getKind() == clang::Decl::Var && expr->getDecl()->isDefinedOutsideFunctionOrMethod()) if (expr->getDecl()->getKind() == clang::Decl::Var && expr->getDecl()->isDefinedOutsideFunctionOrMethod())
{ {
m_client->VisitGlobalVariableUsageExprInDeclBody(m_parentDecl, expr); m_client->VisitGlobalVariableUsageExprInDeclBody(m_functionDecl, expr);
} }
VisitStmt(expr); VisitStmt(expr);
} }
+4 -2
View File
@@ -7,7 +7,8 @@
class ASTBodyVisitor: public clang::StmtVisitor<ASTBodyVisitor> class ASTBodyVisitor: public clang::StmtVisitor<ASTBodyVisitor>
{ {
public: public:
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl); ASTBodyVisitor(ASTBodyVisitorClient* client, clang::FunctionDecl* functionDecl);
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::VarDecl* varDecl);
virtual ~ASTBodyVisitor(); virtual ~ASTBodyVisitor();
void VisitStmt(clang::Stmt* stmt); void VisitStmt(clang::Stmt* stmt);
@@ -19,7 +20,8 @@ public:
private: private:
ASTBodyVisitorClient* m_client; ASTBodyVisitorClient* m_client;
clang::NamedDecl* m_parentDecl; clang::FunctionDecl* m_functionDecl;
clang::VarDecl* m_varDecl;
}; };
#endif // AST_BODY_VISITOR #endif // AST_BODY_VISITOR
@@ -11,10 +11,12 @@ public:
ASTBodyVisitorClient(); ASTBodyVisitorClient();
virtual ~ASTBodyVisitorClient(); virtual ~ASTBodyVisitorClient();
virtual void VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr) = 0; virtual void VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr) = 0;
virtual void VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr) = 0; virtual void VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr) = 0;
virtual void VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr) = 0; virtual void VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr) = 0;
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr) = 0; virtual void VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CXXConstructExpr* expr) = 0;
virtual void VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr) = 0;
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0;
}; };
#endif // AST_BODY_VISITOR_CLIENT_H #endif // AST_BODY_VISITOR_CLIENT_H
+105 -59
View File
@@ -2,6 +2,7 @@
#include "data/parser/cxx/ASTBodyVisitor.h" #include "data/parser/cxx/ASTBodyVisitor.h"
#include "data/parser/cxx/utilityCxx.h" #include "data/parser/cxx/utilityCxx.h"
#include "data/parser/ParseFunction.h"
#include "data/parser/ParseLocation.h" #include "data/parser/ParseLocation.h"
#include "data/parser/ParseTypeUsage.h" #include "data/parser/ParseTypeUsage.h"
#include "data/parser/ParseVariable.h" #include "data/parser/ParseVariable.h"
@@ -141,9 +142,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
{ {
m_client->onFunctionParsed( m_client->onFunctionParsed(
getParseLocationForNamedDecl(declaration), getParseLocationForNamedDecl(declaration),
declaration->getQualifiedNameAsString(), getParseFunction(declaration),
getParseTypeUsageOfReturnType(declaration),
getParameters(declaration),
getParseLocationOfFunctionBody(declaration) getParseLocationOfFunctionBody(declaration)
); );
@@ -173,13 +172,9 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
m_client->onMethodParsed( m_client->onMethodParsed(
getParseLocationForNamedDecl(declaration), getParseLocationForNamedDecl(declaration),
declaration->getQualifiedNameAsString(), getParseFunction(declaration),
getParseTypeUsageOfReturnType(declaration),
getParameters(declaration),
convertAccessType(declaration->getAccess()), convertAccessType(declaration->getAccess()),
abstraction, abstraction,
declaration->isConst(),
declaration->isStatic(),
getParseLocationOfFunctionBody(declaration) getParseLocationOfFunctionBody(declaration)
); );
@@ -206,9 +201,8 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
if (init->isMemberInitializer()) if (init->isMemberInitializer())
{ {
m_client->onFieldUsageParsed( m_client->onFieldUsageParsed(
// getParseLocation(init->getSourceRange()),
getParseLocationForNamedDecl(init->getMember(), init->getMemberLocation()), getParseLocationForNamedDecl(init->getMember(), init->getMemberLocation()),
declaration->getQualifiedNameAsString(), getParseFunction(declaration),
init->getMember()->getQualifiedNameAsString() init->getMember()->getQualifiedNameAsString()
); );
} }
@@ -264,7 +258,7 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
return true; return true;
} }
void ASTVisitor::VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr) void ASTVisitor::VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr)
{ {
// if (clang::FunctionDecl *CalleeDecl = CE->getDirectCallee()) // if (clang::FunctionDecl *CalleeDecl = CE->getDirectCallee())
// { // {
@@ -282,21 +276,39 @@ void ASTVisitor::VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr
m_client->onCallParsed( m_client->onCallParsed(
getParseLocation(expr->getSourceRange()), getParseLocation(expr->getSourceRange()),
decl->getQualifiedNameAsString(), getParseFunction(decl),
expr->getDirectCallee()->getQualifiedNameAsString() getParseFunction(expr->getDirectCallee())
); );
} }
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr) void ASTVisitor::VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr)
{ {
m_client->onCallParsed( m_client->onCallParsed(
getParseLocation(expr->getSourceRange()), getParseLocation(expr->getSourceRange()),
decl->getQualifiedNameAsString(), getParseVariable(decl),
expr->getConstructor()->getQualifiedNameAsString() getParseFunction(expr->getDirectCallee())
); );
} }
void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr) void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr)
{
m_client->onCallParsed(
getParseLocation(expr->getSourceRange()),
getParseFunction(decl),
getParseFunction(expr->getConstructor())
);
}
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CXXConstructExpr* expr)
{
m_client->onCallParsed(
getParseLocation(expr->getSourceRange()),
getParseVariable(decl),
getParseFunction(expr->getConstructor())
);
}
void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr)
{ {
ParseLocation parseLocation = getParseLocation(expr->getSourceRange()); ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
@@ -305,12 +317,12 @@ void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::Me
m_client->onFieldUsageParsed( m_client->onFieldUsageParsed(
parseLocation, parseLocation,
decl->getQualifiedNameAsString(), getParseFunction(decl),
expr->getMemberDecl()->getQualifiedNameAsString() expr->getMemberDecl()->getQualifiedNameAsString()
); );
} }
void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr) void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr)
{ {
ParseLocation parseLocation = getParseLocation(expr->getSourceRange()); ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
@@ -319,7 +331,7 @@ void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl,
m_client->onGlobalVariableUsageParsed( m_client->onGlobalVariableUsageParsed(
parseLocation, parseLocation,
decl->getQualifiedNameAsString(), getParseFunction(decl),
expr->getDecl()->getQualifiedNameAsString() expr->getDecl()->getQualifiedNameAsString()
); );
} }
@@ -330,6 +342,27 @@ bool ASTVisitor::hasValidLocation(const clang::Decl* declaration) const
return location.isValid() && m_context->getSourceManager().isWrittenInMainFile(location); return location.isValid() && m_context->getSourceManager().isWrittenInMainFile(location);
} }
std::string ASTVisitor::getTypeName(const clang::QualType& qualType) const
{
DataType dataType = utility::qualTypeToDataType(qualType);
return dataType.getRawTypeName();
}
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;
}
}
ParseLocation ASTVisitor::getParseLocation(const clang::SourceRange& sourceRange) const ParseLocation ASTVisitor::getParseLocation(const clang::SourceRange& sourceRange) const
{ {
if (sourceRange.isInvalid()) if (sourceRange.isInvalid())
@@ -389,33 +422,21 @@ ParseLocation ASTVisitor::getParseLocationOfRecordBody(clang::CXXRecordDecl* dec
return ParseLocation(); return ParseLocation();
} }
ParseVariable ASTVisitor::getParseVariable(clang::DeclaratorDecl* declaration) const
{
bool isStatic = false;
if (clang::isa<clang::VarDecl>(declaration))
{
clang::VarDecl* varDecl = static_cast<clang::VarDecl*>(declaration);
isStatic = varDecl->isStaticDataMember() || varDecl->getStorageClass() == clang::SC_Static;
}
return ParseVariable(
getParseTypeUsage(declaration->getTypeSourceInfo()->getTypeLoc(), declaration->getType()),
declaration->getQualifiedNameAsString(),
isStatic
);
}
ParseTypeUsage ASTVisitor::getParseTypeUsage(clang::TypeLoc typeLoc, const clang::QualType& type) const ParseTypeUsage ASTVisitor::getParseTypeUsage(clang::TypeLoc typeLoc, const clang::QualType& type) const
{ {
while (typeLoc.getNextTypeLoc())
{
typeLoc = typeLoc.getNextTypeLoc();
}
ParseLocation parseLocation = getParseLocation(typeLoc.getSourceRange());
DataType dataType = utility::qualTypeToDataType(type); DataType dataType = utility::qualTypeToDataType(type);
ParseLocation parseLocation;
parseLocation.endColumnNumber += dataType.getRawTypeName().size() - 1; if (!typeLoc.isNull())
{
while (typeLoc.getNextTypeLoc())
{
typeLoc = typeLoc.getNextTypeLoc();
}
parseLocation = getParseLocation(typeLoc.getSourceRange());
parseLocation.endColumnNumber += dataType.getRawTypeName().size() - 1;
}
return ParseTypeUsage(parseLocation, dataType); return ParseTypeUsage(parseLocation, dataType);
} }
@@ -423,10 +444,16 @@ ParseTypeUsage ASTVisitor::getParseTypeUsage(clang::TypeLoc typeLoc, const clang
ParseTypeUsage ASTVisitor::getParseTypeUsageOfReturnType(clang::FunctionDecl* declaration) const ParseTypeUsage ASTVisitor::getParseTypeUsageOfReturnType(clang::FunctionDecl* declaration) const
{ {
// TODO: use FunctionDecl::getReturnTypeSourceRange() in newer clang version // TODO: use FunctionDecl::getReturnTypeSourceRange() in newer clang version
const clang::TypeSourceInfo *TSI = declaration->getTypeSourceInfo(); clang::TypeLoc typeLoc;
const clang::FunctionTypeLoc FTL = TSI->getTypeLoc().IgnoreParens().getAs<clang::FunctionTypeLoc>();
return getParseTypeUsage(FTL.getReturnLoc(), declaration->getReturnType()); const clang::TypeSourceInfo *TSI = declaration->getTypeSourceInfo();
if (TSI)
{
const clang::FunctionTypeLoc FTL = TSI->getTypeLoc().IgnoreParens().getAs<clang::FunctionTypeLoc>();
typeLoc = FTL.getReturnLoc();
}
return getParseTypeUsage(typeLoc, declaration->getReturnType());
} }
std::vector<ParseTypeUsage> ASTVisitor::getParameters(clang::FunctionDecl* declaration) const std::vector<ParseTypeUsage> ASTVisitor::getParameters(clang::FunctionDecl* declaration) const
@@ -442,23 +469,42 @@ std::vector<ParseTypeUsage> ASTVisitor::getParameters(clang::FunctionDecl* decla
return parameters; return parameters;
} }
std::string ASTVisitor::getTypeName(const clang::QualType& qualType) const ParseVariable ASTVisitor::getParseVariable(clang::DeclaratorDecl* declaration) const
{ {
DataType dataType = utility::qualTypeToDataType(qualType); bool isStatic = false;
return dataType.getRawTypeName(); if (clang::isa<clang::VarDecl>(declaration))
{
clang::VarDecl* varDecl = clang::dyn_cast<clang::VarDecl>(declaration);
isStatic = varDecl->isStaticDataMember() || varDecl->getStorageClass() == clang::SC_Static;
}
return ParseVariable(
getParseTypeUsage(declaration->getTypeSourceInfo()->getTypeLoc(), declaration->getType()),
declaration->getQualifiedNameAsString(),
isStatic
);
} }
ParserClient::AccessType ASTVisitor::convertAccessType(clang::AccessSpecifier access) const ParseFunction ASTVisitor::getParseFunction(clang::FunctionDecl* declaration) const
{ {
switch (access) bool isStatic = false;
bool isConst = false;
if (clang::isa<clang::CXXMethodDecl>(declaration))
{ {
case clang::AS_public: clang::CXXMethodDecl* methodDecl = clang::dyn_cast<clang::CXXMethodDecl>(declaration);
return ParserClient::ACCESS_PUBLIC; isStatic = methodDecl->isStatic();
case clang::AS_protected: isConst = methodDecl->isConst();
return ParserClient::ACCESS_PROTECTED;
case clang::AS_private:
return ParserClient::ACCESS_PRIVATE;
case clang::AS_none:
return ParserClient::ACCESS_NONE;
} }
else
{
isStatic = declaration->getStorageClass() == clang::SC_Static;
}
return ParseFunction(
getParseTypeUsageOfReturnType(declaration),
declaration->getQualifiedNameAsString(),
getParameters(declaration),
isStatic,
isConst
);
} }
+13 -8
View File
@@ -39,25 +39,30 @@ public:
virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* declaration); // enum fields virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* declaration); // enum fields
// ASTBodyVisitorClient implementation // ASTBodyVisitorClient implementation
virtual void VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr); // calls virtual void VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr); // calls
virtual void VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr); // constructor calls virtual void VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr); // calls in initialization of global variables
virtual void VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr); // field usages virtual void VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr); // constructor calls
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr); // global variable usage virtual void VisitCXXConstructExprInDeclBody(clang::VarDecl* decl, clang::CXXConstructExpr* expr); // constructor calls of global variables
virtual void VisitFieldUsageExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr); // field usages
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // global variable usage
private: private:
bool hasValidLocation(const clang::Decl* declaration) const; bool hasValidLocation(const clang::Decl* declaration) const;
std::string getTypeName(const clang::QualType& qualType) const;
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const; ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl, const clang::SourceLocation& loc) const; ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl, const clang::SourceLocation& loc) const;
ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl) const; ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl) const;
ParseLocation getParseLocationOfFunctionBody(clang::FunctionDecl* decl) const; ParseLocation getParseLocationOfFunctionBody(clang::FunctionDecl* decl) const;
ParseLocation getParseLocationOfRecordBody(clang::CXXRecordDecl* decl) const; ParseLocation getParseLocationOfRecordBody(clang::CXXRecordDecl* decl) const;
ParseVariable getParseVariable(clang::DeclaratorDecl* declaration) const;
ParseTypeUsage getParseTypeUsage(clang::TypeLoc typeLoc, const clang::QualType& type) const; ParseTypeUsage getParseTypeUsage(clang::TypeLoc typeLoc, const clang::QualType& type) const;
ParseTypeUsage getParseTypeUsageOfReturnType(clang::FunctionDecl* declaration) const; ParseTypeUsage getParseTypeUsageOfReturnType(clang::FunctionDecl* declaration) const;
std::vector<ParseTypeUsage> getParameters(clang::FunctionDecl* declaration) const; std::vector<ParseTypeUsage> getParameters(clang::FunctionDecl* declaration) const;
DataType qualTypeToDataType(clang::QualType qualType);
std::string getTypeName(const clang::QualType& qualType) const; ParseVariable getParseVariable(clang::DeclaratorDecl* declaration) const;
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const; ParseFunction getParseFunction(clang::FunctionDecl* declaration) const;
clang::ASTContext* m_context; clang::ASTContext* m_context;
std::shared_ptr<ParserClient> m_client; std::shared_ptr<ParserClient> m_client;
+101 -42
View File
@@ -3,6 +3,7 @@
#include <sstream> #include <sstream>
#include "data/parser/cxx/CxxParser.h" #include "data/parser/cxx/CxxParser.h"
#include "data/parser/ParseFunction.h"
#include "data/parser/ParseLocation.h" #include "data/parser/ParseLocation.h"
#include "data/parser/ParserClient.h" #include "data/parser/ParserClient.h"
#include "data/parser/ParseTypeUsage.h" #include "data/parser/ParseTypeUsage.h"
@@ -214,6 +215,19 @@ public:
TS_ASSERT_EQUALS(client->functions[0], "int (anonymous namespace)::sum(int, int) <3:6 3:8>"); TS_ASSERT_EQUALS(client->functions[0], "int (anonymous namespace)::sum(int, int) <3:6 3:8>");
} }
void test_cxx_parser_finds_static_function_in_global_namespace()
{
std::shared_ptr<TestParserClient> client = parseCode(
"static int ceil(float a)\n"
"{\n"
" return static_cast<int>(a) + 1;\n"
"}\n"
);
TS_ASSERT_EQUALS(client->functions.size(), 1);
TS_ASSERT_EQUALS(client->functions[0], "static int ceil(float) <1:1 <1:12 1:15> 4:1>");
}
void test_cxx_parser_finds_method_declaration() void test_cxx_parser_finds_method_declaration()
{ {
std::shared_ptr<TestParserClient> client = parseCode( std::shared_ptr<TestParserClient> client = parseCode(
@@ -497,7 +511,50 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "main -> sum <7:2 7:10>"); TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <7:2 7:10>");
}
void test_cxx_parser_finds_call_in_function_with_right_signature()
{
std::shared_ptr<TestParserClient> client = parseCode(
"int sum(int a, int b)\n"
"{\n"
" return a + b;\n"
"}\n"
"void func()\n"
"{\n"
"}\n"
"void func(bool right)\n"
"{\n"
" sum(1, 2);\n"
"}\n"
);
TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "void func(_Bool) -> int sum(int, int) <10:2 10:10>");
}
void test_cxx_parser_finds_call_to_function_with_right_signature()
{
std::shared_ptr<TestParserClient> client = parseCode(
"int sum(int a, int b)\n"
"{\n"
" return a + b;\n"
"}\n"
"float sum(float a, float b)\n"
"{\n"
" return a + b;\n"
"}\n"
"int main()\n"
"{\n"
" sum(1, 2);\n"
" sum(1.0f, 0.5f);\n"
"}\n"
);
TS_ASSERT_EQUALS(client->calls.size(), 2);
TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <11:2 11:10>");
TS_ASSERT_EQUALS(client->calls[1], "int main() -> float sum(float, float) <12:2 12:16>");
} }
void test_cxx_parser_finds_call_within_call_in_function() void test_cxx_parser_finds_call_within_call_in_function()
@@ -514,8 +571,8 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls.size(), 2);
TS_ASSERT_EQUALS(client->calls[0], "main -> sum <7:9 7:25>"); TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <7:9 7:25>");
TS_ASSERT_EQUALS(client->calls[1], "main -> sum <7:16 7:24>"); TS_ASSERT_EQUALS(client->calls[1], "int main() -> int sum(int, int) <7:16 7:24>");
} }
void test_cxx_parser_finds_call_in_method() void test_cxx_parser_finds_call_in_method()
@@ -535,7 +592,7 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "App::main -> sum <9:10 9:18>"); TS_ASSERT_EQUALS(client->calls[0], "int App::main() -> int sum(int, int) <9:10 9:18>");
} }
void test_cxx_parser_finds_constructor_call() void test_cxx_parser_finds_constructor_call()
@@ -553,7 +610,7 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "main -> App::App <8:6 8:6>"); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <8:6 8:6>");
} }
void test_cxx_parser_finds_constructor_without_definition_call() void test_cxx_parser_finds_constructor_without_definition_call()
@@ -569,7 +626,7 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "main -> App::App <6:6 6:6>"); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <6:6 6:6>");
} }
void test_cxx_parser_finds_constructor_call_of_field() void test_cxx_parser_finds_constructor_call_of_field()
@@ -587,7 +644,7 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "App::App -> Item::Item <7:2 7:2>"); TS_ASSERT_EQUALS(client->calls[0], "void App::App() -> void Item::Item() <7:2 7:2>");
} }
void test_cxx_parser_finds_constructor_call_of_field_in_initialization_list() void test_cxx_parser_finds_constructor_call_of_field_in_initialization_list()
@@ -608,7 +665,7 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "App::App -> Item::Item <9:5 9:11>"); TS_ASSERT_EQUALS(client->calls[0], "void App::App() -> void Item::Item(int) <9:5 9:11>");
} }
void test_cxx_parser_finds_function_call_within_constructor_call_of_field_in_initialization_list() void test_cxx_parser_finds_function_call_within_constructor_call_of_field_in_initialization_list()
@@ -630,8 +687,8 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls.size(), 2);
TS_ASSERT_EQUALS(client->calls[0], "App::App -> Item::Item <10:5 10:15>"); TS_ASSERT_EQUALS(client->calls[0], "void App::App() -> void Item::Item(int) <10:5 10:15>");
TS_ASSERT_EQUALS(client->calls[1], "App::App -> one <10:10 10:14>"); TS_ASSERT_EQUALS(client->calls[1], "void App::App() -> int one() <10:10 10:14>");
} }
void test_cxx_parser_finds_copy_constructor_call() void test_cxx_parser_finds_copy_constructor_call()
@@ -651,8 +708,8 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls.size(), 2);
TS_ASSERT_EQUALS(client->calls[0], "main -> App::App <9:6 9:6>"); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <9:6 9:6>");
TS_ASSERT_EQUALS(client->calls[1], "main -> App::App <10:6 10:14>"); TS_ASSERT_EQUALS(client->calls[1], "int main() -> void App::App(class App const &) <10:6 10:14>");
} }
void test_cxx_parser_finds_global_constructor_call() void test_cxx_parser_finds_global_constructor_call()
@@ -667,7 +724,7 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "app -> App::App <6:5 6:5>"); TS_ASSERT_EQUALS(client->calls[0], "app -> void App::App() <6:5 6:5>");
} }
void test_cxx_parser_finds_global_function_call() void test_cxx_parser_finds_global_function_call()
@@ -678,7 +735,7 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls.size(), 1);
TS_ASSERT_EQUALS(client->calls[0], "a -> one <2:9 2:13>"); TS_ASSERT_EQUALS(client->calls[0], "a -> int one() <2:9 2:13>");
} }
void test_cxx_parser_finds_operator_call() void test_cxx_parser_finds_operator_call()
@@ -699,8 +756,8 @@ public:
); );
TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls.size(), 2);
TS_ASSERT_EQUALS(client->calls[0], "main -> App::App <10:6 10:6>"); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <10:6 10:6>");
TS_ASSERT_EQUALS(client->calls[1], "main -> App::operator+ <11:2 11:8>"); TS_ASSERT_EQUALS(client->calls[1], "int main() -> void App::operator+(int) <11:2 11:8>");
} }
void test_cxx_parser_finds_usage_of_global_variable_in_function() void test_cxx_parser_finds_usage_of_global_variable_in_function()
@@ -715,7 +772,7 @@ public:
); );
TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages.size(), 1);
TS_ASSERT_EQUALS(client->usages[0], "main -> bar <5:2 5:4>"); TS_ASSERT_EQUALS(client->usages[0], "int main() -> bar <5:2 5:4>");
} }
void test_cxx_parser_finds_usage_of_global_variable_in_method() void test_cxx_parser_finds_usage_of_global_variable_in_method()
@@ -733,7 +790,7 @@ public:
); );
TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages.size(), 1);
TS_ASSERT_EQUALS(client->usages[0], "App::foo -> bar <7:3 7:5>"); TS_ASSERT_EQUALS(client->usages[0], "void App::foo() -> bar <7:3 7:5>");
} }
void test_cxx_parser_finds_usage_of_field_in_method() void test_cxx_parser_finds_usage_of_field_in_method()
@@ -751,8 +808,8 @@ public:
); );
TS_ASSERT_EQUALS(client->usages.size(), 2); TS_ASSERT_EQUALS(client->usages.size(), 2);
TS_ASSERT_EQUALS(client->usages[0], "App::foo -> App::bar <5:3 5:5>"); TS_ASSERT_EQUALS(client->usages[0], "void App::foo() -> App::bar <5:3 5:5>");
TS_ASSERT_EQUALS(client->usages[1], "App::foo -> App::bar <6:3 6:11>"); TS_ASSERT_EQUALS(client->usages[1], "void App::foo() -> App::bar <6:3 6:11>");
} }
void test_cxx_parser_finds_usage_of_field_in_initialization_list() void test_cxx_parser_finds_usage_of_field_in_initialization_list()
@@ -768,7 +825,7 @@ public:
); );
TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages.size(), 1);
TS_ASSERT_EQUALS(client->usages[0], "App::App -> App::bar <4:5 4:7>"); TS_ASSERT_EQUALS(client->usages[0], "void App::App() -> App::bar <4:5 4:7>");
} }
void test_cxx_parser_finds_return_type_use_in_function() void test_cxx_parser_finds_return_type_use_in_function()
@@ -874,33 +931,29 @@ private:
} }
virtual void onFunctionParsed( virtual void onFunctionParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation
){ ){
std::string str = functionStr(returnType.dataType, fullName, parameters, false); functions.push_back(addLocationSuffix(functionStr(function), location, scopeLocation));
functions.push_back(addLocationSuffix(str, location, scopeLocation));
addTypeUse(returnType); addTypeUse(function.returnType);
for (const ParseTypeUsage& parameter : parameters) for (const ParseTypeUsage& parameter : function.parameters)
{ {
addTypeUse(parameter); addTypeUse(parameter);
} }
} }
virtual void onMethodParsed( virtual void onMethodParsed(
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType, const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction, const ParseLocation& scopeLocation
bool isConst, bool isStatic, const ParseLocation& scopeLocation ){
) std::string str = functionStr(method);
{ str = addAbstractionPrefix(str, abstraction);
std::string str = functionStr(returnType.dataType, fullName, parameters, isConst);
str = addStaticPrefix(addAbstractionPrefix(str, abstraction), isStatic);
str = addAccessPrefix(str, access); str = addAccessPrefix(str, access);
str = addLocationSuffix(str, location, scopeLocation); str = addLocationSuffix(str, location, scopeLocation);
methods.push_back(str); methods.push_back(str);
addTypeUse(returnType); addTypeUse(method.returnType);
for (const ParseTypeUsage& parameter : parameters) for (const ParseTypeUsage& parameter : method.parameters)
{ {
addTypeUse(parameter); addTypeUse(parameter);
} }
@@ -932,21 +985,27 @@ private:
} }
virtual void onCallParsed( virtual void onCallParsed(
const ParseLocation& location, const std::string& callerName, const std::string& calleeName) const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee)
{ {
calls.push_back(addLocationSuffix(callerName + " -> " + calleeName, location)); calls.push_back(addLocationSuffix(functionStr(caller) + " -> " + functionStr(callee), location));
}
virtual void onCallParsed(
const ParseLocation& location, const ParseVariable& caller, const ParseFunction& callee)
{
calls.push_back(addLocationSuffix(caller.fullName + " -> " + functionStr(callee), location));
} }
virtual void onFieldUsageParsed( virtual void onFieldUsageParsed(
const ParseLocation& location, const std::string& userName, const std::string& usedName) const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
{ {
usages.push_back(addLocationSuffix(userName + " -> " + usedName, location)); usages.push_back(addLocationSuffix(functionStr(user) + " -> " + usedName, location));
} }
virtual void onGlobalVariableUsageParsed( virtual void onGlobalVariableUsageParsed(
const ParseLocation& location, const std::string& userName, const std::string& usedName) const ParseLocation& location, const ParseFunction& user, const std::string& usedName)
{ {
usages.push_back(addLocationSuffix(userName + " -> " + usedName, location)); usages.push_back(addLocationSuffix(functionStr(user) + " -> " + usedName, location));
} }
std::vector<std::string> typedefs; std::vector<std::string> typedefs;
+11
View File
@@ -397,6 +397,17 @@ public:
TS_ASSERT_EQUALS(c2, c3); TS_ASSERT_EQUALS(c2, c3);
} }
void test_graph_saves_nodes_as_undefined_function_when_using_signatures()
{
TestGraph graph;
Node* a1 = graph.createNodeHierarchyWithDistinctSignature("A", "A1");
Node* a2 = graph.createNodeHierarchyWithDistinctSignature("A", "A2");
TS_ASSERT_DIFFERS(a1, a2);
TS_ASSERT_EQUALS(a1->getType(), Node::NODE_UNDEFINED_FUNCTION);
TS_ASSERT_EQUALS(a2->getType(), Node::NODE_UNDEFINED_FUNCTION);
}
void test_graph_creates_multiple_nodes_as_undefined_nodes() void test_graph_creates_multiple_nodes_as_undefined_nodes()
{ {
TestGraph graph; TestGraph graph;