* switched SearchIndex and HierarchyCache to std::unique_ptr * use move semantics and in-place initialization in StorageTypes and SearchIndex * improved autocompletion speed by fixing contained node type checking
317 lines
5.3 KiB
C++
317 lines
5.3 KiB
C++
#include "data/graph/Node.h"
|
|
|
|
#include <sstream>
|
|
|
|
#include "utility/logging/logging.h"
|
|
#include "utility/utilityString.h"
|
|
|
|
#include "data/graph/token_component/TokenComponentAccess.h"
|
|
#include "data/graph/token_component/TokenComponentConst.h"
|
|
#include "data/graph/token_component/TokenComponentStatic.h"
|
|
|
|
Node::Node(Id id, NodeType type, NameHierarchy nameHierarchy, DefinitionKind definitionKind)
|
|
: Token(id)
|
|
, m_type(type)
|
|
, m_nameHierarchy(std::move(nameHierarchy))
|
|
, m_definitionKind(definitionKind)
|
|
, m_childCount(0)
|
|
{
|
|
}
|
|
|
|
Node::Node(const Node& other)
|
|
: Token(other)
|
|
, m_type(other.m_type)
|
|
, m_nameHierarchy(other.m_nameHierarchy)
|
|
, m_definitionKind(other.m_definitionKind)
|
|
, 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_SYMBOL))
|
|
{
|
|
LOG_WARNING(
|
|
L"Cannot change NodeType after it was already set from " + getReadableTypeString() +
|
|
L" to " + type.getReadableTypeWString()
|
|
);
|
|
return;
|
|
}
|
|
m_type = type;
|
|
}
|
|
|
|
bool Node::isType(NodeType::TypeMask mask) const
|
|
{
|
|
return (m_type.getType() & mask) > 0;
|
|
}
|
|
|
|
std::wstring Node::getName() const
|
|
{
|
|
return m_nameHierarchy.getRawName();
|
|
}
|
|
|
|
std::wstring Node::getFullName() const
|
|
{
|
|
return m_nameHierarchy.getQualifiedName();
|
|
}
|
|
|
|
const NameHierarchy& Node::getNameHierarchy() const
|
|
{
|
|
return m_nameHierarchy;
|
|
}
|
|
|
|
bool Node::isDefined() const
|
|
{
|
|
return m_definitionKind != DEFINITION_NONE;
|
|
}
|
|
|
|
bool Node::isImplicit() const
|
|
{
|
|
return m_definitionKind == DEFINITION_IMPLICIT;
|
|
}
|
|
|
|
bool Node::isExplicit() const
|
|
{
|
|
return m_definitionKind == DEFINITION_EXPLICIT;
|
|
}
|
|
|
|
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;
|
|
}
|
|
);
|
|
}
|
|
|
|
bool Node::isParentOf(const Node* node) const
|
|
{
|
|
while ((node = node->getParentNode()))
|
|
{
|
|
if (node == this)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
std::wstring Node::getReadableTypeString() const
|
|
{
|
|
return m_type.getReadableTypeWString();
|
|
}
|
|
|
|
std::wstring Node::getAsString() const
|
|
{
|
|
std::wstringstream str;
|
|
str << L"[" << getId() << L"] " << getReadableTypeString() << L": " << L"\"" << getName() << L"\"";
|
|
|
|
TokenComponentAccess* access = getComponent<TokenComponentAccess>();
|
|
if (access)
|
|
{
|
|
str << L" " << access->getAccessString();
|
|
}
|
|
|
|
if (getComponent<TokenComponentStatic>())
|
|
{
|
|
str << L" static";
|
|
}
|
|
|
|
if (getComponent<TokenComponentConst>())
|
|
{
|
|
str << L" const";
|
|
}
|
|
|
|
return str.str();
|
|
}
|
|
|
|
std::wostream& operator<<(std::wostream& ostream, const Node& node)
|
|
{
|
|
ostream << node.getAsString();
|
|
return ostream;
|
|
}
|