diff --git a/src/source_clang.cc b/src/source_clang.cc index 88bf98d..53c2049 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1360,57 +1360,108 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file auto iter=get_buffer()->get_insert()->get_iter(); auto line=static_cast(iter.get_line()); auto index=static_cast(iter.get_line_index()); - for(size_t c=0;csize();++c) { + for(size_t c=clang_tokens->size()-1;c!=static_cast(-1);--c) { auto &token=(*clang_tokens)[c]; if(token.is_identifier()) { auto &token_offsets=clang_tokens_offsets[c]; - if(line==token_offsets.first.line-1 && index>=token_offsets.first.index-1 && index <=token_offsets.second.index-1) { - auto cursor=token.get_cursor(); - auto kind=cursor.get_kind(); - if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod || - kind==clangmm::Cursor::Kind::Constructor || kind==clangmm::Cursor::Kind::Destructor || - kind==clangmm::Cursor::Kind::ConversionFunction) { - auto referenced=cursor.get_referenced(); - if(referenced && referenced==cursor) { - std::string result; - std::string specifier; - if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod) { - result=cursor.get_type().get_result().get_spelling(); + if(line==token_offsets.first.line-1 && index>=token_offsets.first.index-1 && index<=token_offsets.second.index-1) { + auto token_spelling=token.get_spelling(); + if(!token_spelling.empty() && + (token_spelling.size()>1 || (token_spelling.back()>='a' && token_spelling.back()<='z') || + (token_spelling.back()>='A' && token_spelling.back()<='Z') || + token_spelling.back()=='_')) { + auto cursor=token.get_cursor(); + auto kind=cursor.get_kind(); + if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod || + kind==clangmm::Cursor::Kind::Constructor || kind==clangmm::Cursor::Kind::Destructor || + kind==clangmm::Cursor::Kind::ConversionFunction) { + auto referenced=cursor.get_referenced(); + if(referenced && referenced==cursor) { + std::string result; + std::string specifier; + if(kind==clangmm::Cursor::Kind::FunctionDecl || kind==clangmm::Cursor::Kind::CXXMethod) { + auto start_offset=cursor.get_source_range().get_start().get_offset(); + auto end_offset=token_offsets.first; + + // To accurately get result type: + size_t last_c; + int angle_brackets=0; + for(size_t c=0;csize();++c) { + auto &token=(*clang_tokens)[c]; + auto &token_offsets=clang_tokens_offsets[c]; + if((token_offsets.first.line==start_offset.line && token_offsets.second.line!=end_offset.line && token_offsets.first.index>=start_offset.index) || + (token_offsets.first.line>start_offset.line && token_offsets.second.line=start_offset.index && token_offsets.second.index<=end_offset.index)) { + auto token_spelling=token.get_spelling(); + if(token.get_kind()==clangmm::Token::Kind::Identifier) { + if(c==0 || (*clang_tokens)[c-1].get_spelling()!="::") { + auto name=token_spelling; + auto parent=token.get_cursor().get_type().get_cursor().get_semantic_parent(); + while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) { + auto spelling=parent.get_token_spelling(); + name.insert(0, spelling+"::"); + parent=parent.get_semantic_parent(); + } + result+=name; + } + else + result+=token_spelling; + } + else if((token_spelling=="*" || token_spelling=="&") && !result.empty() && result.back()!='*' && result.back()!='&') + result+=' '+token_spelling; + else if(token_spelling=="extern" || token_spelling=="static" || token_spelling=="virtual" || token_spelling=="friend") {} + else if(token_spelling=="," || (token_spelling.size()>1 && token_spelling!="::" && angle_brackets==0)) + result+=token_spelling+' '; + else { + if(token_spelling=="<") + ++angle_brackets; + else if(token_spelling==">") + --angle_brackets; + result+=token_spelling; + } + last_c=c; + } + } + + if(!result.empty() && result.back()!='*' && result.back()!='&' && result.back()!=' ') + result+=' '; + + if(clang_CXXMethod_isConst(cursor.cx_cursor)) + specifier=" const"; + } - if(!result.empty() && result.back()!='*' && result.back()!='&') - result+=' '; + auto name=cursor.get_spelling(); + auto parent=cursor.get_semantic_parent(); + std::vector semantic_parents; + while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) { + auto spelling=parent.get_spelling()+"::"; + if(spelling!="::") { + semantic_parents.emplace_back(spelling); + name.insert(0, spelling); + } + parent=parent.get_semantic_parent(); + } - if(clang_CXXMethod_isConst(cursor.cx_cursor)) - specifier=" const"; - } - - auto name=cursor.get_spelling(); - auto parent=cursor.get_semantic_parent(); - std::vector semantic_parents; - while(parent && parent.get_kind()!=clangmm::Cursor::Kind::TranslationUnit) { - auto spelling=parent.get_spelling()+"::"; - semantic_parents.emplace_back(spelling); - name.insert(0, spelling); - parent=parent.get_semantic_parent(); - } - - std::string arguments; - for(auto &argument_cursor: cursor.get_arguments()) { - auto argument_type=argument_cursor.get_type().get_spelling(); - for(auto it=semantic_parents.rbegin();it!=semantic_parents.rend();++it) { - size_t pos=argument_type.find(*it); - if(pos==0) - argument_type.erase(pos, it->size()); + std::string arguments; + for(auto &argument_cursor: cursor.get_arguments()) { + auto argument_type=argument_cursor.get_type().get_spelling(); + for(auto it=semantic_parents.rbegin();it!=semantic_parents.rend();++it) { + size_t pos=argument_type.find(*it); + if(pos==0) + argument_type.erase(pos, it->size()); + } + auto argument=argument_cursor.get_spelling(); + if(!arguments.empty()) + arguments+=", "; + arguments+=argument_type; + if(!arguments.empty() && arguments.back()!='*' && arguments.back()!='&') + arguments+=' '; + arguments+=argument; } - auto argument=argument_cursor.get_spelling(); - if(!arguments.empty()) - arguments+=", "; - arguments+=argument_type; - if(!arguments.empty() && arguments.back()!='*' && arguments.back()!='&') - arguments+=' '; - arguments+=argument; + return result+name+'('+arguments+")"+specifier+" {}"; } - return result+name+'('+arguments+")"+specifier+" {}"; } } }