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;