data: storing type modifiers in edges
- ASTVisitor uses DataType instead of string to pass on type information. - Edges can have EdgeComponents. - EdgeComponentDataType stores information that modifies the type a ...TYPE_OF edge points to. - EdgeComponentDataType can create a complete DataType using it's internal information. - Fixed a bug where DataTypeModifiers did not apply their qualifiers.
This commit is contained in:
@@ -15,6 +15,8 @@ add_files(
|
||||
data/parser/cxx/ASTVisitor.h
|
||||
data/parser/cxx/CxxParser.cpp
|
||||
data/parser/cxx/CxxParser.h
|
||||
data/parser/cxx/utilityCxx.cpp
|
||||
data/parser/cxx/utilityCxx.h
|
||||
)
|
||||
|
||||
add_files(
|
||||
@@ -63,6 +65,11 @@ add_files(
|
||||
data/access/GraphAccessProxy.cpp
|
||||
data/access/GraphAccessProxy.h
|
||||
|
||||
data/graph/edgeComponent/EdgeComponent.cpp
|
||||
data/graph/edgeComponent/EdgeComponent.h
|
||||
data/graph/edgeComponent/EdgeComponentDataType.cpp
|
||||
data/graph/edgeComponent/EdgeComponentDataType.h
|
||||
|
||||
data/graph/Edge.cpp
|
||||
data/graph/Edge.h
|
||||
data/graph/Graph.cpp
|
||||
@@ -153,8 +160,6 @@ add_files(
|
||||
utility/FileSystem.h
|
||||
utility/Property.h
|
||||
utility/types.h
|
||||
utility/utilityClang.cpp
|
||||
utility/utilityClang.h
|
||||
utility/utilityString.cpp
|
||||
utility/utilityString.h
|
||||
utility/Vector.h
|
||||
|
||||
+37
-15
@@ -2,11 +2,13 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "data/graph/edgeComponent/EdgeComponentDataType.h"
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
#include "data/type/DataType.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
@@ -40,11 +42,11 @@ void Storage::logLocations() const
|
||||
|
||||
|
||||
void Storage::onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& underlyingType,
|
||||
AccessType access
|
||||
)
|
||||
{
|
||||
log("typedef", fullName + " -> " + underlyingFullName, location);
|
||||
log("typedef", fullName + " -> " + underlyingType.getFullTypeName(), location);
|
||||
}
|
||||
|
||||
void Storage::onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access)
|
||||
@@ -75,10 +77,14 @@ void Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseV
|
||||
|
||||
Node* node = m_graph.createNodeHierarchy(variable.fullName);
|
||||
node->setType(Node::NODE_GLOBAL_VARIABLE);
|
||||
node->setConst(variable.isConst);
|
||||
node->setStatic(variable.isStatic);
|
||||
|
||||
m_graph.createEdge(Edge::EDGE_TYPE_OF, node, m_graph.createNodeHierarchy(variable.typeName));
|
||||
Edge* edge = m_graph.createEdge(Edge::EDGE_TYPE_OF, node, m_graph.createNodeHierarchy(variable.type.getRawTypeName()));
|
||||
edge->addComponent(std::make_shared<EdgeComponentDataType>(
|
||||
variable.type.getQualifierList(), variable.type.getModifierStack()));
|
||||
|
||||
//bool tttt = edge->hasComponent<EdgeComponentDataType>();
|
||||
//std::string foo = edge->getComponent<EdgeComponentDataType>()->getDataType().getFullTypeName();
|
||||
|
||||
addTokenLocation(node, location);
|
||||
}
|
||||
@@ -89,7 +95,7 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable&
|
||||
|
||||
Node* node = m_graph.createNodeHierarchy(variable.fullName);
|
||||
node->setType(Node::NODE_FIELD);
|
||||
node->setConst(variable.isConst);
|
||||
//node->setConst(variable.isConst);
|
||||
node->setStatic(variable.isStatic);
|
||||
|
||||
if (access == ACCESS_NONE)
|
||||
@@ -99,39 +105,48 @@ void Storage::onFieldParsed(const ParseLocation& location, const ParseVariable&
|
||||
}
|
||||
node->setAccess(convertAccessType(access));
|
||||
|
||||
m_graph.createEdge(Edge::EDGE_TYPE_OF, node, m_graph.createNodeHierarchy(variable.typeName));
|
||||
Edge* edge = m_graph.createEdge(Edge::EDGE_TYPE_OF, node, m_graph.createNodeHierarchy(variable.type.getRawTypeName()));
|
||||
edge->addComponent(std::make_shared<EdgeComponentDataType>(
|
||||
variable.type.getQualifierList(), variable.type.getModifierStack()));
|
||||
|
||||
addTokenLocation(node, location);
|
||||
}
|
||||
|
||||
void Storage::onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters
|
||||
)
|
||||
{
|
||||
log("function", fullName, location);
|
||||
|
||||
Node* node = m_graph.createNodeHierarchy(fullName);
|
||||
Node* node = m_graph.createNodeHierarchy(fullName); // Todo: compare signatures in case of overloading.
|
||||
node->setType(Node::NODE_FUNCTION);
|
||||
|
||||
m_graph.createEdge(Edge::EDGE_RETURN_TYPE_OF, node, m_graph.createNodeHierarchy(returnTypeName));
|
||||
for (const ParseVariable& var : parameters)
|
||||
Edge* returnTypeEdge = m_graph.createEdge(
|
||||
Edge::EDGE_RETURN_TYPE_OF, node, m_graph.createNodeHierarchy(returnType.getRawTypeName()));
|
||||
returnTypeEdge->addComponent(std::make_shared<EdgeComponentDataType>(
|
||||
returnType.getQualifierList(), returnType.getModifierStack()));
|
||||
|
||||
for (const ParseVariable& parameter : parameters)
|
||||
{
|
||||
m_graph.createEdge(Edge::EDGE_PARAMETER_OF, node, m_graph.createNodeHierarchy(var.typeName));
|
||||
Edge* parameterEdge = m_graph.createEdge(
|
||||
Edge::EDGE_PARAMETER_OF, node, m_graph.createNodeHierarchy(parameter.type.getRawTypeName()));
|
||||
parameterEdge->addComponent(std::make_shared<EdgeComponentDataType>(
|
||||
parameter.type.getQualifierList(), parameter.type.getModifierStack()));
|
||||
}
|
||||
|
||||
addTokenLocation(node, location);
|
||||
}
|
||||
|
||||
void Storage::onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic
|
||||
)
|
||||
{
|
||||
log("method", fullName, location);
|
||||
|
||||
Node* node = m_graph.createNodeHierarchy(fullName);
|
||||
Node* node = m_graph.createNodeHierarchy(fullName); // Todo: compare signatures in case of overloading.
|
||||
node->setType(Node::NODE_METHOD);
|
||||
node->setConst(isConst);
|
||||
node->setStatic(isStatic);
|
||||
@@ -143,10 +158,17 @@ void Storage::onMethodParsed(
|
||||
}
|
||||
node->setAccess(convertAccessType(access));
|
||||
|
||||
m_graph.createEdge(Edge::EDGE_RETURN_TYPE_OF, node, m_graph.createNodeHierarchy(returnTypeName));
|
||||
Edge* returnTypeEdge = m_graph.createEdge(
|
||||
Edge::EDGE_RETURN_TYPE_OF, node, m_graph.createNodeHierarchy(returnType.getRawTypeName()));
|
||||
returnTypeEdge->addComponent(std::make_shared<EdgeComponentDataType>(
|
||||
returnType.getQualifierList(), returnType.getModifierStack()));
|
||||
|
||||
for (const ParseVariable& parameter : parameters)
|
||||
{
|
||||
m_graph.createEdge(Edge::EDGE_PARAMETER_OF, node, m_graph.createNodeHierarchy(parameter.typeName));
|
||||
Edge* parameterEdge = m_graph.createEdge(
|
||||
Edge::EDGE_PARAMETER_OF, node, m_graph.createNodeHierarchy(parameter.type.getRawTypeName()));
|
||||
parameterEdge->addComponent(std::make_shared<EdgeComponentDataType>(
|
||||
parameter.type.getQualifierList(), parameter.type.getModifierStack()));
|
||||
}
|
||||
|
||||
addTokenLocation(node, location);
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
|
||||
// ParserClient implementation
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& underlyingType,
|
||||
AccessType access
|
||||
);
|
||||
virtual void onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access);
|
||||
@@ -36,12 +36,13 @@ public:
|
||||
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access);
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters);
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic);
|
||||
bool isConst, bool isStatic
|
||||
);
|
||||
|
||||
virtual void onNamespaceParsed(const ParseLocation& location, const std::string& fullName);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "data/graph/edgeComponent/EdgeComponent.h"
|
||||
#include "data/graph/Node.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
@@ -33,6 +34,11 @@ std::shared_ptr<Edge> Edge::createPlainCopy(Node* from, Node* to) const
|
||||
|
||||
edge->setAccess(m_access);
|
||||
|
||||
for (std::shared_ptr<EdgeComponent> component: m_components)
|
||||
{
|
||||
edge->addComponent(component); // Todo: create a deep copy here
|
||||
}
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
@@ -132,6 +138,12 @@ std::string Edge::getAsString() const
|
||||
return str.str();
|
||||
}
|
||||
|
||||
void Edge::addComponent(std::shared_ptr<EdgeComponent> component)
|
||||
{
|
||||
m_components.push_back(component);
|
||||
component->setEdge(this);
|
||||
}
|
||||
|
||||
Edge::Edge(Id id, EdgeType type, Node* from, Node* to)
|
||||
: Token(id)
|
||||
, m_type(type)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "data/graph/Token.h"
|
||||
|
||||
class Node;
|
||||
class EdgeComponent;
|
||||
|
||||
class Edge: public Token
|
||||
{
|
||||
@@ -53,6 +54,15 @@ public:
|
||||
std::string getAccessString() const;
|
||||
std::string getAsString() const;
|
||||
|
||||
|
||||
void addComponent(std::shared_ptr<EdgeComponent> component);
|
||||
|
||||
template <typename ComponentType>
|
||||
std::shared_ptr<ComponentType> getComponent() const;
|
||||
|
||||
template <typename ComponentType>
|
||||
bool hasComponent() const;
|
||||
|
||||
private:
|
||||
// Constructor for plain copies.
|
||||
Edge(Id id, EdgeType type, Node* from, Node* to);
|
||||
@@ -64,8 +74,29 @@ private:
|
||||
|
||||
// Additional fields for different EdgeTypes.
|
||||
AccessType m_access;
|
||||
|
||||
std::vector<std::shared_ptr<EdgeComponent>> m_components;
|
||||
};
|
||||
|
||||
template <typename ComponentType>
|
||||
std::shared_ptr<ComponentType> Edge::getComponent() const
|
||||
{
|
||||
std::shared_ptr<ComponentType> component;
|
||||
for (std::shared_ptr<EdgeComponent> c: m_components)
|
||||
{
|
||||
component = std::dynamic_pointer_cast<ComponentType>(c);
|
||||
if (component)
|
||||
break;
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
template <typename ComponentType>
|
||||
bool Edge::hasComponent() const
|
||||
{
|
||||
return (getComponent<ComponentType>());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const Edge& edge);
|
||||
|
||||
#endif // EDGE_H
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "data/graph/edgeComponent/EdgeComponent.h"
|
||||
|
||||
EdgeComponent::EdgeComponent()
|
||||
{
|
||||
}
|
||||
|
||||
EdgeComponent::~EdgeComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void EdgeComponent::setEdge(Edge* edge)
|
||||
{
|
||||
m_edge = edge;
|
||||
}
|
||||
|
||||
Edge* EdgeComponent::getEdge() const
|
||||
{
|
||||
return m_edge;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef EDGE_COMPONENT_H
|
||||
#define EDGE_COMPONENT_H
|
||||
|
||||
#include "data/graph/Edge.h"
|
||||
|
||||
|
||||
class EdgeComponent
|
||||
{
|
||||
public:
|
||||
EdgeComponent();
|
||||
virtual ~EdgeComponent();
|
||||
|
||||
void setEdge(Edge* edge);
|
||||
|
||||
protected:
|
||||
Edge* getEdge() const;
|
||||
|
||||
private:
|
||||
Edge* m_edge;
|
||||
};
|
||||
|
||||
|
||||
#endif // EDGE_COMPONENT_H
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "data/graph/edgeComponent/EdgeComponentDataType.h"
|
||||
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/graph/Node.h"
|
||||
|
||||
EdgeComponentDataType::EdgeComponentDataType(const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack)
|
||||
: m_qualifierList(qualifierList)
|
||||
, m_modifierStack(modifierStack)
|
||||
{
|
||||
}
|
||||
|
||||
EdgeComponentDataType::~EdgeComponentDataType()
|
||||
{
|
||||
}
|
||||
|
||||
DataType EdgeComponentDataType::getDataType() const
|
||||
{
|
||||
return DataType(getEdge()->getTo()->getName(), m_qualifierList, m_modifierStack);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef EDGE_COMPONENT_DATA_TYPE_H
|
||||
#define EDGE_COMPONENT_DATA_TYPE_H
|
||||
|
||||
#include "data/graph/edgeComponent/EdgeComponent.h"
|
||||
|
||||
#include "data/type/DataTypeModifierStack.h"
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
|
||||
class DataType;
|
||||
|
||||
class EdgeComponentDataType: public EdgeComponent
|
||||
{
|
||||
public:
|
||||
EdgeComponentDataType(const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack);
|
||||
virtual ~EdgeComponentDataType();
|
||||
|
||||
DataType getDataType() const;
|
||||
|
||||
private:
|
||||
const DataTypeQualifierList m_qualifierList;
|
||||
const DataTypeModifierStack m_modifierStack;
|
||||
};
|
||||
|
||||
|
||||
#endif // EDGE_COMPONENT_DATA_TYPE_H
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "data/parser/ParseVariable.h"
|
||||
|
||||
ParseVariable::ParseVariable(const std::string& typeName, const std::string& fullName, bool isConst, bool isStatic)
|
||||
: typeName(typeName)
|
||||
|
||||
ParseVariable::ParseVariable(const DataType& type, const std::string& fullName, bool isStatic)
|
||||
: type(type)
|
||||
, fullName(fullName)
|
||||
, isConst(isConst)
|
||||
, isStatic(isStatic)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "data/type/DataType.h"
|
||||
|
||||
struct ParseVariable
|
||||
{
|
||||
ParseVariable(const std::string& typeName, const std::string& fullName, bool isConst, bool isStatic);
|
||||
ParseVariable(const DataType& type, const std::string& fullName, bool isStatic);
|
||||
|
||||
const std::string typeName;
|
||||
const DataType type;
|
||||
const std::string fullName;
|
||||
const bool isConst;
|
||||
const bool isStatic;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
struct ParseLocation;
|
||||
struct ParseVariable;
|
||||
struct DataType;
|
||||
|
||||
class ParserClient
|
||||
{
|
||||
@@ -27,9 +28,8 @@ public:
|
||||
virtual ~ParserClient();
|
||||
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
AccessType access
|
||||
) = 0;
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& underlyingType,
|
||||
AccessType access) = 0;
|
||||
virtual void onClassParsed(const ParseLocation& location, const std::string& fullName, AccessType access) = 0;
|
||||
virtual void onStructParsed(const ParseLocation& location, const std::string& fullName, AccessType access) = 0;
|
||||
|
||||
@@ -37,11 +37,12 @@ public:
|
||||
virtual void onFieldParsed(const ParseLocation& location, const ParseVariable& variable, AccessType access) = 0;
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters) = 0;
|
||||
virtual void onMethodParsed(const ParseLocation& location, const std::string& fullName,
|
||||
const std::string& returnTypeName, const std::vector<ParseVariable>& parameters, AccessType access,
|
||||
AbstractionType abstraction, bool isConst, bool isStatic) = 0;
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic) = 0;
|
||||
|
||||
virtual void onNamespaceParsed(const ParseLocation& location, const std::string& fullName) = 0;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "data/parser/cxx/ASTVisitor.h"
|
||||
|
||||
#include "data/parser/cxx/ASTBodyVisitor.h"
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParseVariable.h"
|
||||
#include "utility/utilityClang.h"
|
||||
#include "data/type/DataType.h"
|
||||
|
||||
ASTVisitor::ASTVisitor(clang::ASTContext* context, std::shared_ptr<ParserClient> client)
|
||||
@@ -28,7 +28,7 @@ bool ASTVisitor::VisitTypedefDecl(const clang::TypedefDecl* declaration)
|
||||
m_client->onTypedefParsed(
|
||||
getParseLocation(declaration->getSourceRange()),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
declaration->getUnderlyingType().getAsString(),
|
||||
utility::qualTypeToDataType(declaration->getUnderlyingType()),
|
||||
convertAccessType(declaration->getAccess())
|
||||
);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
m_client->onFunctionParsed(
|
||||
getParseLocation(declaration->getSourceRange()),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getTypeName(declaration->getReturnType()),
|
||||
utility::qualTypeToDataType(declaration->getReturnType()),
|
||||
getParameters(declaration)
|
||||
);
|
||||
|
||||
@@ -170,7 +170,7 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
m_client->onMethodParsed(
|
||||
getParseLocation(declaration->getSourceRange()),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
getTypeName(declaration->getReturnType()),
|
||||
utility::qualTypeToDataType(declaration->getReturnType()),
|
||||
getParameters(declaration),
|
||||
convertAccessType(declaration->getAccess()),
|
||||
abstraction,
|
||||
@@ -301,7 +301,7 @@ ParseLocation ASTVisitor::getParseLocation(const clang::SourceRange& sourceRange
|
||||
|
||||
ParseVariable ASTVisitor::getParseVariable(clang::ValueDecl* declaration) const
|
||||
{
|
||||
clang::QualType type = declaration->getType();
|
||||
clang::QualType qualType = declaration->getType();
|
||||
|
||||
bool isStatic = false;
|
||||
if (clang::isa<clang::VarDecl>(declaration))
|
||||
@@ -311,9 +311,8 @@ ParseVariable ASTVisitor::getParseVariable(clang::ValueDecl* declaration) const
|
||||
}
|
||||
|
||||
return ParseVariable(
|
||||
getTypeName(type),
|
||||
utility::qualTypeToDataType(qualType),
|
||||
declaration->getQualifiedNameAsString(),
|
||||
type.isConstQualified(),
|
||||
isStatic
|
||||
);
|
||||
}
|
||||
@@ -332,7 +331,7 @@ std::vector<ParseVariable> ASTVisitor::getParameters(clang::FunctionDecl* declar
|
||||
|
||||
std::string ASTVisitor::getTypeName(const clang::QualType& qualType) const
|
||||
{
|
||||
DataType dataType(qualType);
|
||||
DataType dataType = utility::qualTypeToDataType(qualType);
|
||||
return dataType.getRawTypeName();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ private:
|
||||
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
|
||||
ParseVariable getParseVariable(clang::ValueDecl* declaration) const;
|
||||
std::vector<ParseVariable> getParameters(clang::FunctionDecl* declaration) const;
|
||||
DataType qualTypeToDataType(clang::QualType qualType);
|
||||
std::string getTypeName(const clang::QualType& qualType) const;
|
||||
ParserClient::AccessType convertAccessType(clang::AccessSpecifier) const;
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "data/parser/cxx/utilityCxx.h"
|
||||
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/type/modifier/DataTypeModifierPointer.h"
|
||||
#include "data/type/DataTypeModifierStack.h"
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
DataType qualTypeToDataType(clang::QualType qualType)
|
||||
{
|
||||
std::string typeName;
|
||||
DataTypeQualifierList qualifierList;
|
||||
DataTypeModifierStack modifierStack;
|
||||
|
||||
while (true)
|
||||
{
|
||||
const clang::Type* type = qualType.getTypePtr();
|
||||
if (type->isPointerType())
|
||||
{
|
||||
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierPointer>();
|
||||
if (qualType.isConstQualified())
|
||||
modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
modifierStack.push(modifier);
|
||||
|
||||
qualType = type->getPointeeType();
|
||||
}
|
||||
else if (type->isStructureOrClassType() || type->isEnumeralType())
|
||||
{
|
||||
typeName = qualType.getAsString();
|
||||
|
||||
// we are working on the string here to not lose the namespace information stored in the name.
|
||||
size_t nameStartPosition = typeName.find(' ');
|
||||
if (nameStartPosition != typeName.npos)
|
||||
{
|
||||
nameStartPosition += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nameStartPosition = 0;
|
||||
}
|
||||
typeName = typeName.substr(nameStartPosition, typeName.size());
|
||||
|
||||
//m_typeName = qualType.getBaseTypeIdentifier()->getName(); // this one does not keep namespace information.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = qualType.getUnqualifiedType().getAsString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (qualType.isConstQualified())
|
||||
qualifierList.addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
|
||||
return DataType(typeName, qualifierList, modifierStack);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ class DataType;
|
||||
|
||||
namespace utility
|
||||
{
|
||||
DataType qualTypeToDataType(clang::QualType qualType);
|
||||
}
|
||||
|
||||
#endif // UTILITY_CLANG_H
|
||||
@@ -1,50 +1,28 @@
|
||||
#include "data/type/DataType.h"
|
||||
#include "data/type/modifier/DataTypeModifierPointer.h"
|
||||
|
||||
DataType::DataType(const std::string& typeName)
|
||||
DataType::DataType(
|
||||
const std::string& typeName, const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack
|
||||
)
|
||||
: m_typeName(typeName)
|
||||
, m_qualifierList(qualifierList)
|
||||
, m_modifierStack(modifierStack)
|
||||
{
|
||||
}
|
||||
|
||||
DataType::DataType(clang::QualType qualType)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const clang::Type* type = qualType.getTypePtr();
|
||||
if (type->isPointerType())
|
||||
{
|
||||
std::shared_ptr<DataTypeModifier> modifier = std::make_shared<DataTypeModifierPointer>();
|
||||
if (qualType.isConstQualified())
|
||||
modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
m_modifierStack.push(modifier);
|
||||
|
||||
qualType = type->getPointeeType();
|
||||
}
|
||||
else if (type->isStructureOrClassType() || type->isEnumeralType())
|
||||
{
|
||||
m_typeName = qualType.getAsString();
|
||||
|
||||
// we are working on the string here to not lose the namespace information stored in the name.
|
||||
m_typeName = m_typeName.substr(m_typeName.find(' ') + 1, m_typeName.size() - 1);
|
||||
|
||||
//m_typeName = qualType.getBaseTypeIdentifier()->getName(); // this one does not keep namespace information.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_typeName = qualType.getUnqualifiedType().getAsString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (qualType.isConstQualified())
|
||||
m_qualifierList.addQualifier(DataTypeQualifierList::QUALIFIER_CONST);
|
||||
}
|
||||
|
||||
DataType::~DataType()
|
||||
{
|
||||
}
|
||||
|
||||
DataTypeQualifierList DataType::getQualifierList() const
|
||||
{
|
||||
return m_qualifierList;
|
||||
}
|
||||
|
||||
DataTypeModifierStack DataType::getModifierStack() const
|
||||
{
|
||||
return m_modifierStack;
|
||||
}
|
||||
|
||||
std::string DataType::getFullTypeName() const
|
||||
{
|
||||
return m_modifierStack.applyTo(m_qualifierList.applyTo(m_typeName));
|
||||
|
||||
@@ -4,24 +4,27 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
|
||||
#include "data/type/DataTypeModifierStack.h"
|
||||
#include "data/type/DataTypeQualifierList.h"
|
||||
|
||||
class DataType
|
||||
{
|
||||
public:
|
||||
DataType(clang::QualType qualType);
|
||||
DataType(const std::string& typeName);
|
||||
DataType(
|
||||
const std::string& typeName, const DataTypeQualifierList qualifierList, const DataTypeModifierStack modifierStack
|
||||
);
|
||||
~DataType();
|
||||
|
||||
DataTypeQualifierList getQualifierList() const;
|
||||
DataTypeModifierStack getModifierStack() const;
|
||||
|
||||
std::string getFullTypeName() const;
|
||||
std::string getRawTypeName() const;
|
||||
|
||||
private:
|
||||
std::string m_typeName;
|
||||
DataTypeQualifierList m_qualifierList;
|
||||
DataTypeModifierStack m_modifierStack;
|
||||
const std::string m_typeName;
|
||||
const DataTypeQualifierList m_qualifierList;
|
||||
const DataTypeModifierStack m_modifierStack;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_H
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
|
||||
class DataTypeQualifierList
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -8,6 +8,12 @@ DataTypeModifier::~DataTypeModifier()
|
||||
{
|
||||
}
|
||||
|
||||
void DataTypeModifier::applyTo(std::string& typeName) const
|
||||
{
|
||||
doApplyTo(typeName);
|
||||
typeName = m_qualifierList.applyTo(typeName);
|
||||
}
|
||||
|
||||
void DataTypeModifier::addQualifier(DataTypeQualifierList::QualifierType qualifier)
|
||||
{
|
||||
m_qualifierList.addQualifier(qualifier);
|
||||
|
||||
@@ -11,13 +11,15 @@ public:
|
||||
DataTypeModifier();
|
||||
virtual ~DataTypeModifier();
|
||||
|
||||
virtual void applyTo(std::string& typeName) const = 0;
|
||||
void applyTo(std::string& typeName) const;
|
||||
|
||||
void addQualifier(DataTypeQualifierList::QualifierType qualifier);
|
||||
void removeQualifier(DataTypeQualifierList::QualifierType qualifier);
|
||||
bool hasQualifier(DataTypeQualifierList::QualifierType qualifier) const;
|
||||
|
||||
private:
|
||||
virtual void doApplyTo(std::string& typeName) const = 0;
|
||||
|
||||
DataTypeQualifierList m_qualifierList;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ DataTypeModifierPointer::~DataTypeModifierPointer()
|
||||
{
|
||||
}
|
||||
|
||||
void DataTypeModifierPointer::applyTo(std::string& typeName) const
|
||||
void DataTypeModifierPointer::doApplyTo(std::string& typeName) const
|
||||
{
|
||||
typeName.append(" *");
|
||||
}
|
||||
|
||||
@@ -9,9 +9,8 @@ public:
|
||||
DataTypeModifierPointer();
|
||||
virtual ~DataTypeModifierPointer();
|
||||
|
||||
virtual void applyTo(std::string& typeName) const;
|
||||
|
||||
|
||||
private:
|
||||
virtual void doApplyTo(std::string& typeName) const;
|
||||
};
|
||||
|
||||
#endif // DATA_TYPE_MODIFIER_POINTER_H
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#include "utility/utilityClang.h"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
}
|
||||
@@ -125,9 +125,9 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(client->globalVariables.size(), 4);
|
||||
TS_ASSERT_EQUALS(client->globalVariables[0], "int x <1:1 1:5>");
|
||||
TS_ASSERT_EQUALS(client->globalVariables[1], "const int y <2:1 2:15>");
|
||||
TS_ASSERT_EQUALS(client->globalVariables[1], "int const y <2:1 2:15>");
|
||||
TS_ASSERT_EQUALS(client->globalVariables[2], "static int z <3:1 3:12>");
|
||||
TS_ASSERT_EQUALS(client->globalVariables[3], "A b <5:1 5:4>"); // Todo: what about the pointer?
|
||||
TS_ASSERT_EQUALS(client->globalVariables[3], "A * b <5:1 5:4>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_variable_definitions_in_namespace_scope()
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(client->globalVariables.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->globalVariables[0], "int n::x <2:2 2:6>");
|
||||
TS_ASSERT_EQUALS(client->globalVariables[1], "n::A n::b <4:2 4:5>"); // Todo: what about the pointer?
|
||||
TS_ASSERT_EQUALS(client->globalVariables[1], "n::A * n::b <4:2 4:5>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_field_in_nested_class()
|
||||
@@ -161,7 +161,7 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->fields.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->fields[0], "private static const int B::C::amount <7:3 7:20>");
|
||||
TS_ASSERT_EQUALS(client->fields[0], "private static int const B::C::amount <7:3 7:20>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_fields_in_class_with_access_type()
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
TS_ASSERT_EQUALS(client->fields[0], "private int A::a <3:2 3:6>");
|
||||
TS_ASSERT_EQUALS(client->fields[1], "public int A::b <5:2 5:6>");
|
||||
TS_ASSERT_EQUALS(client->fields[2], "protected static int A::c <6:2 6:13>");
|
||||
TS_ASSERT_EQUALS(client->fields[3], "private const int A::d <8:2 8:12>");
|
||||
TS_ASSERT_EQUALS(client->fields[3], "private int const A::d <8:2 8:12>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_function_in_global_namespace()
|
||||
@@ -701,11 +701,11 @@ private:
|
||||
{
|
||||
public:
|
||||
virtual void onTypedefParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& underlyingFullName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& underlyingType,
|
||||
AccessType access
|
||||
)
|
||||
{
|
||||
std::string str = addAccessPrefix(underlyingFullName + " -> " + fullName, access);
|
||||
std::string str = addAccessPrefix(underlyingType.getFullTypeName() + " -> " + fullName, access);
|
||||
typedefs.push_back(addLocationSuffix(str, location));
|
||||
}
|
||||
|
||||
@@ -730,21 +730,21 @@ private:
|
||||
}
|
||||
|
||||
virtual void onFunctionParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters
|
||||
)
|
||||
{
|
||||
std::string str = returnTypeName + " " + fullName + parameterStr(parameters);
|
||||
std::string str = returnType.getFullTypeName() + " " + fullName + parameterStr(parameters);
|
||||
functions.push_back(addLocationSuffix(str, location));
|
||||
}
|
||||
|
||||
virtual void onMethodParsed(
|
||||
const ParseLocation& location, const std::string& fullName, const std::string& returnTypeName,
|
||||
const ParseLocation& location, const std::string& fullName, const DataType& returnType,
|
||||
const std::vector<ParseVariable>& parameters, AccessType access, AbstractionType abstraction,
|
||||
bool isConst, bool isStatic
|
||||
)
|
||||
{
|
||||
std::string str = returnTypeName + " " + fullName + parameterStr(parameters);
|
||||
std::string str = returnType.getFullTypeName() + " " + fullName + parameterStr(parameters);
|
||||
str = addStaticPrefix(addAbstractionPrefix(str, abstraction), isStatic);
|
||||
str = addConstPrefix(addAccessPrefix(str, access), isConst, false);
|
||||
str = addLocationSuffix(str, location);
|
||||
@@ -841,8 +841,8 @@ private:
|
||||
|
||||
std::string variableStr(const ParseVariable& variable)
|
||||
{
|
||||
std::string str = variable.typeName + " " + variable.fullName;
|
||||
return addStaticPrefix(addConstPrefix(str, variable.isConst, true), variable.isStatic);
|
||||
std::string str = variable.type.getFullTypeName() + " " + variable.fullName;
|
||||
return addStaticPrefix(str, variable.isStatic);
|
||||
}
|
||||
|
||||
std::string parameterStr(const std::vector<ParseVariable> parameters)
|
||||
|
||||
Reference in New Issue
Block a user