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