Files
Sourcetrail/src/lib/data/graph/Node.cpp
T
mlangkabel 90e17c5868 src: converted NodeType to a class
NodeType internally still uses the Type enum
2017-11-23 17:05:15 +01:00

390 lines
6.6 KiB
C++

#include "data/graph/Node.h"
#include <sstream>
#include "utility/logging/logging.h"
#include "utility/utilityString.h"
#include "data/graph/token_component/TokenComponentAbstraction.h"
#include "data/graph/token_component/TokenComponentAccess.h"
#include "data/graph/token_component/TokenComponentConst.h"
#include "data/graph/token_component/TokenComponentStatic.h"
#include "data/graph/token_component/TokenComponentFilePath.h"
Node::Node(Id id, NodeType type, NameHierarchy nameHierarchy, bool defined)
: Token(id)
, m_type(type)
, m_nameHierarchy(nameHierarchy)
, m_defined(defined)
, m_implicit(false)
, m_explicit(false)
, m_childCount(0)
{
}
Node::Node(const Node& other)
: Token(other)
, m_type(other.m_type)
, m_nameHierarchy(other.m_nameHierarchy)
, m_defined(other.m_defined)
, m_implicit(other.m_implicit)
, m_explicit(other.m_explicit)
, m_childCount(other.m_childCount)
{
}
Node::~Node()
{
}
NodeType Node::getType() const
{
return m_type;
}
void Node::setType(NodeType type)
{
if (!isType(type.getType() | NodeType::NODE_NON_INDEXED))
{
LOG_WARNING(
"Cannot change NodeType after it was already set from " + getReadableTypeString() + " to " + type.getReadableTypeString()
);
return;
}
m_type = type;
}
bool Node::isType(NodeType::TypeMask mask) const
{
return (m_type.getType() & mask) > 0;
}
std::string Node::getName() const
{
return m_nameHierarchy.getRawName();
}
std::string Node::getFullName() const
{
return m_nameHierarchy.getQualifiedName();
}
NameHierarchy Node::getNameHierarchy() const
{
return m_nameHierarchy;
}
bool Node::isDefined() const
{
return m_defined;
}
void Node::setDefined(bool defined)
{
m_defined = defined;
}
bool Node::isImplicit() const
{
return m_implicit;
}
void Node::setImplicit(bool implicit)
{
m_implicit = implicit;
}
bool Node::isExplicit() const
{
return m_explicit;
}
void Node::setExplicit(bool bExplicit)
{
m_explicit = bExplicit;
}
size_t Node::getChildCount() const
{
return m_childCount;
}
void Node::setChildCount(size_t childCount)
{
m_childCount = childCount;
}
size_t Node::getEdgeCount() const
{
return m_edges.size();
}
void Node::addEdge(Edge* edge)
{
m_edges.emplace(edge->getId(), edge);
}
void Node::removeEdge(Edge* edge)
{
auto it = m_edges.find(edge->getId());
if (it != m_edges.end())
{
m_edges.erase(it);
}
}
Node* Node::getParentNode() const
{
Edge* edge = getMemberEdge();
if (edge)
{
return edge->getFrom();
}
return nullptr;
}
Node* Node::getLastParentNode()
{
Node* parent = getParentNode();
if (parent)
{
return parent->getLastParentNode();
}
return this;
}
Edge* Node::getMemberEdge() const
{
return findEdgeOfType(Edge::EDGE_MEMBER,
[this](Edge* e)
{
return e->getTo() == this;
}
);
}
Edge* Node::findEdge(std::function<bool(Edge*)> func) const
{
auto it = find_if(m_edges.begin(), m_edges.end(),
[func](std::pair<Id, Edge*> p)
{
return func(p.second);
}
);
if (it != m_edges.end())
{
return it->second;
}
return nullptr;
}
Edge* Node::findEdgeOfType(Edge::TypeMask mask) const
{
return findEdgeOfType(mask, [](Edge* e){ return true; });
}
Edge* Node::findEdgeOfType(Edge::TypeMask mask, std::function<bool(Edge*)> func) const
{
auto it = find_if(m_edges.begin(), m_edges.end(),
[mask, func](std::pair<Id, Edge*> p)
{
if (p.second->isType(mask))
{
return func(p.second);
}
return false;
}
);
if (it != m_edges.end())
{
return it->second;
}
return nullptr;
}
Node* Node::findChildNode(std::function<bool(Node*)> func) const
{
auto it = find_if(m_edges.begin(), m_edges.end(),
[&func](std::pair<Id, Edge*> p)
{
if (p.second->getType() == Edge::EDGE_MEMBER)
{
return func(p.second->getTo());
}
return false;
}
);
if (it != m_edges.end())
{
return it->second->getTo();
}
return nullptr;
}
void Node::forEachEdge(std::function<void(Edge*)> func) const
{
for_each(m_edges.begin(), m_edges.end(),
[func](std::pair<Id, Edge*> p)
{
func(p.second);
}
);
}
void Node::forEachEdgeOfType(Edge::TypeMask mask, std::function<void(Edge*)> func) const
{
for_each(m_edges.begin(), m_edges.end(),
[mask, func](std::pair<Id, Edge*> p)
{
if (p.second->isType(mask))
{
func(p.second);
}
}
);
}
void Node::forEachChildNode(std::function<void(Node*)> func) const
{
forEachEdgeOfType(Edge::EDGE_MEMBER,
[func, this](Edge* e)
{
if (this != e->getTo())
{
func(e->getTo());
}
}
);
}
void Node::forEachNodeRecursive(std::function<void(const Node*)> func) const
{
func(this);
forEachEdgeOfType(Edge::EDGE_MEMBER,
[func, this](Edge* e)
{
if (this != e->getTo())
{
e->getTo()->forEachNodeRecursive(func);
}
}
);
}
bool Node::isNode() const
{
return true;
}
bool Node::isEdge() const
{
return false;
}
void Node::addComponentAbstraction(std::shared_ptr<TokenComponentAbstraction> component)
{
if (getComponent<TokenComponentAbstraction>())
{
// LOG_ERROR("TokenComponentAbstraction has been set before!");
return;
}
else
{
addComponent(component);
}
}
void Node::addComponentConst(std::shared_ptr<TokenComponentConst> component)
{
if (getComponent<TokenComponentConst>())
{
// LOG_ERROR("TokenComponentConst has been set before!");
return;
}
else
{
addComponent(component);
}
}
void Node::addComponentStatic(std::shared_ptr<TokenComponentStatic> component)
{
if (getComponent<TokenComponentStatic>())
{
// LOG_ERROR("TokenComponentStatic has been set before!");
return;
}
else
{
addComponent(component);
}
}
void Node::addComponentFilePath(std::shared_ptr<TokenComponentFilePath> component)
{
if (getComponent<TokenComponentFilePath>())
{
// LOG_ERROR("TokenComponentFilePath has been set before!");
return;
}
else
{
addComponent(component);
}
}
void Node::addComponentAccess(std::shared_ptr<TokenComponentAccess> component)
{
if (getComponent<TokenComponentAccess>())
{
LOG_WARNING("TokenComponentAccess has been set before!");
return;
}
else
{
addComponent(component);
}
}
std::string Node::getReadableTypeString() const
{
return m_type.getReadableTypeString();
}
std::string Node::getAsString() const
{
std::stringstream str;
str << "[" << getId() << "] " << getReadableTypeString() << ": " << "\"" << getName() << "\"";
TokenComponentAccess* access = getComponent<TokenComponentAccess>();
if (access)
{
str << " " << access->getAccessString();
}
if (getComponent<TokenComponentStatic>())
{
str << " static";
}
if (getComponent<TokenComponentConst>())
{
str << " const";
}
return str.str();
}
std::ostream& operator<<(std::ostream& ostream, const Node& node)
{
ostream << node.getAsString();
return ostream;
}