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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user