ui/logic/data: refreshing only source files that have been updated

This change adds the refresh component that allows for refreshing the source code via UI or shortcut. If automatic
refreshing is activated via the UI, the code is refreshed anytime the window gets focus. The contents of all the
updated source files get removed from Storage, before reparsing them. File dependencies are not respected yet.
This commit is contained in:
Eberhard Graether
2015-02-03 14:27:39 +01:00
parent e17341fc43
commit 1690479b0e
52 changed files with 1145 additions and 92 deletions
+26 -3
View File
@@ -1,6 +1,7 @@
#include "cxxtest/TestSuite.h"
#include <algorithm>
#include <fstream>
#include <string>
#include <vector>
@@ -15,7 +16,7 @@ public:
extensions.push_back(".cpp");
std::vector<std::string> cppFiles =
FileSystem::getSourceFilesFromDirectory("data/FileSystemTestSuite", extensions);
FileSystem::getFileNamesFromDirectory("data/FileSystemTestSuite", extensions);
TS_ASSERT_EQUALS(cppFiles.size(), 2);
TS_ASSERT(isInVector(cppFiles, "data/FileSystemTestSuite/main.cpp"));
@@ -28,7 +29,7 @@ public:
extensions.push_back(".h");
std::vector<std::string> headerFiles =
FileSystem::getSourceFilesFromDirectory("data/FileSystemTestSuite", extensions);
FileSystem::getFileNamesFromDirectory("data/FileSystemTestSuite", extensions);
TS_ASSERT_EQUALS(headerFiles.size(), 2);
TS_ASSERT(isInVector(headerFiles, "data/FileSystemTestSuite/tictactoe.h"));
@@ -43,11 +44,33 @@ public:
extensions.push_back(".cpp");
std::vector<std::string> sourceFiles =
FileSystem::getSourceFilesFromDirectory("data/FileSystemTestSuite", extensions);
FileSystem::getFileNamesFromDirectory("data/FileSystemTestSuite", extensions);
TS_ASSERT_EQUALS(sourceFiles.size(), 5);
}
void test_find_updated_source_files()
{
std::string timeString = FileSystem::getTimeStringNow();
std::fstream fileStream;
fileStream.open("./data/FileSystemTestSuite/update.c");
fileStream << "update";
fileStream.close();
std::vector<std::string> extensions;
extensions.push_back(".h");
extensions.push_back(".c");
extensions.push_back(".hpp");
extensions.push_back(".cpp");
std::vector<std::string> sourceFiles =
FileSystem::getFileNamesFromDirectoryUpdatedAfter("data/FileSystemTestSuite", extensions, timeString);
TS_ASSERT_EQUALS(sourceFiles.size(), 1);
TS_ASSERT_EQUALS(sourceFiles[0], "data/FileSystemTestSuite/update.c");
}
void test_filesystem_finds_existing_files()
{
TS_ASSERT(FileSystem::exists("data/FileSystemTestSuite"));
+67
View File
@@ -245,6 +245,21 @@ public:
TS_ASSERT_EQUALS(children[1], &c);
}
void test_node_has_references()
{
Node a(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("A", "::")));
Node b(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("B", "::")));
Node c(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("C", "::")));
Node d(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("D", "::")));
Edge e(Edge::EDGE_MEMBER, &a, &b);
Edge e2(Edge::EDGE_MEMBER, &a, &c);
Edge e3(Edge::EDGE_USAGE, &c, &d);
TS_ASSERT(a.hasReferences());
TS_ASSERT(!b.hasReferences());
TS_ASSERT(c.hasReferences());
}
void test_graph_saves_nodes()
{
Graph graph;
@@ -294,6 +309,58 @@ public:
TS_ASSERT_EQUALS(Edge::EDGE_CALL, graph.getEdgeById(e.getId())->getType());
}
void test_graph_removes_nodes()
{
Graph graph;
Node a(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("A", "::")));
Node b(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("B", "::")));
graph.addNode(&a);
graph.addNode(&b);
TS_ASSERT_EQUALS(2, graph.getNodeCount());
TS_ASSERT_EQUALS(0, graph.getEdgeCount());
graph.removeNode(graph.getNodeById(a.getId()));
TS_ASSERT_EQUALS(1, graph.getNodeCount());
}
void test_graph_removes_unreferenced_nodes()
{
Graph graph;
Node a(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("A", "::")));
Node b(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("B", "::")));
Node c(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("C", "::")));
Node d(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("D", "::")));
Node e(Node::NODE_UNDEFINED, std::make_shared<TokenComponentNameCached>(utility::splitToVector("E", "::")));
Edge e1(Edge::EDGE_MEMBER, &a, &b);
Edge e2(Edge::EDGE_MEMBER, &a, &c);
Edge e3(Edge::EDGE_USAGE, &c, &d);
Edge e4(Edge::EDGE_MEMBER, &b, &e);
graph.addNode(&a);
graph.addNode(&b);
graph.addNode(&c);
graph.addNode(&d);
graph.addNode(&e);
graph.addEdge(&e1);
graph.addEdge(&e2);
graph.addEdge(&e3);
graph.addEdge(&e4);
TS_ASSERT_EQUALS(5, graph.getNodeCount());
TS_ASSERT_EQUALS(4, graph.getEdgeCount());
TS_ASSERT(!graph.removeNodeIfUnreferencedRecursive(graph.getNodeById(a.getId())));
TS_ASSERT(graph.removeNodeIfUnreferencedRecursive(graph.getNodeById(b.getId())));
TS_ASSERT_EQUALS(3, graph.getNodeCount());
TS_ASSERT_EQUALS(2, graph.getEdgeCount());
}
private:
class TestToken: public Token
{
+54 -2
View File
@@ -17,7 +17,8 @@ public:
TS_ASSERT(node->getNameId());
TS_ASSERT(!node->getFirstTokenId());
TS_ASSERT(!node->getParent());
TS_ASSERT(node->getParent());
TS_ASSERT(!node->getParent()->getNameId());
}
void test_get_node()
@@ -32,7 +33,8 @@ public:
TS_ASSERT(node->getNameId());
TS_ASSERT(!node->getFirstTokenId());
TS_ASSERT(!node->getParent());
TS_ASSERT(node->getParent());
TS_ASSERT(!node->getParent()->getNameId());
node = index.getNode("math");
TS_ASSERT(!node);
@@ -72,6 +74,55 @@ public:
TS_ASSERT_EQUALS(node1->getParent(), node2->getParent());
}
void test_remove_nodes()
{
SearchIndex index;
index.addNode(utility::splitToVector("util::math::pow", "::"));
index.addNode(utility::splitToVector("util::math::floor", "::"));
index.removeNode(index.getNode("util::math::pow"));
TS_ASSERT(!index.getNode("util::math::pow"));
TS_ASSERT(index.getNode("util::math::floor"));
TS_ASSERT(index.getNode("util::math"));
index.removeNode(index.getNode("util::math"));
TS_ASSERT(!index.getNode("util::math::floor"));
TS_ASSERT(!index.getNode("util::math"));
TS_ASSERT(index.getNode("util"));
}
void test_remove_unreferenced_nodes()
{
SearchIndex index;
SearchNode* node1 = index.addNode(utility::splitToVector("util::math::pow", "::"));
SearchNode* node2 = index.addNode(utility::splitToVector("util::math::floor", "::"));
node1->addTokenId(1);
node2->addTokenId(2);
TS_ASSERT(index.getNode("util")->hasTokenIdsRecursive());
TS_ASSERT(!index.removeNodeIfUnreferencedRecursive(index.getNode("util")));
TS_ASSERT(!index.removeNodeIfUnreferencedRecursive(index.getNode("util::math")));
TS_ASSERT(!index.removeNodeIfUnreferencedRecursive(index.getNode("util::math::pow")));
node1->removeTokenId(1);
TS_ASSERT(index.removeNodeIfUnreferencedRecursive(index.getNode("util::math::pow")));
TS_ASSERT(!index.getNode("util::math::pow"));
TS_ASSERT(index.getNode("util::math"));
TS_ASSERT(index.getNode("util"));
node2->removeTokenId(2);
TS_ASSERT(index.removeNodeIfUnreferencedRecursive(index.getNode("util::math")));
TS_ASSERT(!index.getNode("util::math"));
TS_ASSERT(!index.getNode("util"));
}
void test_clear()
{
SearchIndex index;
@@ -83,6 +134,7 @@ public:
index.clear();
TS_ASSERT(!index.getNode("math"));
TS_ASSERT(!index.getNode("string"));
}
void test_fuzzy_matching()
+135 -2
View File
@@ -15,6 +15,11 @@
class StorageTestSuite: public CxxTest::TestSuite
{
public:
void setUp()
{
m_filePath = "file.cpp";
}
void test_storage_saves_typedef()
{
TestStorage storage;
@@ -536,6 +541,117 @@ public:
TS_ASSERT(isValidLocation(locations[0], 0));
}
void test_storage_clears_single_file_data_of_single_file_storage()
{
TestStorage storage;
storage.onFunctionParsed(
validLocation(), ParseFunction(typeUsage("bool"), utility::splitToVector("isTrue", "::"),
parameters("char")), validLocation()
);
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 3);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 2);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 4);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 3);
storage.clearFileData(std::vector<std::string>(1, m_filePath));
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 0);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 0);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 0);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 0);
}
void test_storage_clears_unreferenced_single_file_data_of_multi_file_storage()
{
m_filePath = "file.h";
TestStorage storage;
ParseFunction isTrue = ParseFunction(typeUsage("bool"), utility::splitToVector("isTrue", "::"), parameters("char"));
storage.onFunctionParsed(validLocation(), isTrue, validLocation());
m_filePath = "file.cpp";
ParseFunction main = ParseFunction(typeUsage("int"), utility::splitToVector("main", "::"), parameters("void"));
storage.onFunctionParsed(validLocation(), main, validLocation());
storage.onCallParsed(validLocation(), main, isTrue);
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 6);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 5);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 6);
storage.clearFileData(std::vector<std::string>(1, "file.cpp"));
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 3);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 2);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 4);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 3);
}
void test_storage_clears_referenced_single_file_data_of_multi_file_storage()
{
m_filePath = "file.h";
TestStorage storage;
ParseFunction isTrue = ParseFunction(typeUsage("bool"), utility::splitToVector("isTrue", "::"), parameters("void"));
storage.onFunctionParsed(validLocation(), isTrue, validLocation());
m_filePath = "file.cpp";
ParseFunction main = ParseFunction(typeUsage("int"), utility::splitToVector("main", "::"), parameters("void"));
storage.onFunctionParsed(validLocation(), main, validLocation());
storage.onCallParsed(validLocation(), main, isTrue);
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 5);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 5);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 5);
storage.clearFileData(std::vector<std::string>(1, "file.h"));
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 4);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 3);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 5);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 4);
}
void test_storage_clears_multi_file_data_of_multi_file_storage()
{
m_filePath = "file.h";
TestStorage storage;
ParseFunction isTrue = ParseFunction(typeUsage("bool"), utility::splitToVector("isTrue", "::"), parameters("void"));
storage.onFunctionParsed(validLocation(), isTrue, validLocation());
m_filePath = "file.cpp";
ParseFunction main = ParseFunction(typeUsage("int"), utility::splitToVector("main", "::"), parameters("void"));
storage.onFunctionParsed(validLocation(), main, validLocation());
storage.onCallParsed(validLocation(), main, isTrue);
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 5);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 5);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 5);
std::vector<std::string> filePaths;
filePaths.push_back("file.cpp");
filePaths.push_back("file.h");
storage.clearFileData(filePaths);
TS_ASSERT_EQUALS(storage.graph().getNodeCount(), 0);
TS_ASSERT_EQUALS(storage.graph().getEdgeCount(), 0);
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 0);
TS_ASSERT_EQUALS(storage.searchIndex().getNodeCount(), 0);
}
private:
class TestStorage
: public Storage
@@ -568,17 +684,32 @@ private:
{
return getSearchIndex().getWord(wordId);
}
const Graph& graph() const
{
return getGraph();
}
const TokenLocationCollection& tokenLocationCollection() const
{
return getTokenLocationCollection();
}
const SearchIndex& searchIndex() const
{
return getSearchIndex();
}
};
ParseLocation validLocation(Id locationId = 0) const
{
return ParseLocation("file.cpp", 1, locationId, 1, locationId);
return ParseLocation(m_filePath, 1, locationId, 1, locationId);
}
bool isValidLocation(TokenLocation* location, Id locationId) const
{
return
location->getFilePath() == "file.cpp" &&
location->getFilePath() == m_filePath &&
location->getLineNumber() == 1 &&
location->getColumnNumber() == locationId;
}
@@ -594,4 +725,6 @@ private:
params.push_back(typeUsage(param));
return params;
}
std::string m_filePath;
};