Browse Source

Improved false positives in Ctags::get_locations

merge-requests/365/head
eidheim 10 years ago
parent
commit
fca2642798
  1. 103
      src/ctags.cc
  2. 2
      src/ctags.h

103
src/ctags.cc

@ -7,6 +7,7 @@
#include <iostream>
#include <vector>
#include <regex>
#include <climits>
std::pair<boost::filesystem::path, std::unique_ptr<std::stringstream> > Ctags::get_result(const boost::filesystem::path &path) {
auto build=Project::Build::create(path);
@ -103,64 +104,108 @@ Ctags::Location Ctags::get_location(const std::string &line, bool markup) {
return location;
}
std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type) {
//insert name into type
size_t c=0;
size_t bracket_count=0;
for(;c<type.size();++c) {
if(type[c]=='<')
++bracket_count;
else if(type[c]=='>')
--bracket_count;
else if(bracket_count==0 && type[c]=='(')
break;
}
auto full_type=type;
full_type.insert(c, name);
//Split up full_type
///Split up a type into its various significant parts
std::vector<std::string> Ctags::get_type_parts(const std::string type) {
std::vector<std::string> parts;
size_t text_start=-1;
for(size_t c=0;c<full_type.size();++c) {
auto &chr=full_type[c];
for(size_t c=0;c<type.size();++c) {
auto &chr=type[c];
if((chr>='0' && chr<='9') || (chr>='a' && chr<='z') || (chr>='A' && chr<='Z') || chr=='_' || chr=='~') {
if(text_start==static_cast<size_t>(-1))
text_start=c;
}
else {
if(text_start!=static_cast<size_t>(-1))
parts.emplace_back(full_type.substr(text_start, c-text_start));
text_start=-1;
if(text_start!=static_cast<size_t>(-1)) {
parts.emplace_back(type.substr(text_start, c-text_start));
text_start=-1;
}
if(chr=='*' || chr=='&')
parts.emplace_back(std::string()+chr);
}
}
return parts;
}
std::vector<Ctags::Location> Ctags::get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type) {
auto result=get_result(path);
result.second->seekg(0, std::ios::end);
if(result.second->tellg()==0)
return std::vector<Location>();
result.second->seekg(0, std::ios::beg);
//insert name into type
size_t c=0;
size_t bracket_count=0;
for(;c<type.size();++c) {
if(type[c]=='<')
++bracket_count;
else if(type[c]=='>')
--bracket_count;
else if(bracket_count==0 && type[c]=='(')
break;
}
auto full_type=type;
full_type.insert(c, name);
auto parts=get_type_parts(full_type);
//Get short name
std::string short_name;
auto pos=name.rfind(':');
if(pos!=std::string::npos && pos+1<name.size())
short_name=name.substr(pos+1);
else
short_name=name;
std::string line;
size_t best_score=0;
long best_score=LONG_MIN;
std::vector<Location> best_locations;
while(std::getline(*result.second, line)) {
if(line.find(name)==std::string::npos)
//Find function name
auto pos=line.find('\t');
if(pos==std::string::npos)
continue;
auto line_function_name=line.substr(0, pos);
if(line_function_name!=short_name || line.find(name)==std::string::npos)
continue;
auto location=Ctags::get_location(line, false);
location.file_path=result.first/location.file_path;
auto source_parts=get_type_parts(location.source);
//Find match score
size_t score=0;
size_t pos=0;
long score=0;
size_t source_index=0;
for(auto &part: parts) {
auto find_pos=location.source.find(part, pos);
if(find_pos!=std::string::npos) {
pos=find_pos+1;
++score;
bool found=false;
for(auto c=source_index;c<source_parts.size();++c) {
if(part==source_parts[c]) {
source_index=c+1;
++score;
found=true;
break;
}
}
if(!found)
--score;
}
size_t index=0;
for(auto &source_part: source_parts) {
bool found=false;
for(auto c=index;c<parts.size();++c) {
if(source_part==parts[c]) {
index=c+1;
++score;
found=true;
break;
}
}
if(!found)
--score;
}
if(score>best_score) {
best_score=score;
best_locations.clear();

2
src/ctags.h

@ -21,6 +21,8 @@ public:
static Location get_location(const std::string &line, bool markup);
static std::vector<Location> get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type);
private:
static std::vector<std::string> get_type_parts(const std::string type);
};
#endif //JUCI_CTAGS_H_

Loading…
Cancel
Save