Browse Source

C/C++: can now cancel waiting for parsing buffers, and added check for crashed libclang processes in wait_parsing()

pipelines/235045657
eidheim 5 years ago
parent
commit
679fbcdcbc
  1. 51
      src/source_clang.cpp
  2. 2
      src/source_clang.hpp
  3. 4
      src/usages_clang.cpp

51
src/source_clang.cpp

@ -1088,7 +1088,8 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
} }
auto identifier = get_identifier(); auto identifier = get_identifier();
if(identifier) { if(identifier) {
wait_parsing(); if(!wait_parsing())
return;
std::vector<clangmm::TranslationUnit *> translation_units; std::vector<clangmm::TranslationUnit *> translation_units;
translation_units.emplace_back(clang_tu.get()); translation_units.emplace_back(clang_tu.get());
@ -1336,7 +1337,8 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
std::vector<Offset> offsets; std::vector<Offset> offsets;
if(identifier) { if(identifier) {
if(parsed) { if(parsed) {
wait_parsing(); // Wait for other views to finish parsing if(!wait_parsing())
return offsets;
// First, look for a definition cursor that is equal // First, look for a definition cursor that is equal
auto identifier_usr = identifier.cursor.get_usr(); auto identifier_usr = identifier.cursor.get_usr();
@ -1528,7 +1530,8 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
} }
auto identifier = get_identifier(); auto identifier = get_identifier();
if(identifier) { if(identifier) {
wait_parsing(); if(!wait_parsing())
return usages;
auto embolden_token = [](std::string &line, unsigned token_start_pos, unsigned token_end_pos) { auto embolden_token = [](std::string &line, unsigned token_start_pos, unsigned token_end_pos) {
//markup token as bold //markup token as bold
@ -1844,36 +1847,44 @@ Source::ClangViewRefactor::Identifier Source::ClangViewRefactor::get_identifier(
return Identifier(); return Identifier();
} }
void Source::ClangViewRefactor::wait_parsing() { bool Source::ClangViewRefactor::wait_parsing() {
hide_tooltips(); hide_tooltips();
std::unique_ptr<Dialog::Message> message; std::vector<Source::ClangView *> not_parsed_clang_views;
std::vector<Source::ClangView *> clang_views;
for(auto &view : views) { for(auto &view : views) {
if(auto clang_view = dynamic_cast<Source::ClangView *>(view)) { if(auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
if(!clang_view->parsed && !clang_view->selected_completion_string) { if(!clang_view->parsed && !clang_view->selected_completion_string)
clang_views.emplace_back(clang_view); not_parsed_clang_views.emplace_back(clang_view);
if(!message)
message = std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing");
} }
} }
} if(!not_parsed_clang_views.empty()) {
if(message) { bool canceled = false;
auto message = std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing", [&canceled] {
canceled = true;
}, true);
ScopeGuard guard{[&message] {
message->hide();
}};
while(true) { while(true) {
bool all_parsed = true; size_t not_parsed = 0;
for(auto &clang_view : clang_views) { for(auto &clang_view : not_parsed_clang_views) {
if(!clang_view->parsed) { if(clang_view->parse_state == ParseState::stop) {
all_parsed = false; Info::get().print("Canceled due to parsing error in " + clang_view->file_path.string());
break; return false;
} }
if(!clang_view->parsed)
++not_parsed;
} }
if(all_parsed) if(not_parsed == 0)
break; return true;
if(canceled)
return false;
message->set_fraction(static_cast<double>(not_parsed_clang_views.size() - not_parsed) / not_parsed_clang_views.size());
while(Gtk::Main::events_pending()) while(Gtk::Main::events_pending())
Gtk::Main::iteration(); Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
message->hide();
} }
return true;
} }
void Source::ClangViewRefactor::apply_similar_symbol_tag() { void Source::ClangViewRefactor::apply_similar_symbol_tag() {

2
src/source_clang.hpp

@ -100,7 +100,7 @@ namespace Source {
private: private:
Identifier get_identifier(); Identifier get_identifier();
void wait_parsing(); bool wait_parsing();
}; };
class ClangView : public ClangViewAutocomplete, public ClangViewRefactor { class ClangView : public ClangViewAutocomplete, public ClangViewRefactor {

4
src/usages_clang.cpp

@ -171,16 +171,16 @@ std::vector<Usages::Clang::Usages> Usages::Clang::get_usages(const boost::filesy
std::atomic<size_t> tasks_completed = {0}; std::atomic<size_t> tasks_completed = {0};
if(tasks != 0) { if(tasks != 0) {
message = create_message(); message = create_message();
while(cache_in_progress_count != 0) { while(cache_in_progress_count != 0 && !canceled) {
message->set_fraction((static_cast<double>(tasks - cache_in_progress_count) / tasks) / 10.0); message->set_fraction((static_cast<double>(tasks - cache_in_progress_count) / tasks) / 10.0);
while(Gtk::Main::events_pending()) while(Gtk::Main::events_pending())
Gtk::Main::iteration(); Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
} }
tasks_completed = tasks;
if(canceled) if(canceled)
return {}; return {};
tasks_completed = tasks;
// Use cache // Use cache
for(auto it = potential_paths.begin(); it != potential_paths.end();) { for(auto it = potential_paths.begin(); it != potential_paths.end();) {

Loading…
Cancel
Save