data: Added type bitmasking to Node and Edge and check type on Edge creation

This commit is contained in:
Eberhard Graether
2014-07-31 15:07:18 +02:00
parent af9b75348c
commit b110d528dc
6 changed files with 153 additions and 33 deletions
+1
View File
@@ -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.
+86 -2
View File
@@ -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
View File
@@ -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;
+19 -9
View File
@@ -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
View File
@@ -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:
+17
View File
@@ -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");