ui: Added custom tooltipping to code and graph (issue #195)

* Tooltips show node type with access specifier, reference count and fully qualified name
* Fields and global variables include the type name
* Methods and functinos show whole signature. Gets broken into multiple lines if too long.

Included changes:

* Upgraded to C++14
* fixed clang warnings
* Pass location of .srctrlprj file to build.sh script to load on launch
* Split off QtCodeField for showing highlighted and annotated code fom QtCodeArea
* removed TokenComponentSignature
* added TaskDecoratorDelay

bug id = 195
This commit is contained in:
Eberhard Graether
2017-07-31 12:45:22 +02:00
parent 01b1e0d6f1
commit 01864b4d0c
79 changed files with 2340 additions and 1009 deletions
+15 -10
View File
@@ -16,14 +16,17 @@
#include "data/ErrorFilter.h"
#include "data/ErrorInfo.h"
#include "data/storage/StorageStats.h"
#include "data/tooltip/TooltipInfo.h"
#include "data/tooltip/TooltipOrigin.h"
class FilePath;
struct FileInfo;
class Graph;
class SourceLocationCollection;
class SourceLocationFile;
class TextAccess;
struct FileInfo;
class StorageAccess
{
public:
@@ -34,7 +37,7 @@ public:
virtual std::vector<Id> getNodeIdsForNameHierarchies(const std::vector<NameHierarchy> nameHierarchies) const = 0;
virtual NameHierarchy getNameHierarchyForNodeId(Id id) const = 0;
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const = 0;
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id>& nodeIds) const = 0;
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0;
@@ -79,20 +82,22 @@ public:
virtual void setErrorFilter(const ErrorFilter& filter);
virtual Id addNodeBookmark(const NodeBookmark& bookmark) = 0; // todo: remove these from storage access
virtual Id addEdgeBookmark(const EdgeBookmark& bookmark) = 0; // todo: remove these from storage access
virtual Id addBookmarkCategory(const std::string& categoryName) = 0; // todo: remove these from storage access
// todo: remove bookmark related methods from storage access
virtual Id addNodeBookmark(const NodeBookmark& bookmark) = 0;
virtual Id addEdgeBookmark(const EdgeBookmark& bookmark) = 0;
virtual Id addBookmarkCategory(const std::string& categoryName) = 0;
virtual void updateBookmark(const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName) = 0; // todo: remove these from storage access
virtual void removeBookmark(const Id id) = 0; // todo: remove these from storage access
virtual void removeBookmarkCategory(const Id id) = 0; // todo: remove these from storage access
virtual void updateBookmark(
const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName) = 0;
virtual void removeBookmark(const Id id) = 0;
virtual void removeBookmarkCategory(const Id id) = 0;
virtual std::vector<NodeBookmark> getAllNodeBookmarks() const = 0;
virtual std::vector<EdgeBookmark> getAllEdgeBookmarks() const = 0;
virtual std::vector<BookmarkCategory> getAllBookmarkCategories() const = 0;
virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const = 0;
protected:
ErrorFilter m_errorFilter;
};
+11 -1
View File
@@ -75,7 +75,7 @@ NameHierarchy StorageAccessProxy::getNameHierarchyForNodeId(Id id) const
return NameHierarchy(NAME_DELIMITER_UNKNOWN);
}
std::vector<NameHierarchy> StorageAccessProxy::getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const
std::vector<NameHierarchy> StorageAccessProxy::getNameHierarchiesForNodeIds(const std::vector<Id>& nodeIds) const
{
if (hasSubject())
{
@@ -415,6 +415,16 @@ std::vector<BookmarkCategory> StorageAccessProxy::getAllBookmarkCategories() con
return std::vector<BookmarkCategory>();
}
TooltipInfo StorageAccessProxy::getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const
{
if (hasSubject())
{
return m_subject->getTooltipInfoForTokenIds(tokenIds, origin);
}
return TooltipInfo();
}
void StorageAccessProxy::setErrorFilter(const ErrorFilter& filter)
{
StorageAccess::setErrorFilter(filter);
+5 -4
View File
@@ -23,7 +23,7 @@ public:
virtual std::vector<Id> getNodeIdsForNameHierarchies(const std::vector<NameHierarchy> nameHierarchies) const;
virtual NameHierarchy getNameHierarchyForNodeId(Id id) const;
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const;
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id>& nodeIds) const;
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const;
@@ -73,16 +73,17 @@ public:
virtual Id addEdgeBookmark(const EdgeBookmark& bookmark);
virtual Id addBookmarkCategory(const std::string& categoryName);
virtual void updateBookmark(const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName);
virtual void updateBookmark(
const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName);
virtual void removeBookmark(const Id id);
virtual void removeBookmarkCategory(const Id id);
virtual std::vector<NodeBookmark> getAllNodeBookmarks() const;
virtual std::vector<EdgeBookmark> getAllEdgeBookmarks() const;
virtual std::vector<BookmarkCategory> getAllBookmarkCategories() const;
virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const;
protected:
virtual void setErrorFilter(const ErrorFilter& filter);
+7 -23
View File
@@ -10,13 +10,14 @@
#include "data/graph/token_component/TokenComponentConst.h"
#include "data/graph/token_component/TokenComponentStatic.h"
#include "data/graph/token_component/TokenComponentFilePath.h"
#include "data/graph/token_component/TokenComponentSignature.h"
const Node::NodeTypeMask Node::NODE_NOT_VISIBLE = Node::NODE_NAMESPACE | Node::NODE_PACKAGE;
const Node::NodeTypeMask Node::NODE_USEABLE_TYPE = Node::NODE_NON_INDEXED | Node::NODE_BUILTIN_TYPE |
Node::NODE_STRUCT | Node::NODE_CLASS | Node::NODE_INTERFACE | Node::NODE_TYPEDEF;
const Node::NodeTypeMask Node::NODE_INHERITABLE_TYPE = Node::NODE_NON_INDEXED | Node::NODE_BUILTIN_TYPE |
NODE_TYPE | Node::NODE_STRUCT | Node::NODE_CLASS | Node::NODE_INTERFACE;
const Node::NodeTypeMask Node::NODE_NOT_VISIBLE = NODE_NAMESPACE | NODE_PACKAGE;
const Node::NodeTypeMask Node::NODE_USEABLE_TYPE = NODE_NON_INDEXED | NODE_BUILTIN_TYPE | NODE_STRUCT | NODE_CLASS |
NODE_UNION | NODE_INTERFACE | NODE_TYPEDEF;
const Node::NodeTypeMask Node::NODE_INHERITABLE_TYPE = NODE_NON_INDEXED | NODE_BUILTIN_TYPE | NODE_TYPE | NODE_STRUCT |
NODE_CLASS | NODE_INTERFACE;
const Node::NodeTypeMask Node::NODE_MEMBER_TYPE = NODE_METHOD | NODE_FIELD | NODE_CLASS | NODE_INTERFACE | NODE_STRUCT |
NODE_UNION | NODE_TYPEDEF | NODE_ENUM;
std::string Node::getUnderscoredTypeString(NodeType type)
{
@@ -469,23 +470,6 @@ void Node::addComponentFilePath(std::shared_ptr<TokenComponentFilePath> componen
}
}
void Node::addComponentSignature(std::shared_ptr<TokenComponentSignature> component)
{
if (getComponent<TokenComponentSignature>())
{
LOG_ERROR("TokenComponentSignature has been set before!");
return;
}
else if (!isType(NODE_FUNCTION | NODE_METHOD))
{
LOG_ERROR("TokenComponentFilePath can't be set on node of type: " + getReadableTypeString());
}
else
{
addComponent(component);
}
}
void Node::addComponentAccess(std::shared_ptr<TokenComponentAccess> component)
{
if (getComponent<TokenComponentAccess>())
+1
View File
@@ -58,6 +58,7 @@ public:
static const NodeTypeMask NODE_NOT_VISIBLE;
static const NodeTypeMask NODE_USEABLE_TYPE;
static const NodeTypeMask NODE_INHERITABLE_TYPE;
static const NodeTypeMask NODE_MEMBER_TYPE;
Node(Id id, NodeType type, NameHierarchy nameHierarchy, bool defined);
Node(const Node& other);
@@ -1,20 +0,0 @@
#include "data/graph/token_component/TokenComponentSignature.h"
TokenComponentSignature::TokenComponentSignature(const std::string& signature)
: m_signature(signature)
{
}
TokenComponentSignature::~TokenComponentSignature()
{
}
std::shared_ptr<TokenComponent> TokenComponentSignature::copy() const
{
return std::make_shared<TokenComponentSignature>(*this);
}
const std::string& TokenComponentSignature::getSignature() const
{
return m_signature;
}
@@ -1,23 +0,0 @@
#ifndef TOKEN_COMPONENT_SIGNATURE_H
#define TOKEN_COMPONENT_SIGNATURE_H
#include <string>
#include "data/graph/token_component/TokenComponent.h"
class TokenComponentSignature
: public TokenComponent
{
public:
TokenComponentSignature(const std::string& signature);
virtual ~TokenComponentSignature();
virtual std::shared_ptr<TokenComponent> copy() const;
const std::string& getSignature() const;
private:
const std::string m_signature;
};
#endif // TOKEN_COMPONENT_SIGNATURE_H
+10
View File
@@ -61,6 +61,16 @@ bool NameElement::Signature::isValid() const
return ((m_prefix + m_postfix).size() > 0);
}
const std::string& NameElement::Signature::getPrefix() const
{
return m_prefix;
}
const std::string& NameElement::Signature::getPostfix() const
{
return m_postfix;
}
NameElement::NameElement(const std::string& name)
: m_name(name)
{
+3
View File
@@ -21,6 +21,9 @@ public:
std::string qualifyName(const std::string& name) const;
bool isValid() const;
const std::string& getPrefix() const;
const std::string& getPostfix() const;
private:
std::string m_prefix;
std::string m_postfix;
+10
View File
@@ -161,3 +161,13 @@ std::string NameHierarchy::getRawNameWithSignature() const
}
return "";
}
NameElement::Signature NameHierarchy::getSignature() const
{
if (m_elements.size())
{
return m_elements.back()->getSignature(); // todo: use separator for signature!
}
return NameElement::Signature();
}
+2
View File
@@ -37,6 +37,8 @@ public:
std::string getRawName() const;
std::string getRawNameWithSignature() const;
NameElement::Signature getSignature() const;
private:
std::vector<std::shared_ptr<NameElement>> m_elements;
NameDelimiterType m_delimiter;
+22
View File
@@ -25,3 +25,25 @@ int accessKindToInt(AccessKind t)
return t;
}
std::string accessKindToString(AccessKind t)
{
switch (t)
{
case ACCESS_NONE:
return "";
case ACCESS_PUBLIC:
return "public";
case ACCESS_PROTECTED:
return "protected";
case ACCESS_PRIVATE:
return "private";
case ACCESS_DEFAULT:
return "default";
case ACCESS_TEMPLATE_PARAMETER:
return "template parameter";
case ACCESS_TYPE_PARAMETER:
return "type parameter";
}
return "";
}
+3
View File
@@ -1,6 +1,8 @@
#ifndef ACCESS_KIND_H
#define ACCESS_KIND_H
#include <string>
enum AccessKind
{ // these values need to be the same as AccessKind in Java code
ACCESS_NONE = 0,
@@ -14,5 +16,6 @@ enum AccessKind
AccessKind intToAccessKind(int v);
int accessKindToInt(AccessKind t);
std::string accessKindToString(AccessKind t);
#endif // ACCESS_KIND_H
-13
View File
@@ -15,14 +15,6 @@ TaskParseWrapper::~TaskParseWrapper()
{
}
void TaskParseWrapper::setTask(std::shared_ptr<Task> task)
{
if (task)
{
m_taskRunner = std::make_shared<TaskRunner>(task);
}
}
void TaskParseWrapper::doEnter(std::shared_ptr<Blackboard> blackboard)
{
int sourceFileCount = 0;
@@ -54,8 +46,3 @@ void TaskParseWrapper::doReset(std::shared_ptr<Blackboard> blackboard)
{
m_taskRunner->reset();
}
void TaskParseWrapper::doTerminate()
{
m_taskRunner->terminate();
}
-4
View File
@@ -19,19 +19,15 @@ public:
TaskParseWrapper(PersistentStorage* storage);
virtual ~TaskParseWrapper();
virtual void setTask(std::shared_ptr<Task> task);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
virtual void doTerminate();
PersistentStorage* m_storage;
TimePoint m_start;
std::shared_ptr<TaskRunner> m_taskRunner;
};
#endif // TASK_PARSE_WRAPPER_H
+366 -189
View File
@@ -18,12 +18,12 @@
#include "data/graph/token_component/TokenComponentAggregation.h"
#include "data/graph/token_component/TokenComponentFilePath.h"
#include "data/graph/token_component/TokenComponentInheritanceChain.h"
#include "data/graph/token_component/TokenComponentSignature.h"
#include "data/graph/Graph.h"
#include "data/location/SourceLocationCollection.h"
#include "data/location/SourceLocationFile.h"
#include "data/parser/AccessKind.h"
#include "data/parser/ParseLocation.h"
#include "settings/ApplicationSettings.h"
PersistentStorage::PersistentStorage(const FilePath& dbPath, const FilePath& bookmarkPath)
: m_sqliteIndexStorage(dbPath)
@@ -147,182 +147,6 @@ void PersistentStorage::addError(
);
}
Id PersistentStorage::addNodeBookmark(const NodeBookmark& bookmark)
{
const Id categoryId = addBookmarkCategory(bookmark.getCategory().getName());
const Id id = m_sqliteBookmarkStorage.addBookmark(
bookmark.getName(), bookmark.getComment(), bookmark.getTimeStamp().toString(), categoryId);
for (const Id& nodeId: bookmark.getNodeIds())
{
m_sqliteBookmarkStorage.addBookmarkedNode(id, m_sqliteIndexStorage.getNodeById(nodeId).serializedName);
}
return id;
}
Id PersistentStorage::addEdgeBookmark(const EdgeBookmark& bookmark)
{
const Id categoryId = addBookmarkCategory(bookmark.getCategory().getName());
const Id id = m_sqliteBookmarkStorage.addBookmark(
bookmark.getName(), bookmark.getComment(), bookmark.getTimeStamp().toString(), categoryId);
for (const Id& edgeId: bookmark.getEdgeIds())
{
const StorageEdge storageEdge = m_sqliteIndexStorage.getEdgeById(edgeId);
bool sourceNodeActive = storageEdge.sourceNodeId == bookmark.getActiveNodeId();
m_sqliteBookmarkStorage.addBookmarkedEdge(
id,
// todo: optimization for multiple edges in same bookmark: use a local cache here
m_sqliteIndexStorage.getNodeById(storageEdge.sourceNodeId).serializedName,
m_sqliteIndexStorage.getNodeById(storageEdge.targetNodeId).serializedName,
storageEdge.type,
sourceNodeActive
);
}
return id;
}
Id PersistentStorage::addBookmarkCategory(const std::string& name)
{
if (name.empty())
{
return 0;
}
Id id = m_sqliteBookmarkStorage.getBookmarkCategoryByName(name).id;
if (id == 0)
{
id = m_sqliteBookmarkStorage.addBookmarkCategory(name);
}
return id;
}
void PersistentStorage::updateBookmark(
const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName)
{
const Id categoryId = addBookmarkCategory(categoryName); // only creates category if id didn't exist before;
m_sqliteBookmarkStorage.updateBookmark(bookmarkId, name, comment, categoryId);
}
void PersistentStorage::removeBookmark(const Id id)
{
m_sqliteBookmarkStorage.removeBookmark(id);
}
void PersistentStorage::removeBookmarkCategory(Id id)
{
m_sqliteBookmarkStorage.removeBookmarkCategory(id);
}
std::vector<NodeBookmark> PersistentStorage::getAllNodeBookmarks() const
{
std::unordered_map<Id, StorageBookmarkCategory> bookmarkCategories;
for (const StorageBookmarkCategory& bookmarkCategory: m_sqliteBookmarkStorage.getAllBookmarkCategories())
{
bookmarkCategories[bookmarkCategory.id] = bookmarkCategory;
}
std::unordered_map<Id, std::vector<Id>> bookmarkIdToBookmarkedNodeIds;
for (const StorageBookmarkedNode& bookmarkedNode: m_sqliteBookmarkStorage.getAllBookmarkedNodes())
{
bookmarkIdToBookmarkedNodeIds[bookmarkedNode.bookmarkId].push_back(
m_sqliteIndexStorage.getNodeBySerializedName(bookmarkedNode.serializedNodeName).id);
}
std::vector<NodeBookmark> nodeBookmarks;
for (const StorageBookmark& storageBookmark: m_sqliteBookmarkStorage.getAllBookmarks())
{
auto itCategories = bookmarkCategories.find(storageBookmark.categoryId);
auto itNodeIds = bookmarkIdToBookmarkedNodeIds.find(storageBookmark.id);
if (itCategories != bookmarkCategories.end() && itNodeIds != bookmarkIdToBookmarkedNodeIds.end())
{
NodeBookmark bookmark(
storageBookmark.id,
storageBookmark.name,
storageBookmark.comment,
storageBookmark.timestamp,
BookmarkCategory(itCategories->second.id, itCategories->second.name)
);
bookmark.setNodeIds(itNodeIds->second);
bookmark.setIsValid();
nodeBookmarks.push_back(bookmark);
}
}
return nodeBookmarks;
}
std::vector<EdgeBookmark> PersistentStorage::getAllEdgeBookmarks() const
{
std::unordered_map<Id, StorageBookmarkCategory> bookmarkCategories;
for (const StorageBookmarkCategory& bookmarkCategory: m_sqliteBookmarkStorage.getAllBookmarkCategories())
{
bookmarkCategories[bookmarkCategory.id] = bookmarkCategory;
}
std::unordered_map<Id, std::vector<StorageBookmarkedEdge>> bookmarkIdToBookmarkedEdges;
for (const StorageBookmarkedEdge& bookmarkedEdge: m_sqliteBookmarkStorage.getAllBookmarkedEdges())
{
bookmarkIdToBookmarkedEdges[bookmarkedEdge.bookmarkId].push_back(bookmarkedEdge);
}
std::vector<EdgeBookmark> edgeBookmarks;
Cache<std::string, Id> nodeIdCache([&](std::string serializedNodeName)
{
return m_sqliteIndexStorage.getNodeBySerializedName(serializedNodeName).id;
}
);
for (const StorageBookmark& storageBookmark: m_sqliteBookmarkStorage.getAllBookmarks())
{
auto itCategories = bookmarkCategories.find(storageBookmark.categoryId);
auto itBookmarkedEdges = bookmarkIdToBookmarkedEdges.find(storageBookmark.id);
if (itCategories != bookmarkCategories.end() && itBookmarkedEdges != bookmarkIdToBookmarkedEdges.end())
{
EdgeBookmark bookmark(
storageBookmark.id,
storageBookmark.name,
storageBookmark.comment,
storageBookmark.timestamp,
BookmarkCategory(itCategories->second.id, itCategories->second.name)
);
Id activeNodeId = 0;
for (const StorageBookmarkedEdge& bookmarkedEdge: itBookmarkedEdges->second)
{
const Id sourceNodeId = nodeIdCache.getValue(bookmarkedEdge.serializedSourceNodeName);
const Id targetNodeId = nodeIdCache.getValue(bookmarkedEdge.serializedTargetNodeName);
const Id edgeId =
m_sqliteIndexStorage.getEdgeBySourceTargetType(sourceNodeId, targetNodeId, bookmarkedEdge.edgeType).id;
bookmark.addEdgeId(edgeId);
if (activeNodeId == 0)
{
activeNodeId = bookmarkedEdge.sourceNodeActive ? sourceNodeId : targetNodeId;
}
}
bookmark.setActiveNodeId(activeNodeId);
bookmark.setIsValid();
edgeBookmarks.push_back(bookmark);
}
}
return edgeBookmarks;
}
std::vector<BookmarkCategory> PersistentStorage::getAllBookmarkCategories() const
{
std::vector<BookmarkCategory> categories;
for (const StorageBookmarkCategory storageBookmarkCategoriy: m_sqliteBookmarkStorage.getAllBookmarkCategories())
{
categories.push_back(BookmarkCategory(storageBookmarkCategoriy.id, storageBookmarkCategoriy.name));
}
return categories;
}
void PersistentStorage::forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const
{
for (StorageNode& node: m_sqliteIndexStorage.getAll<StorageNode>())
@@ -602,7 +426,7 @@ NameHierarchy PersistentStorage::getNameHierarchyForNodeId(Id nodeId) const
return NameHierarchy::deserialize(m_sqliteIndexStorage.getFirstById<StorageNode>(nodeId).serializedName);
}
std::vector<NameHierarchy> PersistentStorage::getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const
std::vector<NameHierarchy> PersistentStorage::getNameHierarchiesForNodeIds(const std::vector<Id>& nodeIds) const
{
TRACE();
@@ -1564,6 +1388,370 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getErrorSourceLocat
return collection;
}
Id PersistentStorage::addNodeBookmark(const NodeBookmark& bookmark)
{
const Id categoryId = addBookmarkCategory(bookmark.getCategory().getName());
const Id id = m_sqliteBookmarkStorage.addBookmark(
bookmark.getName(), bookmark.getComment(), bookmark.getTimeStamp().toString(), categoryId);
for (const Id& nodeId: bookmark.getNodeIds())
{
m_sqliteBookmarkStorage.addBookmarkedNode(id, m_sqliteIndexStorage.getNodeById(nodeId).serializedName);
}
return id;
}
Id PersistentStorage::addEdgeBookmark(const EdgeBookmark& bookmark)
{
const Id categoryId = addBookmarkCategory(bookmark.getCategory().getName());
const Id id = m_sqliteBookmarkStorage.addBookmark(
bookmark.getName(), bookmark.getComment(), bookmark.getTimeStamp().toString(), categoryId);
for (const Id& edgeId: bookmark.getEdgeIds())
{
const StorageEdge storageEdge = m_sqliteIndexStorage.getEdgeById(edgeId);
bool sourceNodeActive = storageEdge.sourceNodeId == bookmark.getActiveNodeId();
m_sqliteBookmarkStorage.addBookmarkedEdge(
id,
// todo: optimization for multiple edges in same bookmark: use a local cache here
m_sqliteIndexStorage.getNodeById(storageEdge.sourceNodeId).serializedName,
m_sqliteIndexStorage.getNodeById(storageEdge.targetNodeId).serializedName,
storageEdge.type,
sourceNodeActive
);
}
return id;
}
Id PersistentStorage::addBookmarkCategory(const std::string& name)
{
if (name.empty())
{
return 0;
}
Id id = m_sqliteBookmarkStorage.getBookmarkCategoryByName(name).id;
if (id == 0)
{
id = m_sqliteBookmarkStorage.addBookmarkCategory(name);
}
return id;
}
void PersistentStorage::updateBookmark(
const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName)
{
const Id categoryId = addBookmarkCategory(categoryName); // only creates category if id didn't exist before;
m_sqliteBookmarkStorage.updateBookmark(bookmarkId, name, comment, categoryId);
}
void PersistentStorage::removeBookmark(const Id id)
{
m_sqliteBookmarkStorage.removeBookmark(id);
}
void PersistentStorage::removeBookmarkCategory(Id id)
{
m_sqliteBookmarkStorage.removeBookmarkCategory(id);
}
std::vector<NodeBookmark> PersistentStorage::getAllNodeBookmarks() const
{
std::unordered_map<Id, StorageBookmarkCategory> bookmarkCategories;
for (const StorageBookmarkCategory& bookmarkCategory: m_sqliteBookmarkStorage.getAllBookmarkCategories())
{
bookmarkCategories[bookmarkCategory.id] = bookmarkCategory;
}
std::unordered_map<Id, std::vector<Id>> bookmarkIdToBookmarkedNodeIds;
for (const StorageBookmarkedNode& bookmarkedNode: m_sqliteBookmarkStorage.getAllBookmarkedNodes())
{
bookmarkIdToBookmarkedNodeIds[bookmarkedNode.bookmarkId].push_back(
m_sqliteIndexStorage.getNodeBySerializedName(bookmarkedNode.serializedNodeName).id);
}
std::vector<NodeBookmark> nodeBookmarks;
for (const StorageBookmark& storageBookmark: m_sqliteBookmarkStorage.getAllBookmarks())
{
auto itCategories = bookmarkCategories.find(storageBookmark.categoryId);
auto itNodeIds = bookmarkIdToBookmarkedNodeIds.find(storageBookmark.id);
if (itCategories != bookmarkCategories.end() && itNodeIds != bookmarkIdToBookmarkedNodeIds.end())
{
NodeBookmark bookmark(
storageBookmark.id,
storageBookmark.name,
storageBookmark.comment,
storageBookmark.timestamp,
BookmarkCategory(itCategories->second.id, itCategories->second.name)
);
bookmark.setNodeIds(itNodeIds->second);
bookmark.setIsValid();
nodeBookmarks.push_back(bookmark);
}
}
return nodeBookmarks;
}
std::vector<EdgeBookmark> PersistentStorage::getAllEdgeBookmarks() const
{
std::unordered_map<Id, StorageBookmarkCategory> bookmarkCategories;
for (const StorageBookmarkCategory& bookmarkCategory: m_sqliteBookmarkStorage.getAllBookmarkCategories())
{
bookmarkCategories[bookmarkCategory.id] = bookmarkCategory;
}
std::unordered_map<Id, std::vector<StorageBookmarkedEdge>> bookmarkIdToBookmarkedEdges;
for (const StorageBookmarkedEdge& bookmarkedEdge: m_sqliteBookmarkStorage.getAllBookmarkedEdges())
{
bookmarkIdToBookmarkedEdges[bookmarkedEdge.bookmarkId].push_back(bookmarkedEdge);
}
std::vector<EdgeBookmark> edgeBookmarks;
Cache<std::string, Id> nodeIdCache([&](std::string serializedNodeName)
{
return m_sqliteIndexStorage.getNodeBySerializedName(serializedNodeName).id;
}
);
for (const StorageBookmark& storageBookmark: m_sqliteBookmarkStorage.getAllBookmarks())
{
auto itCategories = bookmarkCategories.find(storageBookmark.categoryId);
auto itBookmarkedEdges = bookmarkIdToBookmarkedEdges.find(storageBookmark.id);
if (itCategories != bookmarkCategories.end() && itBookmarkedEdges != bookmarkIdToBookmarkedEdges.end())
{
EdgeBookmark bookmark(
storageBookmark.id,
storageBookmark.name,
storageBookmark.comment,
storageBookmark.timestamp,
BookmarkCategory(itCategories->second.id, itCategories->second.name)
);
Id activeNodeId = 0;
for (const StorageBookmarkedEdge& bookmarkedEdge: itBookmarkedEdges->second)
{
const Id sourceNodeId = nodeIdCache.getValue(bookmarkedEdge.serializedSourceNodeName);
const Id targetNodeId = nodeIdCache.getValue(bookmarkedEdge.serializedTargetNodeName);
const Id edgeId =
m_sqliteIndexStorage.getEdgeBySourceTargetType(sourceNodeId, targetNodeId, bookmarkedEdge.edgeType).id;
bookmark.addEdgeId(edgeId);
if (activeNodeId == 0)
{
activeNodeId = bookmarkedEdge.sourceNodeActive ? sourceNodeId : targetNodeId;
}
}
bookmark.setActiveNodeId(activeNodeId);
bookmark.setIsValid();
edgeBookmarks.push_back(bookmark);
}
}
return edgeBookmarks;
}
std::vector<BookmarkCategory> PersistentStorage::getAllBookmarkCategories() const
{
std::vector<BookmarkCategory> categories;
for (const StorageBookmarkCategory storageBookmarkCategoriy: m_sqliteBookmarkStorage.getAllBookmarkCategories())
{
categories.push_back(BookmarkCategory(storageBookmarkCategoriy.id, storageBookmarkCategoriy.name));
}
return categories;
}
TooltipInfo PersistentStorage::getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const
{
TRACE();
TooltipInfo info;
if (!tokenIds.size())
{
return info;
}
StorageNode node = m_sqliteIndexStorage.getFirstById<StorageNode>(tokenIds[0]);
if (node.id == 0 && origin == TOOLTIP_ORIGIN_CODE)
{
StorageEdge edge = m_sqliteIndexStorage.getFirstById<StorageEdge>(tokenIds[0]);
if (edge.id > 0)
{
node = m_sqliteIndexStorage.getFirstById<StorageNode>(edge.targetNodeId);
}
}
if (node.id == 0)
{
return info;
}
Node::NodeType type = Node::intToType(node.type);
info.title = Node::getReadableTypeString(type);
DefinitionKind defKind = DEFINITION_NONE;
StorageSymbol symbol = m_sqliteIndexStorage.getFirstById<StorageSymbol>(node.id);
if (symbol.id > 0)
{
defKind = intToDefinitionKind(symbol.definitionKind);
}
if (type & Node::NODE_MEMBER_TYPE)
{
StorageComponentAccess access = m_sqliteIndexStorage.getComponentAccessByNodeId(node.id);
if (access.nodeId != 0)
{
info.title = accessKindToString(intToAccessKind(access.type)) + " " + info.title;
}
}
if (type == Node::NODE_FILE)
{
bool complete = false;
auto it = m_fileNodeComplete.find(node.id);
if (it != m_fileNodeComplete.end())
{
complete = it->second;
}
if (!complete)
{
info.title = "incomplete " + info.title;
}
}
else if (defKind == DEFINITION_NONE && type != Node::NODE_NON_INDEXED)
{
info.title = "non-indexed " + info.title;
}
else if (defKind == DEFINITION_IMPLICIT)
{
info.title = "implicit " + info.title;
}
info.count = 0;
info.countText = "reference";
for (auto edge : m_sqliteIndexStorage.getEdgesByTargetId(node.id))
{
if (Edge::intToType(edge.type) != Edge::EDGE_MEMBER)
{
info.count++;
}
}
info.snippets.push_back(getTooltipSnippetForNode(node));
if (origin == TOOLTIP_ORIGIN_CODE)
{
info.offset = Vec2i(20, 30);
}
else
{
info.offset = Vec2i(50, 20);
}
return info;
}
TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& node) const
{
TRACE();
TooltipSnippet snippet;
NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName);
snippet.code = nameHierarchy.getQualifiedNameWithSignature();
snippet.locationFile = std::make_shared<SourceLocationFile>(
FilePath(nameHierarchy.getDelimiter() == NAME_DELIMITER_JAVA ? "main.java" : "main.cpp"), true, true);
if (Node::intToType(node.type) & (Node::NODE_FUNCTION | Node::NODE_METHOD | Node::NODE_FIELD | Node::NODE_GLOBAL_VARIABLE))
{
snippet.code = utility::breakSignature(
nameHierarchy.getSignature().getPrefix(),
nameHierarchy.getQualifiedName(),
nameHierarchy.getSignature().getPostfix(),
50,
ApplicationSettings::getInstance()->getCodeTabWidth()
);
std::vector<Id> typeNodeIds;
for (auto edge : m_sqliteIndexStorage.getEdgesBySourceId(node.id))
{
if (Edge::intToType(edge.type) == Edge::EDGE_TYPE_USAGE)
{
typeNodeIds.push_back(edge.targetNodeId);
}
}
std::set<std::pair<std::string, Id>, bool(*)(const std::pair<std::string, Id>&, const std::pair<std::string, Id>&)> typeNames(
[](const std::pair<std::string, Id>& a, const std::pair<std::string, Id>& b)
{
if (a.first.size() == b.first.size())
{
return a.first < b.first;
}
return a.first.size() > b.first.size();
}
);
typeNames.insert(std::make_pair(nameHierarchy.getQualifiedName(), node.id));
for (auto typeNode : m_sqliteIndexStorage.getAllByIds<StorageNode>(typeNodeIds))
{
typeNames.insert(std::make_pair(
NameHierarchy::deserialize(typeNode.serializedName).getQualifiedName(),
typeNode.id
));
}
Id locationId = 1;
std::vector<std::pair<size_t, size_t>> locationRanges;
for (auto p : typeNames)
{
size_t pos = 0;
while (pos != std::string::npos)
{
pos = snippet.code.find(p.first, pos);
if (pos == std::string::npos)
{
continue;
}
bool inRange = false;
for (auto p : locationRanges)
{
if (pos + 1 >= p.first && pos + 1 <= p.second)
{
inRange = true;
pos = p.second + 1;
break;
}
}
if (!inRange)
{
snippet.locationFile->addSourceLocation(
LOCATION_TOKEN, locationId, std::vector<Id>(1, p.second), 1, pos + 1, 1, pos + p.first.size());
locationRanges.push_back(std::make_pair(pos + 1, pos + p.first.size()));
pos += p.first.size();
locationId++;
}
}
}
}
else
{
snippet.locationFile->addSourceLocation(
LOCATION_TOKEN, 0, std::vector<Id>(1, node.id), 1, 1, 1, snippet.code.size());
}
return snippet;
}
Id PersistentStorage::getFileNodeId(const FilePath& filePath) const
{
if (filePath.empty())
@@ -1864,17 +2052,6 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph
node->setExplicit(true);
}
if (type == Node::NODE_FUNCTION || type == Node::NODE_METHOD)
{
std::string signatureString = nameHierarchy.getRawNameWithSignature();
if (signatureString.size() > 0) // this should always be the case since functions and methods must have sigs.
{
node->addComponentSignature(
std::make_shared<TokenComponentSignature>(signatureString)
);
}
}
if (addChildCount)
{
node->setChildCount(m_hierarchyCache.getFirstNonImplicitChildIdsCountForNodeId(storageNode.id));
+16 -15
View File
@@ -30,20 +30,6 @@ public:
virtual void addComponentAccess(Id nodeId , int type);
virtual void addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
virtual void addError(const std::string& message, const FilePath& filePath, uint startLine, uint startCol, bool fatal, bool indexed);
virtual Id addNodeBookmark(const NodeBookmark& bookmark);
virtual Id addEdgeBookmark(const EdgeBookmark& bookmark);
virtual Id addBookmarkCategory(const std::string& categoryName);
void updateBookmark(const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName);
virtual void removeBookmark(const Id id);
virtual void removeBookmarkCategory(const Id id);
std::vector<NodeBookmark> getAllNodeBookmarks() const;
std::vector<EdgeBookmark> getAllEdgeBookmarks() const;
virtual std::vector<BookmarkCategory> getAllBookmarkCategories() const;
virtual void forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const;
virtual void forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const;
@@ -89,7 +75,7 @@ public:
virtual std::vector<Id> getNodeIdsForNameHierarchies(const std::vector<NameHierarchy> nameHierarchies) const;
virtual NameHierarchy getNameHierarchyForNodeId(Id nodeId) const;
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const;
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id>& nodeIds) const;
virtual Node::NodeType getNodeTypeForNodeWithId(Id nodeId) const;
@@ -138,6 +124,21 @@ public:
virtual std::vector<ErrorInfo> getErrorsLimited() const;
virtual std::shared_ptr<SourceLocationCollection> getErrorSourceLocationsLimited(std::vector<ErrorInfo>* errors) const;
virtual Id addNodeBookmark(const NodeBookmark& bookmark);
virtual Id addEdgeBookmark(const EdgeBookmark& bookmark);
virtual Id addBookmarkCategory(const std::string& categoryName);
virtual void updateBookmark(const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName);
virtual void removeBookmark(const Id id);
virtual void removeBookmarkCategory(const Id id);
virtual std::vector<NodeBookmark> getAllNodeBookmarks() const;
virtual std::vector<EdgeBookmark> getAllEdgeBookmarks() const;
virtual std::vector<BookmarkCategory> getAllBookmarkCategories() const;
virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const;
TooltipSnippet getTooltipSnippetForNode(const StorageNode& node) const;
private:
Id getFileNodeId(const FilePath& filePath) const;
std::vector<Id> getFileNodeIds(const std::vector<FilePath>& filePaths) const;
@@ -219,9 +219,10 @@ int SqliteStorage::executeStatementScalar(CppSQLite3Statement& statement, const
if (q.eof() || q.numFields() < 1)
{
char error[] = "Invalid scalar query";
throw CppSQLite3Exception(
CPPSQLITE_ERROR,
"Invalid scalar query",
error,
false
);
}
+34
View File
@@ -0,0 +1,34 @@
#ifndef TOOLTIP_INFO_H
#define TOOLTIP_INFO_H
#include <memory>
#include "utility/math/Vector2.h"
#include "utility/types.h"
class SourceLocationFile;
struct TooltipSnippet
{
std::string code;
std::shared_ptr<SourceLocationFile> locationFile;
};
struct TooltipInfo
{
bool isValid() const
{
return title.size() || snippets.size();
}
std::string title;
int count = -1;
std::string countText;
std::vector<TooltipSnippet> snippets;
Vec2i offset;
};
#endif // TOOLTIP_INFO_H
+10
View File
@@ -0,0 +1,10 @@
#ifndef TOOLTIP_ORIGIN_H
#define TOOLTIP_ORIGIN_H
enum TooltipOrigin
{
TOOLTIP_ORIGIN_GRAPH,
TOOLTIP_ORIGIN_CODE
};
#endif // TOOLTIP_ORIGIN_H