|
|
|
@ -6,6 +6,7 @@ |
|
|
|
#include "debug_clang.h" |
|
|
|
#include "debug_clang.h" |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
#include "info.h" |
|
|
|
#include "info.h" |
|
|
|
|
|
|
|
#include "dialogs.h" |
|
|
|
|
|
|
|
|
|
|
|
namespace sigc { |
|
|
|
namespace sigc { |
|
|
|
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE |
|
|
|
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE |
|
|
|
@ -891,6 +892,7 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
} |
|
|
|
} |
|
|
|
auto token=get_token(); |
|
|
|
auto token=get_token(); |
|
|
|
if(token) { |
|
|
|
if(token) { |
|
|
|
|
|
|
|
wait_parsing(views); |
|
|
|
std::vector<Source::View*> renamed_views; |
|
|
|
std::vector<Source::View*> renamed_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)) { |
|
|
|
@ -968,28 +970,32 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
return location; |
|
|
|
return location; |
|
|
|
} |
|
|
|
} |
|
|
|
auto token=get_token(); |
|
|
|
auto token=get_token(); |
|
|
|
for(auto &view: views) { |
|
|
|
if(token) { |
|
|
|
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { |
|
|
|
wait_parsing(views); |
|
|
|
if(clang_view->language && clang_view->language->get_id()!="chdr" && clang_view->language->get_id()!="cpphdr") { |
|
|
|
for(auto &view: views) { |
|
|
|
for(auto token_it=clang_view->clang_tokens->rbegin();token_it!=clang_view->clang_tokens->rend();++token_it) { |
|
|
|
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { |
|
|
|
auto cursor=token_it->get_cursor(); |
|
|
|
if(clang_view->language && clang_view->language->get_id()!="chdr" && clang_view->language->get_id()!="cpphdr") { |
|
|
|
auto kind=cursor.get_kind(); |
|
|
|
for(auto token_it=clang_view->clang_tokens->rbegin();token_it!=clang_view->clang_tokens->rend();++token_it) { |
|
|
|
if((kind==clang::CursorKind::FunctionDecl || kind==clang::CursorKind::CXXMethod || |
|
|
|
auto cursor=token_it->get_cursor(); |
|
|
|
kind==clang::CursorKind::Constructor || kind==clang::CursorKind::Destructor) && |
|
|
|
auto kind=cursor.get_kind(); |
|
|
|
token_it->get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
if((kind==clang::CursorKind::FunctionDecl || kind==clang::CursorKind::CXXMethod || |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
kind==clang::CursorKind::Constructor || kind==clang::CursorKind::Destructor) && |
|
|
|
if(referenced && token.kind==referenced.get_kind() && |
|
|
|
token_it->get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
token.spelling==token_it->get_spelling() && token.usr==referenced.get_usr()) { |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
location.file_path=cursor.get_source_location().get_path(); |
|
|
|
if(referenced && token.kind==referenced.get_kind() && |
|
|
|
auto clang_offset=cursor.get_source_location().get_offset(); |
|
|
|
token.spelling==token_it->get_spelling() && token.usr==referenced.get_usr()) { |
|
|
|
location.line=clang_offset.line; |
|
|
|
location.file_path=cursor.get_source_location().get_path(); |
|
|
|
location.index=clang_offset.index; |
|
|
|
auto clang_offset=cursor.get_source_location().get_offset(); |
|
|
|
return location; |
|
|
|
location.line=clang_offset.line; |
|
|
|
|
|
|
|
location.index=clang_offset.index; |
|
|
|
|
|
|
|
return location; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Info::get().print("Could not find implementation"); |
|
|
|
} |
|
|
|
} |
|
|
|
return location; |
|
|
|
return location; |
|
|
|
}; |
|
|
|
}; |
|
|
|
@ -1001,46 +1007,49 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
return usages; |
|
|
|
return usages; |
|
|
|
} |
|
|
|
} |
|
|
|
auto token=get_token(); |
|
|
|
auto token=get_token(); |
|
|
|
std::vector<Source::View*> views_reordered; |
|
|
|
if(token) { |
|
|
|
views_reordered.emplace_back(this); |
|
|
|
wait_parsing(views); |
|
|
|
for(auto &view: views) { |
|
|
|
std::vector<Source::View*> views_reordered; |
|
|
|
if(view!=this) |
|
|
|
views_reordered.emplace_back(this); |
|
|
|
views_reordered.emplace_back(view); |
|
|
|
for(auto &view: views) { |
|
|
|
} |
|
|
|
if(view!=this) |
|
|
|
for(auto &view: views_reordered) { |
|
|
|
views_reordered.emplace_back(view); |
|
|
|
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { |
|
|
|
} |
|
|
|
auto offsets=clang_view->clang_tokens->get_similar_token_offsets(token.kind, token.spelling, token.usr); |
|
|
|
for(auto &view: views_reordered) { |
|
|
|
for(auto &offset: offsets) { |
|
|
|
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { |
|
|
|
size_t whitespaces_removed=0; |
|
|
|
auto offsets=clang_view->clang_tokens->get_similar_token_offsets(token.kind, token.spelling, token.usr); |
|
|
|
auto start_iter=clang_view->get_buffer()->get_iter_at_line(offset.first.line-1); |
|
|
|
for(auto &offset: offsets) { |
|
|
|
while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) { |
|
|
|
size_t whitespaces_removed=0; |
|
|
|
start_iter.forward_char(); |
|
|
|
auto start_iter=clang_view->get_buffer()->get_iter_at_line(offset.first.line-1); |
|
|
|
whitespaces_removed++; |
|
|
|
while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) { |
|
|
|
} |
|
|
|
start_iter.forward_char(); |
|
|
|
auto end_iter=start_iter; |
|
|
|
whitespaces_removed++; |
|
|
|
while(!end_iter.ends_line()) |
|
|
|
|
|
|
|
end_iter.forward_char(); |
|
|
|
|
|
|
|
std::string line=Glib::Markup::escape_text(clang_view->get_buffer()->get_text(start_iter, end_iter)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//markup token as bold
|
|
|
|
|
|
|
|
size_t token_start_pos=offset.first.index-1-whitespaces_removed; |
|
|
|
|
|
|
|
size_t token_end_pos=offset.second.index-1-whitespaces_removed; |
|
|
|
|
|
|
|
size_t pos=0; |
|
|
|
|
|
|
|
while((pos=line.find('&', pos))!=std::string::npos) { |
|
|
|
|
|
|
|
size_t pos2=line.find(';', pos+2); |
|
|
|
|
|
|
|
if(token_start_pos>pos) { |
|
|
|
|
|
|
|
token_start_pos+=pos2-pos; |
|
|
|
|
|
|
|
token_end_pos+=pos2-pos; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else if(token_end_pos>pos) |
|
|
|
auto end_iter=start_iter; |
|
|
|
token_end_pos+=pos2-pos; |
|
|
|
while(!end_iter.ends_line()) |
|
|
|
else |
|
|
|
end_iter.forward_char(); |
|
|
|
break; |
|
|
|
std::string line=Glib::Markup::escape_text(clang_view->get_buffer()->get_text(start_iter, end_iter)); |
|
|
|
pos=pos2+1; |
|
|
|
|
|
|
|
|
|
|
|
//markup token as bold
|
|
|
|
|
|
|
|
size_t token_start_pos=offset.first.index-1-whitespaces_removed; |
|
|
|
|
|
|
|
size_t token_end_pos=offset.second.index-1-whitespaces_removed; |
|
|
|
|
|
|
|
size_t pos=0; |
|
|
|
|
|
|
|
while((pos=line.find('&', pos))!=std::string::npos) { |
|
|
|
|
|
|
|
size_t pos2=line.find(';', pos+2); |
|
|
|
|
|
|
|
if(token_start_pos>pos) { |
|
|
|
|
|
|
|
token_start_pos+=pos2-pos; |
|
|
|
|
|
|
|
token_end_pos+=pos2-pos; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(token_end_pos>pos) |
|
|
|
|
|
|
|
token_end_pos+=pos2-pos; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
pos=pos2+1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
line.insert(token_end_pos, "</b>"); |
|
|
|
|
|
|
|
line.insert(token_start_pos, "<b>"); |
|
|
|
|
|
|
|
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, clang_view->file_path), line); |
|
|
|
} |
|
|
|
} |
|
|
|
line.insert(token_end_pos, "</b>"); |
|
|
|
|
|
|
|
line.insert(token_start_pos, "<b>"); |
|
|
|
|
|
|
|
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, clang_view->file_path), line); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1277,6 +1286,36 @@ Source::ClangViewRefactor::Token Source::ClangViewRefactor::get_token() { |
|
|
|
return Token(); |
|
|
|
return Token(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Source::ClangViewRefactor::wait_parsing(const std::vector<Source::View*> &views) { |
|
|
|
|
|
|
|
std::unique_ptr<Dialog::Message> message; |
|
|
|
|
|
|
|
std::vector<Source::ClangView*> clang_views; |
|
|
|
|
|
|
|
for(auto &view: views) { |
|
|
|
|
|
|
|
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { |
|
|
|
|
|
|
|
if(!clang_view->parsed) { |
|
|
|
|
|
|
|
clang_views.emplace_back(clang_view); |
|
|
|
|
|
|
|
if(!message) |
|
|
|
|
|
|
|
message=std::unique_ptr<Dialog::Message>(new Dialog::Message("Please wait while all buffers finish parsing")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(message) { |
|
|
|
|
|
|
|
for(;;) { |
|
|
|
|
|
|
|
while(g_main_context_pending(NULL)) |
|
|
|
|
|
|
|
g_main_context_iteration(NULL, false); |
|
|
|
|
|
|
|
bool all_parsed=true; |
|
|
|
|
|
|
|
for(auto &clang_view: clang_views) { |
|
|
|
|
|
|
|
if(!clang_view->parsed) { |
|
|
|
|
|
|
|
all_parsed=false; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(all_parsed) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
message->hide(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) { |
|
|
|
void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) { |
|
|
|
if(parsed) { |
|
|
|
if(parsed) { |
|
|
|
if(token && last_tagged_token!=token) { |
|
|
|
if(token && last_tagged_token!=token) { |
|
|
|
|