data: Parsing functions with ParseFunction for signature comparing

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