data: Added type bitmasking to Node and Edge and check type on Edge creation
This commit is contained in:
@@ -3,6 +3,7 @@ Token.cpp ERROR: Location Id was not referenced by this Token.
|
||||
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.
|
||||
Edge.cpp ERROR: Edge call can't go from Node undefined to Node undefined
|
||||
Settings.cpp WARNING: File for Settings not found.
|
||||
ConfigManager.cpp ERROR: value Bool is not present in config.
|
||||
ConfigManager.cpp ERROR: value Int is not present in config.
|
||||
|
||||
@@ -14,6 +14,8 @@ Edge::Edge(EdgeType type, Node* from, Node* to)
|
||||
{
|
||||
m_from->addEdge(this);
|
||||
m_to->addEdge(this);
|
||||
|
||||
checkType();
|
||||
}
|
||||
|
||||
Edge::Edge(const Edge& other, Node* from, Node* to)
|
||||
@@ -30,6 +32,8 @@ Edge::Edge(const Edge& other, Node* from, Node* to)
|
||||
{
|
||||
LOG_ERROR("Nodes are not plain copies.");
|
||||
}
|
||||
|
||||
checkType();
|
||||
}
|
||||
|
||||
Edge::~Edge()
|
||||
@@ -43,6 +47,11 @@ Edge::EdgeType Edge::getType() const
|
||||
return m_type;
|
||||
}
|
||||
|
||||
bool Edge::isType(EdgeTypeMask mask) const
|
||||
{
|
||||
return (m_type & mask) > 0;
|
||||
}
|
||||
|
||||
Node* Edge::getFrom() const
|
||||
{
|
||||
return m_from;
|
||||
@@ -102,9 +111,9 @@ void Edge::addComponentDataType(std::shared_ptr<TokenComponentDataType> componen
|
||||
}
|
||||
}
|
||||
|
||||
std::string Edge::getTypeString() const
|
||||
std::string Edge::getTypeString(EdgeType type) const
|
||||
{
|
||||
switch (m_type)
|
||||
switch (type)
|
||||
{
|
||||
case EDGE_MEMBER:
|
||||
return "child";
|
||||
@@ -128,6 +137,11 @@ std::string Edge::getTypeString() const
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Edge::getTypeString() const
|
||||
{
|
||||
return getTypeString(m_type);
|
||||
}
|
||||
|
||||
std::string Edge::getAsString() const
|
||||
{
|
||||
std::stringstream str;
|
||||
@@ -147,3 +161,73 @@ std::ostream& operator<<(std::ostream& ostream, const Edge& edge)
|
||||
ostream << edge.getAsString();
|
||||
return ostream;
|
||||
}
|
||||
|
||||
bool Edge::checkType() const
|
||||
{
|
||||
Node::NodeTypeMask typeMask = Node::NODE_UNDEFINED | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM | Node::NODE_TYPEDEF;
|
||||
Node::NodeTypeMask variableMask = Node::NODE_UNDEFINED | Node::NODE_GLOBAL_VARIABLE | Node::NODE_FIELD;
|
||||
Node::NodeTypeMask functionMask = Node::NODE_UNDEFINED_FUNCTION | Node::NODE_FUNCTION | Node::NODE_METHOD;
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case EDGE_MEMBER:
|
||||
if (!m_from->isType(Node::NODE_UNDEFINED | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_NAMESPACE | Node::NODE_ENUM) ||
|
||||
(m_to->isType(Node::NODE_NAMESPACE) && !m_from->isType(Node::NODE_UNDEFINED | Node::NODE_NAMESPACE)) ||
|
||||
(m_from->isType(Node::NODE_ENUM) && !m_to->isType(Node::NODE_FIELD)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case EDGE_TYPE_OF:
|
||||
if (!m_from->isType(variableMask) || !m_to->isType(typeMask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case EDGE_RETURN_TYPE_OF:
|
||||
case EDGE_PARAMETER_TYPE_OF:
|
||||
case EDGE_TYPE_USAGE:
|
||||
if (!m_from->isType(functionMask) || !m_to->isType(typeMask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case EDGE_INHERITANCE:
|
||||
if (!m_from->isType(Node::NODE_CLASS) || !m_to->isType(Node::NODE_UNDEFINED | Node::NODE_CLASS))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case EDGE_CALL:
|
||||
if (!m_from->isType(variableMask | functionMask) || !m_to->isType(functionMask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case EDGE_USAGE:
|
||||
if (!m_from->isType(functionMask) || !m_to->isType(variableMask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case EDGE_TYPEDEF_OF:
|
||||
if (!m_from->isType(Node::NODE_TYPEDEF) || !m_to->isType(typeMask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_ERROR_STREAM(
|
||||
<< "Edge " << getTypeString()
|
||||
<< " can't go from Node " << m_from->getTypeString()
|
||||
<< " to Node " << m_to->getTypeString()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
+15
-10
@@ -13,17 +13,18 @@ class TokenComponentDataType;
|
||||
class Edge: public Token
|
||||
{
|
||||
public:
|
||||
enum EdgeType
|
||||
typedef int EdgeTypeMask;
|
||||
enum EdgeType : EdgeTypeMask
|
||||
{
|
||||
EDGE_MEMBER,
|
||||
EDGE_TYPE_OF,
|
||||
EDGE_RETURN_TYPE_OF,
|
||||
EDGE_PARAMETER_TYPE_OF,
|
||||
EDGE_TYPE_USAGE,
|
||||
EDGE_USAGE,
|
||||
EDGE_CALL,
|
||||
EDGE_INHERITANCE,
|
||||
EDGE_TYPEDEF_OF
|
||||
EDGE_MEMBER = 0x1,
|
||||
EDGE_TYPE_OF = 0x2,
|
||||
EDGE_RETURN_TYPE_OF = 0x4,
|
||||
EDGE_PARAMETER_TYPE_OF = 0x8,
|
||||
EDGE_TYPE_USAGE = 0x10,
|
||||
EDGE_USAGE = 0x20,
|
||||
EDGE_CALL = 0x40,
|
||||
EDGE_INHERITANCE = 0x80,
|
||||
EDGE_TYPEDEF_OF = 0x100
|
||||
};
|
||||
|
||||
Edge(EdgeType type, Node* from, Node* to);
|
||||
@@ -31,6 +32,7 @@ public:
|
||||
virtual ~Edge();
|
||||
|
||||
EdgeType getType() const;
|
||||
bool isType(EdgeTypeMask mask) const;
|
||||
|
||||
Node* getFrom() const;
|
||||
Node* getTo() const;
|
||||
@@ -46,12 +48,15 @@ public:
|
||||
void addComponentDataType(std::shared_ptr<TokenComponentDataType> component);
|
||||
|
||||
// Logging.
|
||||
std::string getTypeString(EdgeType type) const;
|
||||
std::string getTypeString() const;
|
||||
std::string getAsString() const;
|
||||
|
||||
private:
|
||||
void operator=(const Node&);
|
||||
|
||||
bool checkType() const;
|
||||
|
||||
const EdgeType m_type;
|
||||
|
||||
Node* const m_from;
|
||||
|
||||
@@ -31,16 +31,21 @@ Node::NodeType Node::getType() const
|
||||
|
||||
void Node::setType(NodeType type)
|
||||
{
|
||||
if (type != m_type && m_type != NODE_UNDEFINED && m_type != NODE_UNDEFINED_FUNCTION)
|
||||
if (!isType(type | NODE_UNDEFINED | NODE_UNDEFINED_FUNCTION))
|
||||
{
|
||||
LOG_WARNING(
|
||||
"Cannot change NodeType after it was already set from " + getTypeString(m_type) + " to " + getTypeString(type)
|
||||
"Cannot change NodeType after it was already set from " + getTypeString() + " to " + getTypeString(type)
|
||||
);
|
||||
return;
|
||||
}
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
bool Node::isType(NodeTypeMask mask) const
|
||||
{
|
||||
return (m_type & mask) > 0;
|
||||
}
|
||||
|
||||
const std::string& Node::getName() const
|
||||
{
|
||||
return m_name;
|
||||
@@ -197,9 +202,9 @@ void Node::addComponentConst(std::shared_ptr<TokenComponentConst> component)
|
||||
{
|
||||
LOG_ERROR("TokenComponentConst has been set before!");
|
||||
}
|
||||
else if (m_type != NODE_METHOD)
|
||||
else if (!isType(NODE_METHOD))
|
||||
{
|
||||
LOG_ERROR("TokenComponentConst can't be set on node of type: " + getTypeString(m_type));
|
||||
LOG_ERROR("TokenComponentConst can't be set on node of type: " + getTypeString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -213,9 +218,9 @@ void Node::addComponentStatic(std::shared_ptr<TokenComponentStatic> component)
|
||||
{
|
||||
LOG_ERROR("TokenComponentStatic has been set before!");
|
||||
}
|
||||
else if (m_type != NODE_GLOBAL_VARIABLE && m_type != NODE_FIELD && m_type != NODE_FUNCTION && m_type != NODE_METHOD)
|
||||
else if (!isType(NODE_GLOBAL_VARIABLE | NODE_FIELD | NODE_FUNCTION | NODE_METHOD))
|
||||
{
|
||||
LOG_ERROR("TokenComponentStatic can't be set on node of type: " + getTypeString(m_type));
|
||||
LOG_ERROR("TokenComponentStatic can't be set on node of type: " + getTypeString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -229,9 +234,9 @@ void Node::addComponentSignature(std::shared_ptr<TokenComponentSignature> compon
|
||||
{
|
||||
LOG_ERROR("TokenComponentSignature has been set before!");
|
||||
}
|
||||
else if (m_type != NODE_UNDEFINED_FUNCTION && m_type != NODE_FUNCTION && m_type != NODE_METHOD)
|
||||
else if (!isType(NODE_UNDEFINED_FUNCTION | NODE_FUNCTION | NODE_METHOD))
|
||||
{
|
||||
LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString(m_type));
|
||||
LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -269,10 +274,15 @@ std::string Node::getTypeString(NodeType type) const
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Node::getTypeString() const
|
||||
{
|
||||
return getTypeString(m_type);
|
||||
}
|
||||
|
||||
std::string Node::getAsString() const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "[" << getId() << "] " << getTypeString(m_type) << ": " << "\"" << getName() << "\"";
|
||||
str << "[" << getId() << "] " << getTypeString() << ": " << "\"" << getName() << "\"";
|
||||
|
||||
if (getComponent<TokenComponentStatic>())
|
||||
{
|
||||
|
||||
+15
-12
@@ -16,19 +16,20 @@ class TokenComponentSignature;
|
||||
class Node: public Token
|
||||
{
|
||||
public:
|
||||
enum NodeType
|
||||
typedef int NodeTypeMask;
|
||||
enum NodeType : NodeTypeMask
|
||||
{
|
||||
NODE_UNDEFINED,
|
||||
NODE_UNDEFINED_FUNCTION,
|
||||
NODE_CLASS,
|
||||
NODE_STRUCT,
|
||||
NODE_GLOBAL_VARIABLE,
|
||||
NODE_FIELD,
|
||||
NODE_FUNCTION,
|
||||
NODE_METHOD,
|
||||
NODE_NAMESPACE,
|
||||
NODE_ENUM,
|
||||
NODE_TYPEDEF
|
||||
NODE_UNDEFINED = 0x1,
|
||||
NODE_UNDEFINED_FUNCTION = 0x2,
|
||||
NODE_CLASS = 0x4,
|
||||
NODE_STRUCT = 0x8,
|
||||
NODE_GLOBAL_VARIABLE = 0x10,
|
||||
NODE_FIELD = 0x20,
|
||||
NODE_FUNCTION = 0x40,
|
||||
NODE_METHOD = 0x80,
|
||||
NODE_NAMESPACE = 0x100,
|
||||
NODE_ENUM = 0x200,
|
||||
NODE_TYPEDEF = 0x400
|
||||
};
|
||||
|
||||
Node(NodeType type, const std::string& name);
|
||||
@@ -37,6 +38,7 @@ public:
|
||||
|
||||
NodeType getType() const;
|
||||
void setType(NodeType type);
|
||||
bool isType(NodeTypeMask mask) const;
|
||||
|
||||
const std::string& getName() const;
|
||||
std::string getFullName() const;
|
||||
@@ -69,6 +71,7 @@ public:
|
||||
|
||||
// Logging.
|
||||
std::string getTypeString(NodeType type) const;
|
||||
std::string getTypeString() const;
|
||||
std::string getAsString() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -148,6 +148,13 @@ public:
|
||||
TS_ASSERT_EQUALS(n.getType(), n2.getType());
|
||||
}
|
||||
|
||||
void test_node_type_bit_masking()
|
||||
{
|
||||
Node n(Node::NODE_NAMESPACE, "A");
|
||||
TS_ASSERT(n.isType(Node::NODE_FUNCTION | Node::NODE_NAMESPACE | Node::NODE_CLASS));
|
||||
TS_ASSERT(!n.isType(Node::NODE_FUNCTION | Node::NODE_METHOD | Node::NODE_CLASS));
|
||||
}
|
||||
|
||||
void test_get_type_of_edges()
|
||||
{
|
||||
Node a(Node::NODE_UNDEFINED, "A");
|
||||
@@ -169,6 +176,16 @@ public:
|
||||
TS_ASSERT_EQUALS(e.getType(), e2.getType());
|
||||
}
|
||||
|
||||
void test_edge_type_bit_masking()
|
||||
{
|
||||
Node a(Node::NODE_UNDEFINED, "A");
|
||||
Node b(Node::NODE_UNDEFINED, "B");
|
||||
Edge e(Edge::EDGE_TYPE_OF, &a, &b);
|
||||
|
||||
TS_ASSERT(e.isType(Edge::EDGE_MEMBER | Edge::EDGE_CALL | Edge::EDGE_TYPE_OF));
|
||||
TS_ASSERT(!e.isType(Edge::EDGE_USAGE | Edge::EDGE_MEMBER | Edge::EDGE_CALL));
|
||||
}
|
||||
|
||||
void test_node_finds_child_node()
|
||||
{
|
||||
Node a(Node::NODE_UNDEFINED, "A");
|
||||
|
||||
Reference in New Issue
Block a user