logic: Show overview of analyzed symbols after launch
* show analysed nodes as bundles in graph * ellide node names longer than 50 chars * sort nodes alphabetic in these bundles * show stats of analysis in code * error are displayed as well in overview * added keywords overview and error * project description can be set in .coatiproject file * description can include links to symbols using [symbol] syntax * updated documentation * increased toc nesting in documentation
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/messaging/MessageQueue.h"
|
||||
#include "utility/messaging/type/MessageActivateNodes.h"
|
||||
#include "utility/messaging/type/MessageShowErrors.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/scheduling/TaskScheduler.h"
|
||||
#include "utility/Version.h"
|
||||
@@ -130,14 +129,7 @@ void Application::handleMessage(MessageFinishedParsing* message)
|
||||
{
|
||||
m_project->logStats();
|
||||
|
||||
if (message->errorCount == 0)
|
||||
{
|
||||
MessageRefresh().refreshUiOnly().dispatch();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageShowErrors().dispatch();
|
||||
}
|
||||
MessageRefresh().refreshUiOnly().dispatch();
|
||||
}
|
||||
|
||||
void Application::handleMessage(MessageLoadProject* message)
|
||||
|
||||
@@ -165,6 +165,7 @@ add_files(
|
||||
data/StorageCache.cpp
|
||||
data/StorageCache.h
|
||||
data/StorageTypes.h
|
||||
data/StorageStats.h
|
||||
data/TaskCleanStorage.cpp
|
||||
data/TaskCleanStorage.h
|
||||
|
||||
@@ -210,10 +211,12 @@ add_files(
|
||||
utility/math/Vector4.h
|
||||
utility/math/VectorBase.h
|
||||
|
||||
utility/messaging/type/MessageActivateAll.h
|
||||
utility/messaging/type/MessageActivateEdge.h
|
||||
utility/messaging/type/MessageActivateFile.h
|
||||
utility/messaging/type/MessageActivateNodes.h
|
||||
utility/messaging/type/MessageActivateTokenLocations.h
|
||||
utility/messaging/type/MessageActivateTokenIds.h
|
||||
utility/messaging/type/MessageActivateTokens.h
|
||||
utility/messaging/type/MessageActivateWindow.h
|
||||
utility/messaging/type/MessageAutoRefreshChanged.h
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "utility/utility.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
#include "data/access/StorageAccess.h"
|
||||
#include "data/location/TokenLocation.h"
|
||||
@@ -12,6 +13,7 @@
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "settings/ProjectSettings.h"
|
||||
|
||||
CodeController::CodeController(StorageAccess* storageAccess)
|
||||
: m_storageAccess(storageAccess)
|
||||
@@ -24,6 +26,63 @@ CodeController::~CodeController()
|
||||
|
||||
const uint CodeController::s_lineRadius = 2;
|
||||
|
||||
void CodeController::handleMessage(MessageActivateAll* message)
|
||||
{
|
||||
std::vector<std::string> errorMessages;
|
||||
std::vector<CodeView::CodeSnippetParams> snippets = getSnippetsForErrorLocations(&errorMessages);
|
||||
|
||||
StorageStats stats = m_storageAccess->getStorageStats();
|
||||
CodeView::CodeSnippetParams statsSnippet;
|
||||
|
||||
statsSnippet.startLineNumber = 1;
|
||||
statsSnippet.endLineNumber = 1;
|
||||
|
||||
statsSnippet.locationFile = std::make_shared<TokenLocationFile>(FilePath());
|
||||
statsSnippet.locationFile->isWholeCopy = true;
|
||||
|
||||
std::vector<std::string> description = getProjectDescription(statsSnippet.locationFile.get());
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "\n";
|
||||
ss << "\t" + ProjectSettings::getInstance()->getFilePath().withoutExtension().fileName() + "\n";
|
||||
|
||||
if (description.size())
|
||||
{
|
||||
ss << "\n";
|
||||
for (const std::string& line : description)
|
||||
{
|
||||
ss << line + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
ss << "\n";
|
||||
ss << "\t" + std::to_string(stats.fileCount) + " files\n";
|
||||
ss << "\t" + std::to_string(stats.fileLOCCount) + " lines of code\n";
|
||||
ss << "\n";
|
||||
ss << "\t" + std::to_string(stats.nodeCount) + " symbols\n";
|
||||
ss << "\t" + std::to_string(stats.edgeCount) + " relations\n";
|
||||
ss << "\n";
|
||||
ss << "\t" + std::to_string(stats.errorCount) + " errors\n";
|
||||
ss << "\n";
|
||||
|
||||
if (stats.errorCount > 0)
|
||||
{
|
||||
ss << "\tWarning: The analysis may be incomplete as long as it yields errors.\n";
|
||||
ss << "\tTry resolving them and refresh the project.\n";
|
||||
ss << "\n";
|
||||
}
|
||||
|
||||
statsSnippet.code = ss.str();
|
||||
|
||||
snippets.insert(snippets.begin(), statsSnippet);
|
||||
|
||||
CodeView* view = getView();
|
||||
view->setActiveTokenIds(std::vector<Id>());
|
||||
view->setErrorMessages(errorMessages);
|
||||
view->showCodeSnippets(snippets);
|
||||
}
|
||||
|
||||
void CodeController::handleMessage(MessageActivateTokens* message)
|
||||
{
|
||||
if (message->keepContent() && message->isIgnorable())
|
||||
@@ -92,17 +151,7 @@ void CodeController::handleMessage(MessageFocusOut* message)
|
||||
void CodeController::handleMessage(MessageShowErrors* message)
|
||||
{
|
||||
std::vector<std::string> errorMessages;
|
||||
TokenLocationCollection errorCollection = m_storageAccess->getErrorTokenLocations(&errorMessages);
|
||||
|
||||
std::vector<CodeView::CodeSnippetParams> snippets;
|
||||
|
||||
errorCollection.forEachTokenLocationFile(
|
||||
[&](std::shared_ptr<TokenLocationFile> file) -> void
|
||||
{
|
||||
std::vector<CodeView::CodeSnippetParams> fileSnippets = getSnippetsForFile(file);
|
||||
snippets.insert(snippets.end(), fileSnippets.begin(), fileSnippets.end());
|
||||
}
|
||||
);
|
||||
std::vector<CodeView::CodeSnippetParams> snippets = getSnippetsForErrorLocations(&errorMessages);
|
||||
|
||||
CodeView* view = getView();
|
||||
view->setActiveTokenIds(std::vector<Id>());
|
||||
@@ -357,3 +406,72 @@ std::shared_ptr<SnippetMerger> CodeController::buildMergerHierarchy(
|
||||
nextMerger->addChild(currentMerger);
|
||||
return currentMerger;
|
||||
}
|
||||
|
||||
std::vector<CodeView::CodeSnippetParams> CodeController::getSnippetsForErrorLocations(
|
||||
std::vector<std::string>* errorMessages)
|
||||
const {
|
||||
TokenLocationCollection errorCollection = m_storageAccess->getErrorTokenLocations(errorMessages);
|
||||
|
||||
std::vector<CodeView::CodeSnippetParams> snippets;
|
||||
|
||||
errorCollection.forEachTokenLocationFile(
|
||||
[&](std::shared_ptr<TokenLocationFile> file) -> void
|
||||
{
|
||||
std::vector<CodeView::CodeSnippetParams> fileSnippets = getSnippetsForFile(file);
|
||||
snippets.insert(snippets.end(), fileSnippets.begin(), fileSnippets.end());
|
||||
}
|
||||
);
|
||||
|
||||
return snippets;
|
||||
}
|
||||
|
||||
std::vector<std::string> CodeController::getProjectDescription(TokenLocationFile* locationFile) const
|
||||
{
|
||||
std::string description = ProjectSettings::getInstance()->getDescription();
|
||||
|
||||
if (!description.size())
|
||||
{
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> lines = utility::splitToVector(description, "\\n");
|
||||
size_t startLineNumber = 4;
|
||||
|
||||
for (size_t i = 0; i < lines.size(); i++)
|
||||
{
|
||||
std::string line = "\t" + lines[i];
|
||||
|
||||
size_t pos = 0;
|
||||
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
size_t posA = line.find('[', pos);
|
||||
size_t posB = line.find(']', posA);
|
||||
|
||||
if (posA == std::string::npos || posB == std::string::npos)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
std::string tokenName = line.substr(posA + 1, posB - posA - 1);
|
||||
|
||||
Id tokenId = m_storageAccess->getIdForNodeWithSearchNameHierarchy(NameHierarchy(tokenName));
|
||||
|
||||
if (tokenId > 0)
|
||||
{
|
||||
line.replace(posA, posB - posA + 1, tokenName);
|
||||
locationFile->addTokenLocation(
|
||||
0, tokenId,
|
||||
startLineNumber + i, posA + 1,
|
||||
startLineNumber + i, posA + tokenName.size()
|
||||
);
|
||||
}
|
||||
|
||||
pos = posA + tokenName.size();
|
||||
}
|
||||
|
||||
lines[i] = line;
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageActivateAll.h"
|
||||
#include "utility/messaging/type/MessageActivateTokens.h"
|
||||
#include "utility/messaging/type/MessageFocusIn.h"
|
||||
#include "utility/messaging/type/MessageFocusOut.h"
|
||||
@@ -24,6 +25,7 @@ class TokenLocationFile;
|
||||
|
||||
class CodeController
|
||||
: public Controller
|
||||
, public MessageListener<MessageActivateAll>
|
||||
, public MessageListener<MessageActivateTokens>
|
||||
, public MessageListener<MessageFocusIn>
|
||||
, public MessageListener<MessageFocusOut>
|
||||
@@ -39,6 +41,7 @@ public:
|
||||
private:
|
||||
static const uint s_lineRadius;
|
||||
|
||||
virtual void handleMessage(MessageActivateAll* message);
|
||||
virtual void handleMessage(MessageActivateTokens* message);
|
||||
virtual void handleMessage(MessageFocusIn* message);
|
||||
virtual void handleMessage(MessageFocusOut* message);
|
||||
@@ -57,6 +60,10 @@ private:
|
||||
std::shared_ptr<SnippetMerger> buildMergerHierarchy(
|
||||
TokenLocation* location, SnippetMerger& fileScopedMerger, std::map<int, std::shared_ptr<SnippetMerger>>& mergers) const;
|
||||
|
||||
std::vector<CodeView::CodeSnippetParams> getSnippetsForErrorLocations(std::vector<std::string>* errorMessages) const;
|
||||
|
||||
std::vector<std::string> getProjectDescription(TokenLocationFile* locationFile) const;
|
||||
|
||||
StorageAccess* m_storageAccess;
|
||||
};
|
||||
|
||||
|
||||
@@ -53,6 +53,15 @@ void FeatureController::handleMessage(MessageSearch* message)
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureController::handleMessage(MessageActivateTokenIds* message)
|
||||
{
|
||||
std::shared_ptr<MessageActivateTokens> m = m_activationTranslator.translateMessage(message);
|
||||
if (m)
|
||||
{
|
||||
m->dispatchImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureController::handleMessage(MessageActivateTokenLocations* message)
|
||||
{
|
||||
std::vector<Id> nodeIds = m_storageAccess->getNodeIdsForLocationIds(message->locationIds);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "utility/messaging/type/MessageActivateEdge.h"
|
||||
#include "utility/messaging/type/MessageActivateFile.h"
|
||||
#include "utility/messaging/type/MessageActivateNodes.h"
|
||||
#include "utility/messaging/type/MessageActivateTokenIds.h"
|
||||
#include "utility/messaging/type/MessageActivateTokenLocations.h"
|
||||
#include "utility/messaging/type/MessageResetZoom.h"
|
||||
#include "utility/messaging/type/MessageSearch.h"
|
||||
@@ -23,6 +24,7 @@ class FeatureController
|
||||
, public MessageListener<MessageActivateEdge>
|
||||
, public MessageListener<MessageActivateFile>
|
||||
, public MessageListener<MessageActivateNodes>
|
||||
, public MessageListener<MessageActivateTokenIds>
|
||||
, public MessageListener<MessageActivateTokenLocations>
|
||||
, public MessageListener<MessageResetZoom>
|
||||
, public MessageListener<MessageSearch>
|
||||
@@ -38,6 +40,7 @@ private:
|
||||
virtual void handleMessage(MessageActivateFile* message);
|
||||
virtual void handleMessage(MessageActivateNodes* message);
|
||||
virtual void handleMessage(MessageSearch* message);
|
||||
virtual void handleMessage(MessageActivateTokenIds* message);
|
||||
virtual void handleMessage(MessageActivateTokenLocations* message);
|
||||
virtual void handleMessage(MessageResetZoom* message);
|
||||
virtual void handleMessage(MessageSwitchColorScheme* message);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utility.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
#include "component/controller/helper/DummyEdge.h"
|
||||
#include "component/controller/helper/DummyNode.h"
|
||||
@@ -23,6 +24,21 @@ GraphController::~GraphController()
|
||||
{
|
||||
}
|
||||
|
||||
void GraphController::handleMessage(MessageActivateAll* message)
|
||||
{
|
||||
m_activeNodeIds.clear();
|
||||
m_activeEdgeIds.clear();
|
||||
|
||||
createDummyGraphForTokenIds(std::vector<Id>(), m_storageAccess->getGraphForAll());
|
||||
|
||||
bundleNodesByType();
|
||||
|
||||
layoutNesting();
|
||||
layoutGraph();
|
||||
|
||||
buildGraph(message);
|
||||
}
|
||||
|
||||
void GraphController::handleMessage(MessageActivateTokens* message)
|
||||
{
|
||||
if (message->isEdge || message->keepContent())
|
||||
@@ -49,7 +65,16 @@ void GraphController::handleMessage(MessageActivateTokens* message)
|
||||
return;
|
||||
}
|
||||
|
||||
createDummyGraphForTokenIds(utility::concat(m_activeNodeIds, m_activeEdgeIds));
|
||||
std::vector<Id> tokenIds = utility::concat(m_activeNodeIds, m_activeEdgeIds);
|
||||
|
||||
std::shared_ptr<Graph> graph = m_storageAccess->getGraphForActiveTokenIds(tokenIds);
|
||||
|
||||
createDummyGraphForTokenIds(tokenIds, graph);
|
||||
|
||||
bundleNodes();
|
||||
|
||||
layoutNesting();
|
||||
layoutGraph();
|
||||
|
||||
buildGraph(message);
|
||||
}
|
||||
@@ -76,7 +101,7 @@ void GraphController::handleMessage(MessageGraphNodeBundleSplit* message)
|
||||
DummyNode& node = m_dummyNodes[i];
|
||||
if (node.isBundleNode() && node.tokenId == message->bundleId)
|
||||
{
|
||||
m_dummyNodes.insert(m_dummyNodes.end(), node.bundledNodes.begin(), node.bundledNodes.end());
|
||||
m_dummyNodes.insert(m_dummyNodes.begin() + i + 1, node.bundledNodes.begin(), node.bundledNodes.end());
|
||||
m_dummyNodes.erase(m_dummyNodes.begin() + i);
|
||||
break;
|
||||
}
|
||||
@@ -156,7 +181,7 @@ void GraphController::clear()
|
||||
getView()->clear();
|
||||
}
|
||||
|
||||
void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenIds)
|
||||
void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenIds, const std::shared_ptr<Graph> graph)
|
||||
{
|
||||
GraphView* view = getView();
|
||||
if (!view)
|
||||
@@ -165,8 +190,6 @@ void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenId
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> graph = m_storageAccess->getGraphForActiveTokenIds(tokenIds);
|
||||
|
||||
m_dummyEdges.clear();
|
||||
|
||||
std::set<Id> addedNodes;
|
||||
@@ -190,6 +213,7 @@ void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenId
|
||||
for (DummyNode& node : dummyNodes)
|
||||
{
|
||||
node.hasParent = false;
|
||||
node.name = node.data->getFullName();
|
||||
}
|
||||
|
||||
m_dummyNodes = dummyNodes;
|
||||
@@ -197,11 +221,6 @@ void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenId
|
||||
autoExpandActiveNode(tokenIds);
|
||||
setActiveAndVisibility(tokenIds);
|
||||
|
||||
bundleNodes();
|
||||
|
||||
layoutNesting();
|
||||
layoutGraph();
|
||||
|
||||
m_graph = graph;
|
||||
}
|
||||
|
||||
@@ -210,6 +229,7 @@ DummyNode GraphController::createDummyNodeTopDown(Node* node)
|
||||
DummyNode result;
|
||||
result.data = node;
|
||||
result.tokenId = node->getId();
|
||||
result.name = node->getName();
|
||||
|
||||
// there is a global root node with id 0 afaik, so here we actually want the one node below this global root
|
||||
Node* parent = node;
|
||||
@@ -314,6 +334,8 @@ void GraphController::autoExpandActiveNode(const std::vector<Id>& activeTokenIds
|
||||
|
||||
void GraphController::setActiveAndVisibility(const std::vector<Id>& activeTokenIds)
|
||||
{
|
||||
bool noActive = activeTokenIds.size() == 0;
|
||||
|
||||
for (DummyNode& node : m_dummyNodes)
|
||||
{
|
||||
setNodeActiveRecursive(node, activeTokenIds);
|
||||
@@ -335,7 +357,7 @@ void GraphController::setActiveAndVisibility(const std::vector<Id>& activeTokenI
|
||||
DummyNode* from = findDummyNodeRecursive(m_dummyNodes, edge.ownerId);
|
||||
DummyNode* to = findDummyNodeRecursive(m_dummyNodes, edge.targetId);
|
||||
|
||||
if (from && to && (from->active || to->active || edge.active))
|
||||
if (from && to && (noActive || from->active || to->active || edge.active))
|
||||
{
|
||||
edge.visible = true;
|
||||
from->connected = true;
|
||||
@@ -345,7 +367,7 @@ void GraphController::setActiveAndVisibility(const std::vector<Id>& activeTokenI
|
||||
|
||||
for (DummyNode& node : m_dummyNodes)
|
||||
{
|
||||
setNodeVisibilityRecursiveBottomUp(node);
|
||||
setNodeVisibilityRecursiveBottomUp(node, noActive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +386,7 @@ void GraphController::setNodeActiveRecursive(DummyNode& node, const std::vector<
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphController::setNodeVisibilityRecursiveBottomUp(DummyNode& node) const
|
||||
bool GraphController::setNodeVisibilityRecursiveBottomUp(DummyNode& node, bool noActive) const
|
||||
{
|
||||
node.visible = false;
|
||||
node.childVisible = false;
|
||||
@@ -382,13 +404,13 @@ bool GraphController::setNodeVisibilityRecursiveBottomUp(DummyNode& node) const
|
||||
|
||||
for (DummyNode& subNode : node.subNodes)
|
||||
{
|
||||
if (setNodeVisibilityRecursiveBottomUp(subNode))
|
||||
if (setNodeVisibilityRecursiveBottomUp(subNode, noActive))
|
||||
{
|
||||
node.childVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.active || node.connected || node.childVisible)
|
||||
if (noActive || node.active || node.connected || node.childVisible)
|
||||
{
|
||||
setNodeVisibilityRecursiveTopDown(node, false);
|
||||
}
|
||||
@@ -617,6 +639,54 @@ bool GraphController::isTypeNodeWithSingleInheritance(const DummyNode& node, boo
|
||||
return matches;
|
||||
}
|
||||
|
||||
#define BUNDLE_BY_TYPE(__type__, __name__) \
|
||||
bundleNodesMatching( \
|
||||
[&](const DummyNode& node) \
|
||||
{ \
|
||||
return node.visible && node.isGraphNode() && node.data->isType(__type__); \
|
||||
}, \
|
||||
1, \
|
||||
__name__ \
|
||||
); \
|
||||
|
||||
void GraphController::bundleNodesByType()
|
||||
{
|
||||
BUNDLE_BY_TYPE(Node::NODE_CLASS, "Classes");
|
||||
BUNDLE_BY_TYPE(Node::NODE_STRUCT, "Structs");
|
||||
|
||||
BUNDLE_BY_TYPE(Node::NODE_FUNCTION, "Functions");
|
||||
BUNDLE_BY_TYPE(Node::NODE_GLOBAL_VARIABLE, "Global Variables");
|
||||
|
||||
BUNDLE_BY_TYPE(Node::NODE_TYPE, "Types");
|
||||
BUNDLE_BY_TYPE(Node::NODE_TYPEDEF, "Typedefs");
|
||||
BUNDLE_BY_TYPE(Node::NODE_ENUM, "Enums");
|
||||
|
||||
BUNDLE_BY_TYPE(Node::NODE_FILE, "Files");
|
||||
BUNDLE_BY_TYPE(Node::NODE_MACRO, "Macros");
|
||||
|
||||
// should never be visible
|
||||
|
||||
BUNDLE_BY_TYPE(Node::NODE_METHOD, "Methods");
|
||||
BUNDLE_BY_TYPE(Node::NODE_FIELD, "Fields");
|
||||
BUNDLE_BY_TYPE(Node::NODE_ENUM_CONSTANT, "Enum Constants");
|
||||
BUNDLE_BY_TYPE(Node::NODE_TEMPLATE_PARAMETER_TYPE, "Template Parameter Types");
|
||||
BUNDLE_BY_TYPE(Node::NODE_UNDEFINED, "Undefined Symbols");
|
||||
BUNDLE_BY_TYPE(Node::NODE_NAMESPACE, "Namespaces");
|
||||
|
||||
for (DummyNode& node : m_dummyNodes)
|
||||
{
|
||||
if (node.isBundleNode())
|
||||
{
|
||||
sort(node.bundledNodes.begin(), node.bundledNodes.end(),
|
||||
[](const DummyNode& a, const DummyNode& b) -> bool
|
||||
{
|
||||
return utility::toLowerCase(a.name) < utility::toLowerCase(b.name);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphController::layoutNesting()
|
||||
{
|
||||
for (DummyNode& node : m_dummyNodes)
|
||||
@@ -663,15 +733,14 @@ void GraphController::layoutNestingRecursive(DummyNode& node) const
|
||||
|
||||
if (node.isGraphNode())
|
||||
{
|
||||
if (!node.hasParent)
|
||||
size_t maxNameSize = 50;
|
||||
if (!node.active && node.name.size() > maxNameSize)
|
||||
{
|
||||
width = margins.charWidth * node.data->getFullName().size();
|
||||
}
|
||||
else
|
||||
{
|
||||
width = margins.charWidth * node.data->getName().size();
|
||||
node.name = node.name.substr(0, maxNameSize - 3) + "...";
|
||||
}
|
||||
|
||||
width = margins.charWidth * node.name.size();
|
||||
|
||||
if (node.data->isType(Node::NODE_TYPE | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM) && node.subNodes.size())
|
||||
{
|
||||
addExpandToggleNode(node);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageActivateAll.h"
|
||||
#include "utility/messaging/type/MessageActivateTokens.h"
|
||||
#include "utility/messaging/type/MessageFlushUpdates.h"
|
||||
#include "utility/messaging/type/MessageFocusIn.h"
|
||||
@@ -26,6 +27,7 @@ class StorageAccess;
|
||||
|
||||
class GraphController
|
||||
: public Controller
|
||||
, public MessageListener<MessageActivateAll>
|
||||
, public MessageListener<MessageActivateTokens>
|
||||
, public MessageListener<MessageFlushUpdates>
|
||||
, public MessageListener<MessageFocusIn>
|
||||
@@ -40,6 +42,7 @@ public:
|
||||
~GraphController();
|
||||
|
||||
private:
|
||||
virtual void handleMessage(MessageActivateAll* message);
|
||||
virtual void handleMessage(MessageActivateTokens* message);
|
||||
virtual void handleMessage(MessageFlushUpdates* message);
|
||||
virtual void handleMessage(MessageFocusIn* message);
|
||||
@@ -53,20 +56,21 @@ private:
|
||||
|
||||
void clear();
|
||||
|
||||
void createDummyGraphForTokenIds(const std::vector<Id>& tokenIds);
|
||||
void createDummyGraphForTokenIds(const std::vector<Id>& tokenIds, const std::shared_ptr<Graph> graph);
|
||||
DummyNode createDummyNodeTopDown(Node* node);
|
||||
|
||||
void autoExpandActiveNode(const std::vector<Id>& activeTokenIds);
|
||||
|
||||
void setActiveAndVisibility(const std::vector<Id>& activeTokenIds);
|
||||
void setNodeActiveRecursive(DummyNode& node, const std::vector<Id>& activeTokenIds) const;
|
||||
bool setNodeVisibilityRecursiveBottomUp(DummyNode& node) const;
|
||||
bool setNodeVisibilityRecursiveBottomUp(DummyNode& node, bool noActive) const;
|
||||
void setNodeVisibilityRecursiveTopDown(DummyNode& node, bool parentExpanded) const;
|
||||
|
||||
void bundleNodes();
|
||||
void bundleNodesMatching(std::function<bool(const DummyNode&)> matcher, size_t count, const std::string& name);
|
||||
bool isTypeNodeWithSingleAggregation(const DummyNode& node, TokenComponentAggregation::Direction direction) const;
|
||||
bool isTypeNodeWithSingleInheritance(const DummyNode& node, bool isBase) const;
|
||||
void bundleNodesByType();
|
||||
|
||||
void layoutNesting();
|
||||
void layoutNestingRecursive(DummyNode& node) const;
|
||||
|
||||
@@ -12,6 +12,12 @@ SearchController::~SearchController()
|
||||
{
|
||||
}
|
||||
|
||||
void SearchController::handleMessage(MessageActivateAll* message)
|
||||
{
|
||||
SearchMatch match = SearchMatch::createCommand(SearchMatch::COMMAND_ALL);
|
||||
getView()->setMatches(std::vector<SearchMatch>(1, match));
|
||||
}
|
||||
|
||||
void SearchController::handleMessage(MessageActivateTokens* message)
|
||||
{
|
||||
if (!message->keepContent() && !message->isFromSearch)
|
||||
@@ -33,7 +39,8 @@ void SearchController::handleMessage(MessageSearchAutocomplete* message)
|
||||
|
||||
void SearchController::handleMessage(MessageShowErrors* message)
|
||||
{
|
||||
getView()->setMatches(std::vector<SearchMatch>());
|
||||
SearchMatch match = SearchMatch::createCommand(SearchMatch::COMMAND_ERROR);
|
||||
getView()->setMatches(std::vector<SearchMatch>(1, match));
|
||||
}
|
||||
|
||||
SearchView* SearchController::getView()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "component/controller/Controller.h"
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageActivateAll.h"
|
||||
#include "utility/messaging/type/MessageActivateTokens.h"
|
||||
#include "utility/messaging/type/MessageFind.h"
|
||||
#include "utility/messaging/type/MessageSearchAutocomplete.h"
|
||||
@@ -13,6 +14,7 @@ class SearchView;
|
||||
|
||||
class SearchController
|
||||
: public Controller
|
||||
, public MessageListener<MessageActivateAll>
|
||||
, public MessageListener<MessageActivateTokens>
|
||||
, public MessageListener<MessageFind>
|
||||
, public MessageListener<MessageSearchAutocomplete>
|
||||
@@ -23,6 +25,7 @@ public:
|
||||
~SearchController();
|
||||
|
||||
private:
|
||||
virtual void handleMessage(MessageActivateAll* message);
|
||||
virtual void handleMessage(MessageActivateTokens* message);
|
||||
virtual void handleMessage(MessageFind* message);
|
||||
virtual void handleMessage(MessageSearchAutocomplete* message);
|
||||
|
||||
@@ -67,6 +67,18 @@ void UndoRedoController::handleMessage(MessageActivateNodes* message)
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void UndoRedoController::handleMessage(MessageActivateTokenIds* message)
|
||||
{
|
||||
if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() && message->tokenIds.size() &&
|
||||
static_cast<MessageActivateTokenIds*>(m_lastCommand.message.get())->tokenIds == message->tokenIds)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Command command(std::make_shared<MessageActivateTokenIds>(*message), 0);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void UndoRedoController::handleMessage(MessageDeactivateEdge* message)
|
||||
{
|
||||
MessageBase* m = nullptr;
|
||||
@@ -140,23 +152,9 @@ void UndoRedoController::handleMessage(MessageRefresh* message)
|
||||
|
||||
if (requiresActivateFallbackToken())
|
||||
{
|
||||
Id nodeId = m_storageAccess->getIdForNodeWithSearchNameHierarchy(NameHierarchy("main"));
|
||||
if (!nodeId)
|
||||
{
|
||||
nodeId = m_storageAccess->getIdForFirstNode();
|
||||
}
|
||||
|
||||
if (nodeId)
|
||||
{
|
||||
MessageActivateNodes m;
|
||||
m.addNode(
|
||||
nodeId,
|
||||
m_storageAccess->getNodeTypeForNodeWithId(nodeId),
|
||||
m_storageAccess->getNameHierarchyForNodeWithId(nodeId)
|
||||
);
|
||||
m.isFromSystem = true;
|
||||
m.dispatch();
|
||||
}
|
||||
SearchMatch match = SearchMatch::createCommand(SearchMatch::COMMAND_ALL);
|
||||
MessageSearch msg(std::vector<SearchMatch>(1, match));
|
||||
msg.dispatch();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "utility/messaging/type/MessageActivateEdge.h"
|
||||
#include "utility/messaging/type/MessageActivateFile.h"
|
||||
#include "utility/messaging/type/MessageActivateNodes.h"
|
||||
#include "utility/messaging/type/MessageActivateTokenIds.h"
|
||||
#include "utility/messaging/type/MessageDeactivateEdge.h"
|
||||
#include "utility/messaging/type/MessageGraphNodeBundleSplit.h"
|
||||
#include "utility/messaging/type/MessageGraphNodeExpand.h"
|
||||
@@ -32,6 +33,7 @@ class UndoRedoController
|
||||
, public MessageListener<MessageActivateEdge>
|
||||
, public MessageListener<MessageActivateFile>
|
||||
, public MessageListener<MessageActivateNodes>
|
||||
, public MessageListener<MessageActivateTokenIds>
|
||||
, public MessageListener<MessageDeactivateEdge>
|
||||
, public MessageListener<MessageGraphNodeBundleSplit>
|
||||
, public MessageListener<MessageGraphNodeExpand>
|
||||
@@ -63,6 +65,7 @@ private:
|
||||
virtual void handleMessage(MessageActivateEdge* message);
|
||||
virtual void handleMessage(MessageActivateFile* message);
|
||||
virtual void handleMessage(MessageActivateNodes* message);
|
||||
virtual void handleMessage(MessageActivateTokenIds* message);
|
||||
virtual void handleMessage(MessageDeactivateEdge* message);
|
||||
virtual void handleMessage(MessageGraphNodeBundleSplit* message);
|
||||
virtual void handleMessage(MessageGraphNodeExpand* message);
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "component/controller/helper/ActivationTranslator.h"
|
||||
|
||||
#include "data/access/StorageAccess.h"
|
||||
#include "utility/messaging/type/MessageActivateAll.h"
|
||||
#include "utility/messaging/type/MessageActivateEdge.h"
|
||||
#include "utility/messaging/type/MessageActivateFile.h"
|
||||
#include "utility/messaging/type/MessageActivateNodes.h"
|
||||
#include "utility/messaging/type/MessageActivateTokenIds.h"
|
||||
#include "utility/messaging/type/MessageActivateTokens.h"
|
||||
#include "utility/messaging/type/MessageSearch.h"
|
||||
#include "utility/messaging/type/MessageShowErrors.h"
|
||||
#include "utility/messaging/type/MessageShowFile.h"
|
||||
|
||||
ActivationTranslator::ActivationTranslator(StorageAccess* storageAccess)
|
||||
@@ -99,9 +102,40 @@ std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(co
|
||||
return m;
|
||||
}
|
||||
|
||||
std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(const MessageActivateTokenIds* message) const
|
||||
{
|
||||
std::shared_ptr<MessageActivateTokens> m;
|
||||
m = std::make_shared<MessageActivateTokens>(message->tokenIds);
|
||||
m->undoRedoType = message->undoRedoType;
|
||||
m->setKeepContent(message->keepContent());
|
||||
return m;
|
||||
}
|
||||
|
||||
std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(const MessageSearch* message) const
|
||||
{
|
||||
std::vector<Id> tokenIds = m_storageAccess->getTokenIdsForMatches(message->getMatches());
|
||||
const std::vector<SearchMatch>& matches = message->getMatches();
|
||||
|
||||
for (const SearchMatch& match : matches)
|
||||
{
|
||||
if (match.searchType == SearchMatch::SEARCH_COMMAND &&
|
||||
match.getFullName() == SearchMatch::getCommandName(SearchMatch::COMMAND_ALL))
|
||||
{
|
||||
MessageActivateAll msg;
|
||||
msg.undoRedoType = message->undoRedoType;
|
||||
msg.dispatchImmediately();
|
||||
return nullptr;
|
||||
}
|
||||
else if (match.searchType == SearchMatch::SEARCH_COMMAND &&
|
||||
match.getFullName() == SearchMatch::getCommandName(SearchMatch::COMMAND_ERROR))
|
||||
{
|
||||
MessageShowErrors msg;
|
||||
msg.undoRedoType = message->undoRedoType;
|
||||
msg.dispatchImmediately();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Id> tokenIds = m_storageAccess->getTokenIdsForMatches(matches);
|
||||
tokenIds = m_storageAccess->getActiveTokenIdsForTokenIds(tokenIds);
|
||||
|
||||
std::shared_ptr<MessageActivateTokens> m;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
class MessageActivateEdge;
|
||||
class MessageActivateFile;
|
||||
class MessageActivateNodes;
|
||||
class MessageActivateTokenIds;
|
||||
class MessageActivateTokens;
|
||||
class MessageSearch;
|
||||
class StorageAccess;
|
||||
@@ -19,6 +20,7 @@ public:
|
||||
std::shared_ptr<MessageActivateTokens> translateMessage(const MessageActivateEdge* message) const;
|
||||
std::shared_ptr<MessageActivateTokens> translateMessage(const MessageActivateFile* message) const;
|
||||
std::shared_ptr<MessageActivateTokens> translateMessage(const MessageActivateNodes* message) const;
|
||||
std::shared_ptr<MessageActivateTokens> translateMessage(const MessageActivateTokenIds* message) const;
|
||||
std::shared_ptr<MessageActivateTokens> translateMessage(const MessageSearch* message) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -126,13 +126,18 @@ void BucketGrid::createBuckets(std::vector<DummyNode>& nodes, const std::vector<
|
||||
bool activeNodeAdded = false;
|
||||
for (DummyNode& node : nodes)
|
||||
{
|
||||
if (node.hasActiveSubNode())
|
||||
if (node.hasActiveSubNode() || !edges.size())
|
||||
{
|
||||
addNode(&node);
|
||||
activeNodeAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!edges.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activeNodeAdded)
|
||||
{
|
||||
addNode(&nodes[0]);
|
||||
|
||||
@@ -114,6 +114,8 @@ public:
|
||||
|
||||
// GraphNode
|
||||
const Node* data;
|
||||
std::string name;
|
||||
|
||||
bool active;
|
||||
bool connected;
|
||||
bool expanded;
|
||||
@@ -127,7 +129,6 @@ public:
|
||||
|
||||
// BundleNode
|
||||
std::vector<DummyNode> bundledNodes;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
#endif // DUMMY_NODE_H
|
||||
|
||||
@@ -135,6 +135,27 @@ void HierarchyCache::addFirstVisibleChildIdsForNodeId(Id nodeId, std::vector<Id>
|
||||
}
|
||||
}
|
||||
|
||||
bool HierarchyCache::isChildOfVisibleNodeOrInvisible(Id nodeId) const
|
||||
{
|
||||
HierarchyNode* node = getNode(nodeId);
|
||||
if (!node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!node->isVisible())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node->getParent() && node->getParent()->isVisible())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
HierarchyCache::HierarchyNode* HierarchyCache::getNode(Id nodeId) const
|
||||
{
|
||||
std::map<Id, std::shared_ptr<HierarchyNode>>::const_iterator it = m_nodes.find(nodeId);
|
||||
|
||||
@@ -19,6 +19,8 @@ public:
|
||||
void addAllChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds, std::vector<Id>* edgeIds) const;
|
||||
void addFirstVisibleChildIdsForNodeId(Id nodeId, std::vector<Id>* nodeIds) const;
|
||||
|
||||
bool isChildOfVisibleNodeOrInvisible(Id nodeId) const;
|
||||
|
||||
private:
|
||||
class HierarchyNode
|
||||
{
|
||||
|
||||
@@ -119,10 +119,11 @@ Id SqliteStorage::addFile(const std::string& serializedName, const std::string&
|
||||
{
|
||||
Id id = addNode(Node::NODE_FILE, serializedName, true);
|
||||
std::shared_ptr<TextAccess> content = TextAccess::createFromFile(filePath);
|
||||
unsigned int loc = content->getLineCount();
|
||||
|
||||
CppSQLite3Statement stmt = m_database.compileStatement((
|
||||
"INSERT INTO file(id, path, modification_time, content) VALUES("
|
||||
+ std::to_string(id) + ", '" + filePath + "', '" + modificationTime + "', ?);"
|
||||
"INSERT INTO file(id, path, modification_time, content, loc) VALUES("
|
||||
+ std::to_string(id) + ", '" + filePath + "', '" + modificationTime + "', ?, " + std::to_string(loc) + ");"
|
||||
).c_str());
|
||||
|
||||
stmt.bind(1, content->getText().c_str());
|
||||
@@ -653,6 +654,11 @@ int SqliteStorage::getFileCount() const
|
||||
return m_database.execScalar("SELECT COUNT(*) FROM file;");
|
||||
}
|
||||
|
||||
int SqliteStorage::getFileLOCCount() const
|
||||
{
|
||||
return m_database.execScalar("SELECT SUM(loc) FROM file;");
|
||||
}
|
||||
|
||||
int SqliteStorage::getSourceLocationCount() const
|
||||
{
|
||||
return m_database.execScalar("SELECT COUNT(*) FROM source_location;");
|
||||
@@ -719,6 +725,7 @@ void SqliteStorage::setupTables()
|
||||
"path TEXT, "
|
||||
"modification_time TEXT, "
|
||||
"content TEXT, "
|
||||
"loc INTEGER, "
|
||||
"PRIMARY KEY(id), "
|
||||
"FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE);"
|
||||
);
|
||||
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
int getNodeCount() const;
|
||||
int getEdgeCount() const;
|
||||
int getFileCount() const;
|
||||
int getFileLOCCount() const;
|
||||
int getSourceLocationCount() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -40,6 +40,9 @@ Version Storage::getVersion() const
|
||||
|
||||
bool Storage::init()
|
||||
{
|
||||
m_commandIndex.addNode(NameHierarchy(SearchMatch::getCommandName(SearchMatch::COMMAND_ALL)));
|
||||
m_commandIndex.addNode(NameHierarchy(SearchMatch::getCommandName(SearchMatch::COMMAND_ERROR)));
|
||||
|
||||
return m_sqliteStorage.init();
|
||||
}
|
||||
|
||||
@@ -141,19 +144,21 @@ const SearchIndex& Storage::getSearchIndex() const
|
||||
void Storage::logStats() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
StorageStats stats = getStorageStats();
|
||||
|
||||
ss << "\nGraph:\n";
|
||||
ss << "\t" << m_sqliteStorage.getNodeCount() << " Nodes\n";
|
||||
ss << "\t" << m_sqliteStorage.getEdgeCount() << " Edges\n";
|
||||
ss << "\t" << stats.nodeCount << " Nodes\n";
|
||||
ss << "\t" << stats.edgeCount << " Edges\n";
|
||||
|
||||
ss << "\nSearch:\n";
|
||||
ss << "\t" << m_tokenIndex.getCharCount() << " Characters\n";
|
||||
ss << "\t" << m_tokenIndex.getWordCount() << " Words\n";
|
||||
ss << "\t" << m_tokenIndex.getNodeCount() << " SearchNodes\n";
|
||||
ss << "\t" << stats.charCount << " Characters\n";
|
||||
ss << "\t" << stats.wordCount << " Words\n";
|
||||
ss << "\t" << stats.searchNodeCount << " SearchNodes\n";
|
||||
|
||||
ss << "\nCode:\n";
|
||||
ss << "\t" << m_sqliteStorage.getFileCount() << " Files\n";
|
||||
ss << "\t" << m_sqliteStorage.getSourceLocationCount() << " Source Locations\n";
|
||||
ss << "\t" << stats.fileCount << " Files\n";
|
||||
ss << "\t" << stats.fileLOCCount << " Lines of Code\n";
|
||||
ss << "\t" << stats.sourceLocationCount << " Source Locations\n";
|
||||
|
||||
LOG_WARNING(ss.str());
|
||||
}
|
||||
@@ -812,7 +817,12 @@ std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& qu
|
||||
|
||||
m_cachedQuery = query;
|
||||
|
||||
std::vector<SearchMatch> matches = SearchIndex::getMatches(m_cachedResults, query);
|
||||
SearchResults results = m_cachedResults;
|
||||
SearchResults commandResults = m_commandIndex.runFuzzySearch(query);
|
||||
results.insert(commandResults.begin(), commandResults.end());
|
||||
|
||||
std::vector<SearchMatch> matches = SearchIndex::getMatches(results, query);
|
||||
|
||||
LOG_INFO_STREAM(<< matches.size() << " matches for \"" << query << "\"");
|
||||
|
||||
if (matches.size() > 100)
|
||||
@@ -825,6 +835,7 @@ std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& qu
|
||||
if (!match.tokenIds.size())
|
||||
{
|
||||
match.searchType = SearchMatch::SEARCH_COMMAND;
|
||||
match.typeName = "command";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -883,6 +894,25 @@ std::vector<SearchMatch> Storage::getSearchMatchesForTokenIds(const std::vector<
|
||||
return matches;
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> Storage::getGraphForAll() const
|
||||
{
|
||||
std::shared_ptr<Graph> graph = std::make_shared<Graph>();
|
||||
|
||||
std::vector<Id> tokenIds;
|
||||
for (StorageNode node: m_sqliteStorage.getAllNodes())
|
||||
{
|
||||
if (node.defined && Node::intToType(node.type) != Node::NODE_TEMPLATE_PARAMETER_TYPE
|
||||
&& !m_hierarchyCache.isChildOfVisibleNodeOrInvisible(node.id))
|
||||
{
|
||||
tokenIds.push_back(node.id);
|
||||
}
|
||||
}
|
||||
|
||||
addNodesToGraph(tokenIds, graph.get());
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> Storage::getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const
|
||||
{
|
||||
std::shared_ptr<Graph> g = std::make_shared<Graph>();
|
||||
@@ -1293,6 +1323,26 @@ TimePoint Storage::getFileModificationTime(const FilePath& filePath) const
|
||||
return TimePoint(m_sqliteStorage.getFileByPath(filePath.str()).modificationTime);
|
||||
}
|
||||
|
||||
StorageStats Storage::getStorageStats() const
|
||||
{
|
||||
StorageStats stats;
|
||||
|
||||
stats.nodeCount = m_sqliteStorage.getNodeCount();
|
||||
stats.edgeCount = m_sqliteStorage.getEdgeCount();
|
||||
|
||||
stats.charCount = m_tokenIndex.getCharCount();
|
||||
stats.wordCount = m_tokenIndex.getWordCount();
|
||||
stats.searchNodeCount = m_tokenIndex.getNodeCount();
|
||||
|
||||
stats.fileCount = m_sqliteStorage.getFileCount();
|
||||
stats.fileLOCCount = m_sqliteStorage.getFileLOCCount();
|
||||
stats.sourceLocationCount = m_sqliteStorage.getSourceLocationCount();
|
||||
|
||||
stats.errorCount = getErrorCount();
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
Id Storage::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool defined)
|
||||
{
|
||||
if (nameHierarchy.size() == 0)
|
||||
|
||||
@@ -146,6 +146,7 @@ public:
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query) const;
|
||||
virtual std::vector<SearchMatch> getSearchMatchesForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const;
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
|
||||
virtual std::vector<Id> getActiveTokenIdsForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
@@ -171,6 +172,8 @@ public:
|
||||
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const;
|
||||
virtual TimePoint getFileModificationTime(const FilePath& filePath) const;
|
||||
|
||||
virtual StorageStats getStorageStats() const;
|
||||
|
||||
private:
|
||||
Id addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool defined);
|
||||
Id addNodeHierarchy(Node::NodeType type, const ParseFunction& function, bool defined);
|
||||
@@ -205,6 +208,8 @@ private:
|
||||
void log(std::string type, std::string str, const ParseLocation& location) const;
|
||||
|
||||
SearchIndex m_tokenIndex;
|
||||
SearchIndex m_commandIndex;
|
||||
|
||||
SqliteStorage m_sqliteStorage;
|
||||
|
||||
mutable std::map <FilePath, Id> m_fileNodeIds;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef STORAGE_STATS_H
|
||||
#define STORAGE_STATS_H
|
||||
|
||||
struct StorageStats
|
||||
{
|
||||
StorageStats()
|
||||
: nodeCount(0)
|
||||
, edgeCount(0)
|
||||
, charCount(0)
|
||||
, wordCount(0)
|
||||
, searchNodeCount(0)
|
||||
, fileCount(0)
|
||||
, fileLOCCount(0)
|
||||
, sourceLocationCount(0)
|
||||
, errorCount(0)
|
||||
{}
|
||||
|
||||
size_t nodeCount;
|
||||
size_t edgeCount;
|
||||
|
||||
size_t charCount;
|
||||
size_t wordCount;
|
||||
size_t searchNodeCount;
|
||||
|
||||
size_t fileCount;
|
||||
size_t fileLOCCount;
|
||||
size_t sourceLocationCount;
|
||||
|
||||
size_t errorCount;
|
||||
};
|
||||
|
||||
#endif // STORAGE_STATS_H
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "data/graph/Node.h"
|
||||
#include "data/search/SearchMatch.h"
|
||||
#include "data/StorageStats.h"
|
||||
|
||||
struct FileInfo;
|
||||
class Graph;
|
||||
@@ -37,6 +38,7 @@ public:
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query) const = 0;
|
||||
virtual std::vector<SearchMatch> getSearchMatchesForTokenIds(const std::vector<Id>& tokenIds) const = 0;
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const = 0;
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const = 0;
|
||||
|
||||
virtual std::vector<Id> getActiveTokenIdsForTokenIds(const std::vector<Id>& tokenIds) const = 0;
|
||||
@@ -60,6 +62,8 @@ public:
|
||||
|
||||
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const = 0;
|
||||
virtual TimePoint getFileModificationTime(const FilePath& filePath) const = 0;
|
||||
|
||||
virtual StorageStats getStorageStats() const = 0;
|
||||
};
|
||||
|
||||
#endif // STORAGE_ACCESS_H
|
||||
|
||||
@@ -113,6 +113,16 @@ std::vector<SearchMatch> StorageAccessProxy::getSearchMatchesForTokenIds(const s
|
||||
return std::vector<SearchMatch>();
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> StorageAccessProxy::getGraphForAll() const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getGraphForAll();
|
||||
}
|
||||
|
||||
return std::make_shared<Graph>();
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> StorageAccessProxy::getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const
|
||||
{
|
||||
if (hasSubject())
|
||||
@@ -274,3 +284,13 @@ TimePoint StorageAccessProxy::getFileModificationTime(const FilePath& filePath)
|
||||
|
||||
return TimePoint(boost::posix_time::not_a_date_time);
|
||||
}
|
||||
|
||||
StorageStats StorageAccessProxy::getStorageStats() const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getStorageStats();
|
||||
}
|
||||
|
||||
return StorageStats();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query) const;
|
||||
virtual std::vector<SearchMatch> getSearchMatchesForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const;
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
|
||||
virtual std::vector<Id> getActiveTokenIdsForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
@@ -51,6 +52,8 @@ public:
|
||||
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const;
|
||||
virtual TimePoint getFileModificationTime(const FilePath& filePath) const;
|
||||
|
||||
virtual StorageStats getStorageStats() const;
|
||||
|
||||
private:
|
||||
StorageAccess* m_subject;
|
||||
};
|
||||
|
||||
@@ -45,6 +45,28 @@ std::string SearchMatch::searchMatchesToString(const std::vector<SearchMatch>& m
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
SearchMatch SearchMatch::createCommand(CommandType type)
|
||||
{
|
||||
SearchMatch match;
|
||||
match.nameHierarchy = NameHierarchy(getCommandName(type));
|
||||
match.typeName = "command";
|
||||
match.searchType = SEARCH_COMMAND;
|
||||
return match;
|
||||
}
|
||||
|
||||
std::string SearchMatch::getCommandName(CommandType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case COMMAND_ALL:
|
||||
return "overview";
|
||||
case COMMAND_ERROR:
|
||||
return "error";
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
SearchMatch::SearchMatch()
|
||||
: typeName("")
|
||||
, searchType(SEARCH_NONE)
|
||||
|
||||
@@ -19,11 +19,20 @@ struct SearchMatch
|
||||
SEARCH_OPERATOR
|
||||
};
|
||||
|
||||
enum CommandType
|
||||
{
|
||||
COMMAND_ALL,
|
||||
COMMAND_ERROR
|
||||
};
|
||||
|
||||
static void log(const std::vector<SearchMatch>& matches, const std::string& query);
|
||||
|
||||
static std::string getSearchTypeName(SearchType type);
|
||||
static std::string searchMatchesToString(const std::vector<SearchMatch>& matches);
|
||||
|
||||
static SearchMatch createCommand(CommandType type);
|
||||
static std::string getCommandName(CommandType type);
|
||||
|
||||
SearchMatch();
|
||||
SearchMatch(const std::string& query);
|
||||
|
||||
|
||||
@@ -122,3 +122,8 @@ bool ProjectSettings::setSourceExtensions(const std::vector<std::string> &source
|
||||
{
|
||||
return setValues("source/extensions/source_extensions", sourceExtensions);
|
||||
}
|
||||
|
||||
std::string ProjectSettings::getDescription() const
|
||||
{
|
||||
return getValue<std::string>("info/description", "");
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ public:
|
||||
|
||||
virtual void save(const FilePath& filePath);
|
||||
|
||||
// info
|
||||
std::string getDescription() const;
|
||||
|
||||
// language settings
|
||||
std::string getLanguage() const;
|
||||
bool setLanguage(const std::string& language);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef MESSAGE_ACTIVATE_ALL_H
|
||||
#define MESSAGE_ACTIVATE_ALL_H
|
||||
|
||||
#include "utility/messaging/Message.h"
|
||||
|
||||
class MessageActivateAll
|
||||
: public Message<MessageActivateAll>
|
||||
{
|
||||
public:
|
||||
MessageActivateAll()
|
||||
{
|
||||
}
|
||||
|
||||
static const std::string getStaticType()
|
||||
{
|
||||
return "MessageActivateAll";
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MESSAGE_ACTIVATE_ALL_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef MESSAGE_ACTIVATE_TOKEN_IDS_H
|
||||
#define MESSAGE_ACTIVATE_TOKEN_IDS_H
|
||||
|
||||
#include "utility/messaging/Message.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class MessageActivateTokenIds
|
||||
: public Message<MessageActivateTokenIds>
|
||||
{
|
||||
public:
|
||||
MessageActivateTokenIds(const std::vector<Id>& tokenIds)
|
||||
: tokenIds(tokenIds)
|
||||
{
|
||||
}
|
||||
|
||||
static const std::string getStaticType()
|
||||
{
|
||||
return "MessageActivateTokenIds";
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os) const
|
||||
{
|
||||
for (const Id& id : tokenIds)
|
||||
{
|
||||
os << id << " ";
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Id> tokenIds;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_ACTIVATE_TOKEN_IDS_H
|
||||
@@ -128,6 +128,13 @@ namespace utility
|
||||
return res.first == prefix.end();
|
||||
}
|
||||
|
||||
std::string toUpperCase(const std::string& in)
|
||||
{
|
||||
std::string out;
|
||||
std::transform(in.begin(), in.end(), std::back_inserter(out), toupper);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string toLowerCase(const std::string& in)
|
||||
{
|
||||
std::string out;
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace utility
|
||||
|
||||
bool isPrefix(const std::string& prefix, const std::string& text);
|
||||
|
||||
std::string toUpperCase(const std::string& in);
|
||||
std::string toLowerCase(const std::string& in);
|
||||
bool equalsCaseInsensitive(const std::string& a, const std::string& b);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user