diff --git a/src/app/main.cpp b/src/app/main.cpp index a15749fd..a95bfb4d 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1,4 +1,5 @@ #include "Application.h" +#include "ApplicationStateMonitor.h" #include "ProjectFactoryModuleC.h" #include "ProjectFactoryModuleCpp.h" #include "ProjectFactoryModuleJava.h" @@ -175,7 +176,6 @@ int main(int argc, char *argv[]) Application::destroyInstance(); }); - prefillJavaRuntimePath(); prefillCxxHeaderPaths(); prefillCxxFrameworkPaths(); @@ -196,6 +196,44 @@ int main(int argc, char *argv[]) utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf"); utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".ttf"); + const std::vector storedIndexingFiles = ApplicationStateMonitor::getStoredIndexingFiles(); + if (storedIndexingFiles.size() > 0) + { + ApplicationStateMonitor::clearStoredIndexingFiles(); + if (storedIndexingFiles.size() > 1) + { + std::string fileStrings = ""; + for (const FilePath& filePath: storedIndexingFiles) + { + fileStrings += "
  • " + filePath.str() + "
  • "; + } + Application::getInstance()->handleDialog( + "

    It seems that Coati shut down unexpectedly while indexing your project. We are sorry about that. " + "But let's go on and find out what exactly went wrong. The crash occurred while indexing one of these files:

    " + "" + "

    First of all we need to figure out which of these files caused the crash. Please go ahead and create copy of your project. " + "Remove everything except the files mentioned above from the Project Paths. " + "Set your indexer thread count to 1, force-refresh the project and wait for the crash to reoccur.

    " + ); + } + else + { + Application::getInstance()->handleDialog( + "

    It seems that Coati shut down unexpectedly while indexing your project. We are really sorry about that. " + "At least we know which of your source files caused the crash:

    " + "" + "

    To find out which part of the file caused the crash, please make sure to remove everything except this source file from your Project Paths. " + "Enable the option \"Enable Verbose Indexer Logging\" in your log window (this really slows down indexing performance) and force-refresh the project.

    " + "

    After the expected crash reoccurred please open the respective log file which now contains the portion of the abstract syntax tree that Coati managed to index, " + "including the node where the crash occurred. We hope that this information helps you figure out what caused the crash and tell us what we can do to reproduce it.

    " + ); + } + } + return qtApp.exec(); } } diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 6754fd41..5cccb8f7 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -35,7 +35,7 @@ void Application::createInstance( s_instance->m_storageCache = std::make_shared(); - if (viewFactory != nullptr) + if (hasGui) { s_instance->m_componentManager = ComponentManager::create(viewFactory, s_instance->m_storageCache.get()); diff --git a/src/lib/ApplicationStateMonitor.cpp b/src/lib/ApplicationStateMonitor.cpp new file mode 100644 index 00000000..4867d14c --- /dev/null +++ b/src/lib/ApplicationStateMonitor.cpp @@ -0,0 +1,58 @@ +#include "ApplicationStateMonitor.h" + +#include "settings/ApplicationSettings.h" + +std::shared_ptr ApplicationStateMonitor::getInstance() +{ + if (!s_instance) + { + s_instance = std::shared_ptr(new ApplicationStateMonitor()); + } + return s_instance; +} + +std::vector ApplicationStateMonitor::getStoredIndexingFiles() +{ + return ApplicationSettings::getInstance()->getIndexingFilePaths(); +} + +void ApplicationStateMonitor::clearStoredIndexingFiles() +{ + ApplicationSettings::getInstance()->setIndexingFilePaths(std::vector()); + ApplicationSettings::getInstance()->save(); +} + +void ApplicationStateMonitor::clearIndexingFiles() +{ + std::lock_guard lock(m_indexingFilesMutex); + m_indexingFiles.clear(); + storeCurrentState(); +} + +void ApplicationStateMonitor::addIndexingFile(FilePath file) +{ + std::lock_guard lock(m_indexingFilesMutex); + m_indexingFiles.insert(file); + storeCurrentState(); +} + +void ApplicationStateMonitor::removeIndexingFile(FilePath file) +{ + std::lock_guard lock(m_indexingFilesMutex); + m_indexingFiles.erase(file); + storeCurrentState(); +} + +std::shared_ptr ApplicationStateMonitor::s_instance; + +ApplicationStateMonitor::ApplicationStateMonitor() +{ +} + +void ApplicationStateMonitor::storeCurrentState() +{ + std::vector indexingFiles; + indexingFiles.insert(indexingFiles.begin(), m_indexingFiles.begin(), m_indexingFiles.end()); + ApplicationSettings::getInstance()->setIndexingFilePaths(indexingFiles); + ApplicationSettings::getInstance()->save(); +} diff --git a/src/lib/ApplicationStateMonitor.h b/src/lib/ApplicationStateMonitor.h new file mode 100644 index 00000000..95f9e8a0 --- /dev/null +++ b/src/lib/ApplicationStateMonitor.h @@ -0,0 +1,30 @@ +#ifndef APPLICATION_STATE_MONITOR_H +#define APPLICATION_STATE_MONITOR_H + +#include +#include + +#include "utility/file/FilePath.h" + +class ApplicationStateMonitor +{ +public: + static std::shared_ptr getInstance(); + static std::vector getStoredIndexingFiles(); + static void clearStoredIndexingFiles(); + + void clearIndexingFiles(); + void addIndexingFile(FilePath file); + void removeIndexingFile(FilePath file); + +private: + static std::shared_ptr s_instance; + ApplicationStateMonitor(); + void storeCurrentState(); + + + std::set m_indexingFiles; + std::mutex m_indexingFilesMutex; +}; + +#endif // APPLICATION_STATE_MONITOR_H diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 8729d91c..05595b98 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -383,6 +383,8 @@ add_files( Application.cpp Application.h + ApplicationStateMonitor.cpp + ApplicationStateMonitor.h LicenseChecker.cpp LicenseChecker.h Project.cpp diff --git a/src/lib/data/parser/TaskParse.cpp b/src/lib/data/parser/TaskParse.cpp index 7dbd841b..80606102 100644 --- a/src/lib/data/parser/TaskParse.cpp +++ b/src/lib/data/parser/TaskParse.cpp @@ -1,6 +1,9 @@ #include "data/parser/TaskParse.h" +#include "component/view/DialogView.h" +#include "utility/file/FileRegister.h" #include "utility/scheduling/Blackboard.h" +#include "ApplicationStateMonitor.h" TaskParse::TaskParse( std::shared_ptr storageProvider, @@ -28,6 +31,28 @@ void TaskParse::doEnter(std::shared_ptr blackboard) } } +Task::TaskState TaskParse::doUpdate(std::shared_ptr blackboard) +{ + FilePath sourcePath = m_fileRegister->consumeSourceFile(); + + if (sourcePath.empty()) + { + return STATE_FAILURE; + } + else + { + ApplicationStateMonitor::getInstance()->addIndexingFile(sourcePath); + m_dialogView->updateIndexingDialog( + m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), sourcePath.str() + ); + + indexFile(sourcePath); + ApplicationStateMonitor::getInstance()->removeIndexingFile(sourcePath); + } + + return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS); +} + void TaskParse::doExit(std::shared_ptr blackboard) { std::lock_guard lock(blackboard->getMutex()); diff --git a/src/lib/data/parser/TaskParse.h b/src/lib/data/parser/TaskParse.h index 02d9ea6d..9c3b5936 100644 --- a/src/lib/data/parser/TaskParse.h +++ b/src/lib/data/parser/TaskParse.h @@ -25,10 +25,12 @@ public: protected: virtual void doEnter(std::shared_ptr blackboard); + virtual TaskState doUpdate(std::shared_ptr blackboard); virtual void doExit(std::shared_ptr blackboard); virtual void doReset(std::shared_ptr blackboard); virtual void handleMessage(MessageInterruptTasks* message); + virtual void indexFile(FilePath sourcePath) = 0; std::shared_ptr m_storageProvider; std::shared_ptr m_fileRegister; diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp index a76fb3f1..9b5aac7c 100644 --- a/src/lib/settings/ApplicationSettings.cpp +++ b/src/lib/settings/ApplicationSettings.cpp @@ -175,6 +175,16 @@ void ApplicationSettings::setVerboseIndexerLoggingEnabled(bool value) setValue("application/verbose_indexer_logging_enabled", value); } +std::vector ApplicationSettings::getIndexingFilePaths() const +{ + return getPathValues("application/state/indexing_paths/indexing_path"); +} + +bool ApplicationSettings::setIndexingFilePaths(const std::vector& indexingFiles) +{ + return setPathValues("application/state/indexing_paths/indexing_path", indexingFiles); +} + int ApplicationSettings::getIndexerThreadCount() const { return getValue("indexing/indexer_thread_count", 4); diff --git a/src/lib/settings/ApplicationSettings.h b/src/lib/settings/ApplicationSettings.h index c0e296d3..323bb15d 100644 --- a/src/lib/settings/ApplicationSettings.h +++ b/src/lib/settings/ApplicationSettings.h @@ -53,6 +53,9 @@ public: bool getVerboseIndexerLoggingEnabled() const; void setVerboseIndexerLoggingEnabled(bool loggingEnabled); + std::vector getIndexingFilePaths() const; + bool setIndexingFilePaths(const std::vector& indexingFiles); + // indexing int getIndexerThreadCount() const; void setIndexerThreadCount(const int count); diff --git a/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp b/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp index 6ef6e133..68867b91 100644 --- a/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp +++ b/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp @@ -2,7 +2,6 @@ #include "clang/Tooling/JSONCompilationDatabase.h" -#include "component/view/DialogView.h" #include "data/parser/cxx/CxxParser.h" #include "data/parser/ParserClientImpl.h" #include "data/StorageProvider.h" @@ -62,48 +61,33 @@ void TaskParseCxx::doEnter(std::shared_ptr blackboard) } } -Task::TaskState TaskParseCxx::doUpdate(std::shared_ptr blackboard) +void TaskParseCxx::indexFile(FilePath sourcePath) { FileRegister* fileRegister = m_parser->getFileRegister(); - FilePath sourcePath = fileRegister->consumeSourceFile(); + std::shared_ptr storage = m_storageProvider->popIndexerTarget(); + m_parserClient->setStorage(storage); + m_parserClient->startParsingFile(); - if (sourcePath.empty()) + if (m_isCDB) { - return STATE_FAILURE; + std::vector commands = m_cdb->getCompileCommands(sourcePath.str()); + if (commands.size() > 0) + { + m_parser->runTool(commands[0], m_arguments); + } } else { - m_dialogView->updateIndexingDialog( - fileRegister->getParsedSourceFilesCount(), fileRegister->getSourceFilesCount(), sourcePath.str() - ); - - std::shared_ptr storage = m_storageProvider->popIndexerTarget(); - m_parserClient->setStorage(storage); - m_parserClient->startParsingFile(); - - if (m_isCDB) - { - std::vector commands = m_cdb->getCompileCommands(sourcePath.str()); - if (commands.size() > 0) - { - m_parser->runTool(commands[0], m_arguments); - } - } - else - { - m_parser->runTool(std::vector(1, sourcePath.str())); - } - - m_parserClient->finishParsingFile(); - m_parserClient->resetStorage(); - - if (!m_interrupted) - { - fileRegister->markThreadFilesParsed(); - m_storageProvider->pushIndexerTarget(storage); - } + m_parser->runTool(std::vector(1, sourcePath.str())); } - return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS); + m_parserClient->finishParsingFile(); + m_parserClient->resetStorage(); + + if (!m_interrupted) + { + fileRegister->markThreadFilesParsed(); + m_storageProvider->pushIndexerTarget(storage); + } } diff --git a/src/lib_cxx/data/parser/cxx/TaskParseCxx.h b/src/lib_cxx/data/parser/cxx/TaskParseCxx.h index 3cb4214c..37d98ace 100644 --- a/src/lib_cxx/data/parser/cxx/TaskParseCxx.h +++ b/src/lib_cxx/data/parser/cxx/TaskParseCxx.h @@ -29,7 +29,8 @@ public: private: virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); + + virtual void indexFile(FilePath sourcePath); std::shared_ptr m_parser; std::shared_ptr m_parserClient; diff --git a/src/lib_java/data/parser/java/TaskParseJava.cpp b/src/lib_java/data/parser/java/TaskParseJava.cpp index f7b9a066..6b57d3af 100644 --- a/src/lib_java/data/parser/java/TaskParseJava.cpp +++ b/src/lib_java/data/parser/java/TaskParseJava.cpp @@ -17,38 +17,23 @@ TaskParseJava::TaskParseJava( { } -Task::TaskState TaskParseJava::doUpdate(std::shared_ptr blackboard) +void TaskParseJava::indexFile(FilePath sourcePath) { std::shared_ptr parserClient = std::make_shared(); std::shared_ptr parser = std::make_shared(parserClient.get()); - FilePath sourcePath = m_fileRegister->consumeSourceFile(); + std::shared_ptr storage = m_storageProvider->popIndexerTarget(); + parserClient->setStorage(storage); + parserClient->startParsingFile(); - if (sourcePath.empty()) + parser->parseFile(sourcePath, TextAccess::createFromFile(sourcePath.str()), m_arguments); + + parserClient->finishParsingFile(); + parserClient->resetStorage(); + + if (!m_interrupted) { - return STATE_FAILURE; + m_fileRegister->markThreadFilesParsed(); // todo: rename to markThreadFilesProcessed + m_storageProvider->pushIndexerTarget(storage); } - else - { - m_dialogView->updateIndexingDialog( - m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), sourcePath.str() - ); - - std::shared_ptr storage = m_storageProvider->popIndexerTarget(); - parserClient->setStorage(storage); - parserClient->startParsingFile(); - - parser->parseFile(sourcePath, TextAccess::createFromFile(sourcePath.str()), m_arguments); - - parserClient->finishParsingFile(); - parserClient->resetStorage(); - - if (!m_interrupted) - { - m_fileRegister->markThreadFilesParsed(); // todo: rename to markThreadFilesProcessed - m_storageProvider->pushIndexerTarget(storage); - } - } - - return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS); } diff --git a/src/lib_java/data/parser/java/TaskParseJava.h b/src/lib_java/data/parser/java/TaskParseJava.h index 0a04e704..1c46cc67 100644 --- a/src/lib_java/data/parser/java/TaskParseJava.h +++ b/src/lib_java/data/parser/java/TaskParseJava.h @@ -15,7 +15,7 @@ public: ); private: - virtual TaskState doUpdate(std::shared_ptr blackboard); + void indexFile(FilePath sourcePath); }; #endif // TASK_PARSE_JAVA_H