From dc098606807b3dfba282b311bcf42bfcfdc5aa85 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Wed, 30 Jul 2014 13:32:38 +0200 Subject: [PATCH] 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. --- bin/test/data/log/test_log.txt | 2 +- src/lib/CMakeLists.txt | 2 + src/lib/data/Storage.cpp | 79 +++++---- src/lib/data/Storage.h | 26 ++- src/lib/data/graph/Graph.cpp | 4 +- src/lib/data/graph/Node.cpp | 8 +- src/lib/data/graph/Node.h | 1 + src/lib/data/parser/ParseFunction.cpp | 16 ++ src/lib/data/parser/ParseFunction.h | 25 +++ src/lib/data/parser/ParseLocation.h | 2 +- src/lib/data/parser/ParserClient.cpp | 27 +-- src/lib/data/parser/ParserClient.h | 31 ++-- src/lib/data/parser/cxx/ASTBodyVisitor.cpp | 34 +++- src/lib/data/parser/cxx/ASTBodyVisitor.h | 6 +- .../data/parser/cxx/ASTBodyVisitorClient.h | 10 +- src/lib/data/parser/cxx/ASTVisitor.cpp | 164 +++++++++++------- src/lib/data/parser/cxx/ASTVisitor.h | 21 ++- src/test/CxxParserTestSuite.h | 143 ++++++++++----- src/test/GraphTestSuite.h | 11 ++ 19 files changed, 397 insertions(+), 215 deletions(-) create mode 100644 src/lib/data/parser/ParseFunction.cpp create mode 100644 src/lib/data/parser/ParseFunction.h diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt index cd08873e..5db5f892 100644 --- a/bin/test/data/log/test_log.txt +++ b/bin/test/data/log/test_log.txt @@ -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 diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 73869549..5c0ac7ee 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -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 diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 2e4aa13e..79936524 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -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& 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& 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()); } - if (isStatic) + if (method.isStatic) { node->addComponentStatic(std::make_shared()); } @@ -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); diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 4caa445e..37814d43 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -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& 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& 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; diff --git a/src/lib/data/graph/Graph.cpp b/src/lib/data/graph/Graph.cpp index 835d2849..70127b21 100644 --- a/src/lib/data/graph/Graph.cpp +++ b/src/lib/data/graph/Graph.cpp @@ -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(); if (sigComponent && sigComponent->getSignature() == signature) { - if (type != Node::NODE_UNDEFINED) + if (type != Node::NODE_UNDEFINED && type != Node::NODE_UNDEFINED_FUNCTION) { node->setType(type); } diff --git a/src/lib/data/graph/Node.cpp b/src/lib/data/graph/Node.cpp index f81443cf..37370604 100644 --- a/src/lib/data/graph/Node.cpp +++ b/src/lib/data/graph/Node.cpp @@ -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 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: diff --git a/src/lib/data/graph/Node.h b/src/lib/data/graph/Node.h index 19af8ecd..b99225ca 100644 --- a/src/lib/data/graph/Node.h +++ b/src/lib/data/graph/Node.h @@ -19,6 +19,7 @@ public: enum NodeType { NODE_UNDEFINED, + NODE_UNDEFINED_FUNCTION, NODE_CLASS, NODE_STRUCT, NODE_GLOBAL_VARIABLE, diff --git a/src/lib/data/parser/ParseFunction.cpp b/src/lib/data/parser/ParseFunction.cpp new file mode 100644 index 00000000..0d4a8fc9 --- /dev/null +++ b/src/lib/data/parser/ParseFunction.cpp @@ -0,0 +1,16 @@ +#include "data/parser/ParseFunction.h" + +ParseFunction::ParseFunction( + const ParseTypeUsage& returnType, + const std::string& fullName, + const std::vector& parameters, + bool isStatic, + bool isConst +) + : returnType(returnType) + , fullName(fullName) + , parameters(parameters) + , isStatic(isStatic) + , isConst(isConst) +{ +} diff --git a/src/lib/data/parser/ParseFunction.h b/src/lib/data/parser/ParseFunction.h new file mode 100644 index 00000000..a51c6e07 --- /dev/null +++ b/src/lib/data/parser/ParseFunction.h @@ -0,0 +1,25 @@ +#ifndef PARSE_FUNCTION_H +#define PARSE_FUNCTION_H + +#include + +#include "data/parser/ParseTypeUsage.h" + +struct ParseFunction +{ + ParseFunction( + const ParseTypeUsage& returnType, + const std::string& fullName, + const std::vector& parameters, + bool isStatic = false, + bool isConst = false + ); + + const ParseTypeUsage returnType; + const std::string fullName; + const std::vector parameters; + const bool isStatic; + const bool isConst; +}; + +#endif // PARSE_FUNCTION_H diff --git a/src/lib/data/parser/ParseLocation.h b/src/lib/data/parser/ParseLocation.h index 9092c359..77951e84 100644 --- a/src/lib/data/parser/ParseLocation.h +++ b/src/lib/data/parser/ParseLocation.h @@ -16,7 +16,7 @@ struct ParseLocation bool isValid() const; - const std::string filePath; + std::string filePath; uint startLineNumber; uint startColumnNumber; uint endLineNumber; diff --git a/src/lib/data/parser/ParserClient.cpp b/src/lib/data/parser/ParserClient.cpp index 2a4a4513..699c801c 100644 --- a/src/lib/data/parser/ParserClient.cpp +++ b/src/lib/data/parser/ParserClient.cpp @@ -2,6 +2,7 @@ #include +#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 paramet return str + ")"; } -std::string ParserClient::functionStr( - const DataType& returnType, - const std::string& fullName, - const std::vector& 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& 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() diff --git a/src/lib/data/parser/ParserClient.h b/src/lib/data/parser/ParserClient.h index 01eebc7b..c90c3c16 100644 --- a/src/lib/data/parser/ParserClient.h +++ b/src/lib/data/parser/ParserClient.h @@ -4,6 +4,7 @@ #include #include +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 parameters); - static std::string functionStr( - const DataType& returnType, - const std::string& fullName, - const std::vector& parameters, - bool isConst - ); - static std::string functionSignatureStr( - const DataType& returnType, - const std::string& fullName, - const std::vector& 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& 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& 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 diff --git a/src/lib/data/parser/cxx/ASTBodyVisitor.cpp b/src/lib/data/parser/cxx/ASTBodyVisitor.cpp index 55fd9376..1230c318 100644 --- a/src/lib/data/parser/cxx/ASTBodyVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTBodyVisitor.cpp @@ -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::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::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); } diff --git a/src/lib/data/parser/cxx/ASTBodyVisitor.h b/src/lib/data/parser/cxx/ASTBodyVisitor.h index 59ec600d..4c09302f 100644 --- a/src/lib/data/parser/cxx/ASTBodyVisitor.h +++ b/src/lib/data/parser/cxx/ASTBodyVisitor.h @@ -7,7 +7,8 @@ class ASTBodyVisitor: public clang::StmtVisitor { 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 diff --git a/src/lib/data/parser/cxx/ASTBodyVisitorClient.h b/src/lib/data/parser/cxx/ASTBodyVisitorClient.h index 994508dc..9f0f48e9 100644 --- a/src/lib/data/parser/cxx/ASTBodyVisitorClient.h +++ b/src/lib/data/parser/cxx/ASTBodyVisitorClient.h @@ -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 diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 607f367e..a8e6ab65 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -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(declaration)) - { - clang::VarDecl* varDecl = static_cast(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::TypeLoc typeLoc; - return getParseTypeUsage(FTL.getReturnLoc(), declaration->getReturnType()); + const clang::TypeSourceInfo *TSI = declaration->getTypeSourceInfo(); + if (TSI) + { + const clang::FunctionTypeLoc FTL = TSI->getTypeLoc().IgnoreParens().getAs(); + typeLoc = FTL.getReturnLoc(); + } + + return getParseTypeUsage(typeLoc, declaration->getReturnType()); } std::vector ASTVisitor::getParameters(clang::FunctionDecl* declaration) const @@ -442,23 +469,42 @@ std::vector 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(declaration)) + { + clang::VarDecl* varDecl = clang::dyn_cast(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(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(declaration); + isStatic = methodDecl->isStatic(); + isConst = methodDecl->isConst(); } + else + { + isStatic = declaration->getStorageClass() == clang::SC_Static; + } + + return ParseFunction( + getParseTypeUsageOfReturnType(declaration), + declaration->getQualifiedNameAsString(), + getParameters(declaration), + isStatic, + isConst + ); } diff --git a/src/lib/data/parser/cxx/ASTVisitor.h b/src/lib/data/parser/cxx/ASTVisitor.h index 21a1e8ce..688fb145 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.h +++ b/src/lib/data/parser/cxx/ASTVisitor.h @@ -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 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 m_client; diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index a7b811b2..56a2e5e5 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -3,6 +3,7 @@ #include #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 client = parseCode( + "static int ceil(float a)\n" + "{\n" + " return static_cast(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 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 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 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& 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& 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 typedefs; diff --git a/src/test/GraphTestSuite.h b/src/test/GraphTestSuite.h index 657e168a..eb44855c 100644 --- a/src/test/GraphTestSuite.h +++ b/src/test/GraphTestSuite.h @@ -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;