diff --git a/src/source.h b/src/source.h index ffdade5..97f78e4 100644 --- a/src/source.h +++ b/src/source.h @@ -73,7 +73,7 @@ namespace Source { Glib::RefPtr language; std::function auto_indent; - std::function get_declaration_location; + std::function &views)> get_declaration_location; std::function &views)> get_implementation_location; std::function >(const std::vector &views)> get_usages; std::function goto_method; diff --git a/src/source_clang.cc b/src/source_clang.cc index d2112b3..3a5f7a2 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -965,11 +965,10 @@ Source::ClangViewAutocomplete(file_path, language) { } }); - get_declaration_location=[this](){ - Offset location; + get_declaration_location=[this](const std::vector &views){ if(!parsed) { Info::get().print("Buffer is parsing"); - return location; + return Offset(); } auto iter=get_buffer()->get_insert()->get_iter(); auto line=static_cast(iter.get_line()); @@ -980,16 +979,43 @@ Source::ClangViewAutocomplete(file_path, language) { if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { auto referenced=cursor.get_referenced(); if(referenced) { - location.file_path=referenced.get_source_location().get_path(); - auto clang_offset=referenced.get_source_location().get_offset(); - location.line=clang_offset.line; - location.index=clang_offset.index; - break; + auto file_path=referenced.get_source_location().get_path(); + + //if declaration is implementation instead, attempt to find declaration + if(file_path==this->file_path && this->language && this->language->get_id()!="chdr" && this->language->get_id()!="cpphdr") { + auto identifier=Identifier(referenced.get_kind(), token.get_spelling(), referenced.get_usr()); + + std::vector search_views; + for(auto &view: views) { + if(view->language && (view->language->get_id()=="chdr" || view->language->get_id()=="cpphdr")) + search_views.emplace_back(view); + } + search_views.emplace_back(this); + wait_parsing(search_views); + for(auto &view: search_views) { + if(auto clang_view=dynamic_cast(view)) { + for(auto &token: *clang_view->clang_tokens) { + auto cursor=token.get_cursor(); + if(token.get_kind()==clang::TokenKind::Token_Identifier && cursor.has_type()) { + auto referenced=cursor.get_referenced(); + if(referenced && identifier.kind==referenced.get_kind() && + identifier.spelling==token.get_spelling() && identifier.usr==referenced.get_usr()) { + auto offset=referenced.get_source_location().get_offset(); + return Offset(offset.line, offset.index, referenced.get_source_location().get_path()); + } + } + } + } + } + } + + auto offset=referenced.get_source_location().get_offset(); + return Offset(offset.line, offset.index, file_path); } } } } - return location; + return Offset(); }; get_implementation_location=[this](const std::vector &views){ diff --git a/src/window.cc b/src/window.cc index b7582ab..48796b0 100644 --- a/src/window.cc +++ b/src/window.cc @@ -435,7 +435,7 @@ void Window::set_menu_actions() { menu.add_action("source_goto_declaration", [this]() { if(notebook.get_current_page()!=-1) { if(notebook.get_current_view()->get_declaration_location) { - auto location=notebook.get_current_view()->get_declaration_location(); + auto location=notebook.get_current_view()->get_declaration_location(notebook.source_views); if(location) { boost::filesystem::path declaration_file; boost::system::error_code ec;