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:
@@ -1,6 +1,6 @@
|
||||
ConfigManager.cpp ERROR: value path/to/nowhere is not present in config.
|
||||
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.
|
||||
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
|
||||
|
||||
@@ -102,6 +102,8 @@ add_files(
|
||||
data/location/TokenLocationLine.cpp
|
||||
data/location/TokenLocationLine.h
|
||||
|
||||
data/parser/ParseFunction.cpp
|
||||
data/parser/ParseFunction.h
|
||||
data/parser/ParseLocation.cpp
|
||||
data/parser/ParseLocation.h
|
||||
data/parser/Parser.cpp
|
||||
|
||||
+46
-33
@@ -6,6 +6,7 @@
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
@@ -109,45 +110,40 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable&
|
||||
}
|
||||
|
||||
void Storage::onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation
|
||||
)
|
||||
{
|
||||
log("function", fullName, location);
|
||||
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation
|
||||
){
|
||||
log("function", function.fullName, location);
|
||||
|
||||
Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
|
||||
Node::NODE_FUNCTION, fullName,
|
||||
ParserClient::functionSignatureStr(returnType.dataType, fullName, parameters, false)
|
||||
Node::NODE_FUNCTION, function.fullName, ParserClient::functionSignatureStr(function)
|
||||
);
|
||||
|
||||
addTokenLocation(node, location);
|
||||
addTokenLocation(node, scopeLocation, true);
|
||||
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType);
|
||||
for (const ParseTypeUsage& parameter : parameters)
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, function.returnType);
|
||||
for (const ParseTypeUsage& parameter : function.parameters)
|
||||
{
|
||||
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic, const ParseLocation& scopeLocation
|
||||
)
|
||||
{
|
||||
log("method", fullName, location);
|
||||
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
|
||||
const ParseLocation& scopeLocation
|
||||
){
|
||||
log("method", method.fullName, location);
|
||||
|
||||
Node* node = m_graph.createNodeHierarchyWithDistinctSignature(
|
||||
Node::NODE_METHOD, fullName,
|
||||
ParserClient::functionSignatureStr(returnType.dataType, fullName, parameters, isConst)
|
||||
Node::NODE_METHOD, method.fullName, ParserClient::functionSignatureStr(method)
|
||||
);
|
||||
|
||||
if (isConst)
|
||||
if (method.isConst)
|
||||
{
|
||||
node->addComponentConst(std::make_shared<TokenComponentConst>());
|
||||
}
|
||||
|
||||
if (isStatic)
|
||||
if (method.isStatic)
|
||||
{
|
||||
node->addComponentStatic(std::make_shared<TokenComponentStatic>());
|
||||
}
|
||||
@@ -162,8 +158,8 @@ void Storage::onMethodParsed(
|
||||
addTokenLocation(node, location);
|
||||
addTokenLocation(node, scopeLocation, true);
|
||||
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, returnType);
|
||||
for (const ParseTypeUsage& parameter : parameters)
|
||||
addTypeEdge(node, Edge::EDGE_RETURN_TYPE_OF, method.returnType);
|
||||
for (const ParseTypeUsage& parameter : method.parameters)
|
||||
{
|
||||
addTypeEdge(node, Edge::EDGE_PARAMETER_TYPE_OF, parameter);
|
||||
}
|
||||
@@ -212,23 +208,40 @@ void Storage::onInheritanceParsed(
|
||||
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* calleeNode = m_graph.createNodeHierarchy(calleeName);
|
||||
Node* callerNode =
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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(
|
||||
const ParseLocation& location, const std::string& userName, const std::string& usedName
|
||||
)
|
||||
{
|
||||
log("usage", userName + " -> " + usedName, location);
|
||||
const ParseLocation& location, const ParseFunction& user, const std::string& usedName
|
||||
){
|
||||
log("usage", user.fullName + " -> " + usedName, location);
|
||||
|
||||
Node* userNode = m_graph.createNodeHierarchy(userName);
|
||||
Node* userNode =
|
||||
m_graph.createNodeHierarchyWithDistinctSignature(user.fullName, ParserClient::functionSignatureStr(user));;
|
||||
Node* usedNode = m_graph.createNodeHierarchy(usedName);
|
||||
|
||||
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
|
||||
|
||||
+10
-16
@@ -28,8 +28,7 @@ public:
|
||||
// ParserClient implementation
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& underlyingType,
|
||||
AccessType access
|
||||
);
|
||||
AccessType access);
|
||||
virtual void onClassParsed(
|
||||
const ParseLocation& location, const std::string& fullName, AccessType access, const ParseLocation& scopeLocation);
|
||||
virtual void onStructParsed(
|
||||
@@ -39,14 +38,10 @@ public:
|
||||
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access);
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation
|
||||
);
|
||||
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation);
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic, const ParseLocation& scopeLocation
|
||||
);
|
||||
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
|
||||
const ParseLocation& scopeLocation);
|
||||
|
||||
virtual void onNamespaceParsed(
|
||||
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 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(
|
||||
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(
|
||||
const ParseLocation& location, const std::string& userName, const std::string& usedName
|
||||
);
|
||||
const ParseLocation& location, const ParseFunction& user, const std::string& usedName);
|
||||
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
|
||||
virtual Id getIdForNodeWithName(const std::string& fullName) const;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
return createNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED, fullName, signature);
|
||||
return createNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, fullName, signature);
|
||||
}
|
||||
|
||||
Node* Graph::createNodeHierarchyWithDistinctSignature(
|
||||
@@ -103,7 +103,7 @@ Node* Graph::createNodeHierarchyWithDistinctSignature(
|
||||
TokenComponentSignature* sigComponent = node->getComponent<TokenComponentSignature>();
|
||||
if (sigComponent && sigComponent->getSignature() == signature)
|
||||
{
|
||||
if (type != Node::NODE_UNDEFINED)
|
||||
if (type != Node::NODE_UNDEFINED && type != Node::NODE_UNDEFINED_FUNCTION)
|
||||
{
|
||||
node->setType(type);
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@ Node::NodeType Node::getType() const
|
||||
|
||||
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(
|
||||
"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;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ void Node::addComponentSignature(std::shared_ptr<TokenComponentSignature> compon
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -245,6 +245,8 @@ std::string Node::getTypeString(NodeType type) const
|
||||
{
|
||||
case NODE_UNDEFINED:
|
||||
return "undefined";
|
||||
case NODE_UNDEFINED_FUNCTION:
|
||||
return "undefined function";
|
||||
case NODE_CLASS:
|
||||
return "class";
|
||||
case NODE_STRUCT:
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
enum NodeType
|
||||
{
|
||||
NODE_UNDEFINED,
|
||||
NODE_UNDEFINED_FUNCTION,
|
||||
NODE_CLASS,
|
||||
NODE_STRUCT,
|
||||
NODE_GLOBAL_VARIABLE,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
@@ -16,7 +16,7 @@ struct ParseLocation
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
const std::string filePath;
|
||||
std::string filePath;
|
||||
uint startLineNumber;
|
||||
uint startColumnNumber;
|
||||
uint endLineNumber;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
@@ -103,26 +104,16 @@ std::string ParserClient::parameterStr(const std::vector<ParseTypeUsage> paramet
|
||||
return str + ")";
|
||||
}
|
||||
|
||||
std::string ParserClient::functionStr(
|
||||
const DataType& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isConst
|
||||
){
|
||||
return addConstPrefix(
|
||||
returnType.getFullTypeName() + " " + fullName + parameterStr(parameters),
|
||||
isConst,
|
||||
false
|
||||
);
|
||||
std::string ParserClient::functionStr(const ParseFunction& function)
|
||||
{
|
||||
std::string str =
|
||||
function.returnType.dataType.getFullTypeName() + " " + function.fullName + parameterStr(function.parameters);
|
||||
return addConstPrefix(addStaticPrefix(str, function.isStatic), function.isConst, false);
|
||||
}
|
||||
|
||||
std::string ParserClient::functionSignatureStr(
|
||||
const DataType& returnType,
|
||||
const std::string& fullName,
|
||||
const std::vector<ParseTypeUsage>& parameters,
|
||||
bool isConst
|
||||
){
|
||||
return addConstPrefix(fullName + parameterStr(parameters), isConst, false);
|
||||
std::string ParserClient::functionSignatureStr(const ParseFunction& function)
|
||||
{
|
||||
return addConstPrefix(function.fullName + parameterStr(function.parameters), function.isConst, false);
|
||||
}
|
||||
|
||||
ParserClient::ParserClient()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct ParseFunction;
|
||||
struct ParseLocation;
|
||||
struct ParseTypeUsage;
|
||||
struct ParseVariable;
|
||||
@@ -35,18 +36,8 @@ public:
|
||||
|
||||
static std::string variableStr(const ParseVariable& variable);
|
||||
static std::string parameterStr(const std::vector<ParseTypeUsage> parameters);
|
||||
static std::string functionStr(
|
||||
const DataType& returnType,
|
||||
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
|
||||
);
|
||||
static std::string functionStr(const ParseFunction& function);
|
||||
static std::string functionSignatureStr(const ParseFunction& function);
|
||||
|
||||
ParserClient();
|
||||
virtual ~ParserClient();
|
||||
@@ -65,12 +56,10 @@ public:
|
||||
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0;
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation) = 0;
|
||||
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation) = 0;
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic, const ParseLocation& scopeLocation) = 0;
|
||||
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
|
||||
const ParseLocation& scopeLocation) = 0;
|
||||
|
||||
virtual void onNamespaceParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseLocation& scopeLocation) = 0;
|
||||
@@ -83,11 +72,13 @@ public:
|
||||
virtual void onInheritanceParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& baseName, AccessType access) = 0;
|
||||
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(
|
||||
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(
|
||||
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
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
|
||||
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl)
|
||||
ASTBodyVisitor::ASTBodyVisitor(ASTBodyVisitorClient* client, clang::FunctionDecl* functionDecl)
|
||||
: 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)
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_parentDecl, expr);
|
||||
if (m_functionDecl)
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_client->VisitCallExprInDeclBody(m_varDecl, expr);
|
||||
}
|
||||
|
||||
VisitStmt(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);
|
||||
}
|
||||
@@ -44,7 +66,7 @@ void ASTBodyVisitor::VisitMemberExpr(clang::make_ptr<clang::MemberExpr>::type ex
|
||||
{
|
||||
if (expr->getMemberDecl()->getKind() == clang::Decl::Kind::Field)
|
||||
{
|
||||
m_client->VisitFieldUsageExprInDeclBody(m_parentDecl, expr);
|
||||
m_client->VisitFieldUsageExprInDeclBody(m_functionDecl, 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())
|
||||
{
|
||||
m_client->VisitGlobalVariableUsageExprInDeclBody(m_parentDecl, expr);
|
||||
m_client->VisitGlobalVariableUsageExprInDeclBody(m_functionDecl, expr);
|
||||
}
|
||||
VisitStmt(expr);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
class ASTBodyVisitor: public clang::StmtVisitor<ASTBodyVisitor>
|
||||
{
|
||||
public:
|
||||
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::NamedDecl* parentDecl);
|
||||
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::FunctionDecl* functionDecl);
|
||||
ASTBodyVisitor(ASTBodyVisitorClient* client, clang::VarDecl* varDecl);
|
||||
virtual ~ASTBodyVisitor();
|
||||
|
||||
void VisitStmt(clang::Stmt* stmt);
|
||||
@@ -19,7 +20,8 @@ public:
|
||||
|
||||
private:
|
||||
ASTBodyVisitorClient* m_client;
|
||||
clang::NamedDecl* m_parentDecl;
|
||||
clang::FunctionDecl* m_functionDecl;
|
||||
clang::VarDecl* m_varDecl;
|
||||
};
|
||||
|
||||
#endif // AST_BODY_VISITOR
|
||||
|
||||
@@ -11,10 +11,12 @@ public:
|
||||
ASTBodyVisitorClient();
|
||||
virtual ~ASTBodyVisitorClient();
|
||||
|
||||
virtual void VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr) = 0;
|
||||
virtual void VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr) = 0;
|
||||
virtual void VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr) = 0;
|
||||
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr) = 0;
|
||||
virtual void VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr) = 0;
|
||||
virtual void VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr) = 0;
|
||||
virtual void VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* 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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseTypeUsage.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
@@ -141,9 +142,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
{
|
||||
m_client->onFunctionParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParseTypeUsageOfReturnType(declaration),
|
||||
getParameters(declaration),
|
||||
getParseFunction(declaration),
|
||||
getParseLocationOfFunctionBody(declaration)
|
||||
);
|
||||
|
||||
@@ -173,13 +172,9 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
|
||||
m_client->onMethodParsed(
|
||||
getParseLocationForNamedDecl(declaration),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParseTypeUsageOfReturnType(declaration),
|
||||
getParameters(declaration),
|
||||
getParseFunction(declaration),
|
||||
convertAccessType(declaration->getAccess()),
|
||||
abstraction,
|
||||
declaration->isConst(),
|
||||
declaration->isStatic(),
|
||||
getParseLocationOfFunctionBody(declaration)
|
||||
);
|
||||
|
||||
@@ -206,9 +201,8 @@ bool ASTVisitor::VisitCXXConstructorDecl(clang::CXXConstructorDecl* declaration)
|
||||
if (init->isMemberInitializer())
|
||||
{
|
||||
m_client->onFieldUsageParsed(
|
||||
// getParseLocation(init->getSourceRange()),
|
||||
getParseLocationForNamedDecl(init->getMember(), init->getMemberLocation()),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParseFunction(declaration),
|
||||
init->getMember()->getQualifiedNameAsString()
|
||||
);
|
||||
}
|
||||
@@ -264,7 +258,7 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration)
|
||||
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())
|
||||
// {
|
||||
@@ -282,21 +276,39 @@ void ASTVisitor::VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr
|
||||
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
decl->getQualifiedNameAsString(),
|
||||
expr->getDirectCallee()->getQualifiedNameAsString()
|
||||
getParseFunction(decl),
|
||||
getParseFunction(expr->getDirectCallee())
|
||||
);
|
||||
}
|
||||
|
||||
void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr)
|
||||
void ASTVisitor::VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr)
|
||||
{
|
||||
m_client->onCallParsed(
|
||||
getParseLocation(expr->getSourceRange()),
|
||||
decl->getQualifiedNameAsString(),
|
||||
expr->getConstructor()->getQualifiedNameAsString()
|
||||
getParseVariable(decl),
|
||||
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());
|
||||
|
||||
@@ -305,12 +317,12 @@ void ASTVisitor::VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::Me
|
||||
|
||||
m_client->onFieldUsageParsed(
|
||||
parseLocation,
|
||||
decl->getQualifiedNameAsString(),
|
||||
getParseFunction(decl),
|
||||
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());
|
||||
|
||||
@@ -319,7 +331,7 @@ void ASTVisitor::VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl,
|
||||
|
||||
m_client->onGlobalVariableUsageParsed(
|
||||
parseLocation,
|
||||
decl->getQualifiedNameAsString(),
|
||||
getParseFunction(decl),
|
||||
expr->getDecl()->getQualifiedNameAsString()
|
||||
);
|
||||
}
|
||||
@@ -330,6 +342,27 @@ bool ASTVisitor::hasValidLocation(const clang::Decl* declaration) const
|
||||
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
|
||||
{
|
||||
if (sourceRange.isInvalid())
|
||||
@@ -389,33 +422,21 @@ ParseLocation ASTVisitor::getParseLocationOfRecordBody(clang::CXXRecordDecl* dec
|
||||
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
|
||||
{
|
||||
while (typeLoc.getNextTypeLoc())
|
||||
{
|
||||
typeLoc = typeLoc.getNextTypeLoc();
|
||||
}
|
||||
|
||||
ParseLocation parseLocation = getParseLocation(typeLoc.getSourceRange());
|
||||
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);
|
||||
}
|
||||
@@ -423,10 +444,16 @@ ParseTypeUsage ASTVisitor::getParseTypeUsage(clang::TypeLoc typeLoc, const clang
|
||||
ParseTypeUsage ASTVisitor::getParseTypeUsageOfReturnType(clang::FunctionDecl* declaration) const
|
||||
{
|
||||
// TODO: use FunctionDecl::getReturnTypeSourceRange() in newer clang version
|
||||
const clang::TypeSourceInfo *TSI = declaration->getTypeSourceInfo();
|
||||
const clang::FunctionTypeLoc FTL = TSI->getTypeLoc().IgnoreParens().getAs<clang::FunctionTypeLoc>();
|
||||
clang::TypeLoc typeLoc;
|
||||
|
||||
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
|
||||
@@ -442,23 +469,42 @@ std::vector<ParseTypeUsage> ASTVisitor::getParameters(clang::FunctionDecl* decla
|
||||
return parameters;
|
||||
}
|
||||
|
||||
std::string ASTVisitor::getTypeName(const clang::QualType& qualType) const
|
||||
ParseVariable ASTVisitor::getParseVariable(clang::DeclaratorDecl* declaration) const
|
||||
{
|
||||
DataType dataType = utility::qualTypeToDataType(qualType);
|
||||
return dataType.getRawTypeName();
|
||||
bool isStatic = false;
|
||||
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:
|
||||
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;
|
||||
clang::CXXMethodDecl* methodDecl = clang::dyn_cast<clang::CXXMethodDecl>(declaration);
|
||||
isStatic = methodDecl->isStatic();
|
||||
isConst = methodDecl->isConst();
|
||||
}
|
||||
else
|
||||
{
|
||||
isStatic = declaration->getStorageClass() == clang::SC_Static;
|
||||
}
|
||||
|
||||
return ParseFunction(
|
||||
getParseTypeUsageOfReturnType(declaration),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getParameters(declaration),
|
||||
isStatic,
|
||||
isConst
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,25 +39,30 @@ public:
|
||||
virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* declaration); // enum fields
|
||||
|
||||
// ASTBodyVisitorClient implementation
|
||||
virtual void VisitCallExprInDeclBody(clang::NamedDecl* decl, clang::CallExpr* expr); // calls
|
||||
virtual void VisitCXXConstructExprInDeclBody(clang::NamedDecl* decl, clang::CXXConstructExpr* expr); // constructor calls
|
||||
virtual void VisitFieldUsageExprInDeclBody(clang::NamedDecl* decl, clang::MemberExpr* expr); // field usages
|
||||
virtual void VisitGlobalVariableUsageExprInDeclBody(clang::NamedDecl* decl, clang::DeclRefExpr* expr); // global variable usage
|
||||
virtual void VisitCallExprInDeclBody(clang::FunctionDecl* decl, clang::CallExpr* expr); // calls
|
||||
virtual void VisitCallExprInDeclBody(clang::VarDecl* decl, clang::CallExpr* expr); // calls in initialization of global variables
|
||||
virtual void VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clang::CXXConstructExpr* expr); // constructor calls
|
||||
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:
|
||||
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 getParseLocationForNamedDecl(clang::NamedDecl* decl, const clang::SourceLocation& loc) const;
|
||||
ParseLocation getParseLocationForNamedDecl(clang::NamedDecl* decl) const;
|
||||
ParseLocation getParseLocationOfFunctionBody(clang::FunctionDecl* 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 getParseTypeUsageOfReturnType(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;
|
||||
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
|
||||
|
||||
ParseVariable getParseVariable(clang::DeclaratorDecl* declaration) const;
|
||||
ParseFunction getParseFunction(clang::FunctionDecl* declaration) const;
|
||||
|
||||
clang::ASTContext* m_context;
|
||||
std::shared_ptr<ParserClient> m_client;
|
||||
|
||||
+101
-42
@@ -3,6 +3,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "data/parser/cxx/CxxParser.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParserClient.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>");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
@@ -497,7 +511,50 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -514,8 +571,8 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->calls.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->calls[0], "main -> sum <7:9 7:25>");
|
||||
TS_ASSERT_EQUALS(client->calls[1], "main -> sum <7:16 7:24>");
|
||||
TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <7:9 7:25>");
|
||||
TS_ASSERT_EQUALS(client->calls[1], "int main() -> int sum(int, int) <7:16 7:24>");
|
||||
}
|
||||
|
||||
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[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()
|
||||
@@ -553,7 +610,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -569,7 +626,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -587,7 +644,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -608,7 +665,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -630,8 +687,8 @@ public:
|
||||
);
|
||||
|
||||
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[1], "App::App -> one <10:10 10:14>");
|
||||
TS_ASSERT_EQUALS(client->calls[0], "void App::App() -> void Item::Item(int) <10:5 10:15>");
|
||||
TS_ASSERT_EQUALS(client->calls[1], "void App::App() -> int one() <10:10 10:14>");
|
||||
}
|
||||
|
||||
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[0], "main -> App::App <9:6 9:6>");
|
||||
TS_ASSERT_EQUALS(client->calls[1], "main -> App::App <10:6 10:14>");
|
||||
TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <9:6 9:6>");
|
||||
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()
|
||||
@@ -667,7 +724,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -678,7 +735,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -699,8 +756,8 @@ public:
|
||||
);
|
||||
|
||||
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[1], "main -> App::operator+ <11:2 11:8>");
|
||||
TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <10:6 10:6>");
|
||||
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()
|
||||
@@ -715,7 +772,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -733,7 +790,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -751,8 +808,8 @@ public:
|
||||
);
|
||||
|
||||
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[1], "App::foo -> App::bar <6:3 6:11>");
|
||||
TS_ASSERT_EQUALS(client->usages[0], "void App::foo() -> App::bar <5:3 5:5>");
|
||||
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()
|
||||
@@ -768,7 +825,7 @@ public:
|
||||
);
|
||||
|
||||
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()
|
||||
@@ -874,33 +931,29 @@ private:
|
||||
}
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, const ParseLocation& scopeLocation
|
||||
const ParseLocation& location, const ParseFunction& function, const ParseLocation& scopeLocation
|
||||
){
|
||||
std::string str = functionStr(returnType.dataType, fullName, parameters, false);
|
||||
functions.push_back(addLocationSuffix(str, location, scopeLocation));
|
||||
functions.push_back(addLocationSuffix(functionStr(function), location, scopeLocation));
|
||||
|
||||
addTypeUse(returnType);
|
||||
for (const ParseTypeUsage& parameter : parameters)
|
||||
addTypeUse(function.returnType);
|
||||
for (const ParseTypeUsage& parameter : function.parameters)
|
||||
{
|
||||
addTypeUse(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const ParseTypeUsage& returnType,
|
||||
const std::vector<ParseTypeUsage>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic, const ParseLocation& scopeLocation
|
||||
)
|
||||
{
|
||||
std::string str = functionStr(returnType.dataType, fullName, parameters, isConst);
|
||||
str = addStaticPrefix(addAbstractionPrefix(str, abstraction), isStatic);
|
||||
const ParseLocation& location, const ParseFunction& method, AccessType access, AbstractionType abstraction,
|
||||
const ParseLocation& scopeLocation
|
||||
){
|
||||
std::string str = functionStr(method);
|
||||
str = addAbstractionPrefix(str, abstraction);
|
||||
str = addAccessPrefix(str, access);
|
||||
str = addLocationSuffix(str, location, scopeLocation);
|
||||
methods.push_back(str);
|
||||
|
||||
addTypeUse(returnType);
|
||||
for (const ParseTypeUsage& parameter : parameters)
|
||||
addTypeUse(method.returnType);
|
||||
for (const ParseTypeUsage& parameter : method.parameters)
|
||||
{
|
||||
addTypeUse(parameter);
|
||||
}
|
||||
@@ -932,21 +985,27 @@ private:
|
||||
}
|
||||
|
||||
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(
|
||||
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(
|
||||
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;
|
||||
|
||||
@@ -397,6 +397,17 @@ public:
|
||||
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()
|
||||
{
|
||||
TestGraph graph;
|
||||
|
||||
Reference in New Issue
Block a user