diff --git a/src/CodeCompleteResults.cc b/src/CodeCompleteResults.cc index da916f8..e6aea17 100644 --- a/src/CodeCompleteResults.cc +++ b/src/CodeCompleteResults.cc @@ -3,11 +3,9 @@ #include clang::CodeCompleteResults:: -CodeCompleteResults(CXTranslationUnit &cx_tu, - const std::string &file_name, +CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &file_name, const std::map &buffers, - int line_num, - int column) { + unsigned line_num, unsigned column) { std::vector files; for (auto &buffer : buffers) { CXUnsavedFile file; @@ -31,15 +29,15 @@ clang::CodeCompleteResults::~CodeCompleteResults() { delete cx_results; } -int clang::CodeCompleteResults:: +unsigned clang::CodeCompleteResults:: size() { return cx_results->NumResults; } clang::CompletionString clang::CodeCompleteResults:: -get(int i) { +get(unsigned i) { if (i >= size()) { - throw std::invalid_argument("clang::CodeCompleteResults::get(int i): i>=size()"); + throw std::invalid_argument("clang::CodeCompleteResults::get(unsigned i): i>=size()"); } return CompletionString(cx_results->Results[i].CompletionString); } diff --git a/src/CodeCompleteResults.h b/src/CodeCompleteResults.h index dda4d89..e6c8a17 100644 --- a/src/CodeCompleteResults.h +++ b/src/CodeCompleteResults.h @@ -6,15 +6,14 @@ namespace clang { class CodeCompleteResults { - public: - CodeCompleteResults(CXTranslationUnit &cx_tu, - const std::string &file_name, + friend class TranslationUnit; + CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &file_name, const std::map &buffers, - int line_num, - int column); + unsigned line_num, unsigned column); + public: ~CodeCompleteResults(); - CompletionString get(int index); - int size(); + CompletionString get(unsigned index); + unsigned size(); CXCodeCompleteResults *cx_results; }; diff --git a/src/CompileCommand.cc b/src/CompileCommand.cc index 3d98579..0cb8971 100644 --- a/src/CompileCommand.cc +++ b/src/CompileCommand.cc @@ -5,7 +5,7 @@ std::string clang::CompileCommand:: get_command() { std::string res; unsigned N = clang_CompileCommand_getNumArgs(cx_command); - for (int i = 0; i < N; i++) { + for (unsigned i = 0; i < N; i++) { res += clang_getCString(clang_CompileCommand_getArg(cx_command, i)); } return res; @@ -15,7 +15,7 @@ std::vector clang::CompileCommand:: get_command_as_args() { unsigned N = clang_CompileCommand_getNumArgs(cx_command); std::vector res(N); - for (int i = 0; i < N; i++) { + for (unsigned i = 0; i < N; i++) { res[i] = clang_getCString(clang_CompileCommand_getArg(cx_command, i)); } return res; diff --git a/src/CompletionString.cc b/src/CompletionString.cc index 1c0cb88..2d291c1 100644 --- a/src/CompletionString.cc +++ b/src/CompletionString.cc @@ -7,13 +7,13 @@ bool clang::CompletionString::available() { return clang_getCompletionAvailability(cx_str) == CXAvailability_Available; } -int clang::CompletionString::get_num_chunks() { +unsigned clang::CompletionString::get_num_chunks() { return clang_getNumCompletionChunks(cx_str); } std::vector clang::CompletionString::get_chunks() { std::vector res; - for (size_t i = 0; i < get_num_chunks(); i++) { + for (unsigned i = 0; i < get_num_chunks(); i++) { auto cxstr=clang_getCompletionChunkText(cx_str, i); res.emplace_back(clang_getCString(cxstr), static_cast (clang_getCompletionChunkKind(cx_str, i))); clang_disposeString(cxstr); diff --git a/src/CompletionString.h b/src/CompletionString.h index 43d953b..a9d9830 100644 --- a/src/CompletionString.h +++ b/src/CompletionString.h @@ -32,7 +32,7 @@ namespace clang { bool available(); std::vector get_chunks(); std::string get_brief_comments(); - int get_num_chunks(); + unsigned get_num_chunks(); CXCompletionString cx_str; }; diff --git a/src/Cursor.cc b/src/Cursor.cc index 4a7c992..d5be2a2 100644 --- a/src/Cursor.cc +++ b/src/Cursor.cc @@ -19,13 +19,12 @@ std::string clang::Cursor::get_usr() const { return USR; } -std::string clang::Cursor::get_referenced_usr() const { - auto referenced=clang_getCursorReferenced(cx_cursor); - if(!clang_Cursor_isNull(referenced)) { - return Cursor(referenced).get_usr(); - } - else - return ""; +clang::Cursor clang::Cursor::get_referenced() const { + return Cursor(clang_getCursorReferenced(cx_cursor)); +} + +clang::Cursor::operator bool() const { + return !clang_Cursor_isNull(cx_cursor); } bool clang::Cursor::operator==(const Cursor& rhs) const { diff --git a/src/Cursor.h b/src/Cursor.h index ae85534..7c01ca7 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -181,7 +181,8 @@ namespace clang { SourceLocation get_source_location() const; SourceRange get_source_range() const; std::string get_usr() const; - std::string get_referenced_usr() const; + Cursor get_referenced() const; + operator bool() const; bool operator==(const Cursor& rhs) const; CXCursor cx_cursor; }; diff --git a/src/Diagnostic.cc b/src/Diagnostic.cc index f2f4f52..1ff3cfe 100644 --- a/src/Diagnostic.cc +++ b/src/Diagnostic.cc @@ -8,14 +8,13 @@ clang::Diagnostic::Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnos auto cxstr=clang_getDiagnosticSpelling(cx_diagnostic); spelling=clang_getCString(cxstr); clang_disposeString(cxstr); - clang::SourceLocation location(clang_getDiagnosticLocation(cx_diagnostic)); + clang::SourceLocation start_location(clang_getDiagnosticLocation(cx_diagnostic)); - clang::SourceRange range(location, location); - clang::Tokens tokens(cx_tu, range); + path=start_location.get_path(); + unsigned start_offset=start_location.get_offset(); + clang::Tokens tokens(cx_tu, SourceRange(start_location, start_location)); if(tokens.size()==1) { - auto& token=tokens[0]; - auto locations=token.source_range.get_source_locations(); - this->range=SourceRange::get_range_data(location, locations.second); + offsets=std::pair(start_offset, tokens[0].offsets.second); } } diff --git a/src/Diagnostic.h b/src/Diagnostic.h index a01e776..42d3785 100644 --- a/src/Diagnostic.h +++ b/src/Diagnostic.h @@ -7,15 +7,16 @@ namespace clang { class Diagnostic { - public: + friend class TranslationUnit; Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic); - + public: static const std::string get_severity_spelling(unsigned severity); unsigned severity; std::string severity_spelling; std::string spelling; - RangeData range; + std::string path; + std::pair offsets; }; } diff --git a/src/SourceLocation.cc b/src/SourceLocation.cc index 976eb01..62a2d6c 100644 --- a/src/SourceLocation.cc +++ b/src/SourceLocation.cc @@ -3,39 +3,33 @@ // // // // // // // // // SourceLocation // // // // // // // // // -clang::SourceLocation:: -SourceLocation(CXTranslationUnit &tu, - const std::string &filename, - int line_number, - int line_offset) { - CXFile file = clang_getFile(tu, - filename.c_str()); - cx_location = clang_getLocation(tu, - file, - line_number, - line_offset); +clang::SourceLocation::SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset) { + CXFile file = clang_getFile(tu, filepath.c_str()); + cx_location = clang_getLocationForOffset(tu, file, offset); } -clang::SourceLocation:: -SourceLocation(CXTranslationUnit &tu, - const std::string &filepath, - int offset) { - CXFile file = clang_getFile(tu, - filepath.c_str()); - cx_location = clang_getLocationForOffset(tu, - file, - offset); +std::string clang::SourceLocation::get_path() { + std::string path; + get_data(&path, NULL, NULL, NULL); + return path; +} +unsigned clang::SourceLocation::get_offset() { + unsigned offset; + get_data(NULL, NULL, NULL, &offset); + return offset; } -void clang::SourceLocation:: -get_location_info(std::string* path, - unsigned *line, - unsigned *column, - unsigned *offset) { - CXFile file; - clang_getExpansionLocation(cx_location, &file, line, column, offset); - if (path != NULL && file!=NULL) { - path->operator=(((clang_getCString((clang_getFileName(file)))))); - } +void clang::SourceLocation::get_data(std::string* path, unsigned *line, unsigned *column, unsigned *offset) { + if(path==nullptr) + clang_getExpansionLocation(cx_location, NULL, line, column, offset); + else { + CXFile file; + clang_getExpansionLocation(cx_location, &file, line, column, offset); + if (file!=NULL) { + auto cxstr=clang_getFileName(file); + *path=clang_getCString(cxstr); + clang_disposeString(cxstr); + } + } } diff --git a/src/SourceLocation.h b/src/SourceLocation.h index 0837dc1..9f29b99 100644 --- a/src/SourceLocation.h +++ b/src/SourceLocation.h @@ -6,24 +6,19 @@ namespace clang { class SourceLocation { + friend class TranslationUnit; + SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset); public: SourceLocation(const CXSourceLocation& cx_location) : cx_location(cx_location) {} - - SourceLocation(CXTranslationUnit &cx_tu, - const std::string &filename, - int line_number, - int column); - - SourceLocation(CXTranslationUnit &tu, - const std::string &filepath, - int offset); - void get_location_info(std::string *path, - unsigned *line, - unsigned *column, - unsigned *offset); + public: + std::string get_path(); + unsigned get_offset(); CXSourceLocation cx_location; + + private: + void get_data(std::string *path, unsigned *line, unsigned *column, unsigned *offset); }; } // namespace clang diff --git a/src/SourceRange.cc b/src/SourceRange.cc index ae3bd24..5c97323 100644 --- a/src/SourceRange.cc +++ b/src/SourceRange.cc @@ -5,23 +5,10 @@ SourceRange(clang::SourceLocation &start, clang::SourceLocation &end) { cx_range = clang_getRange(start.cx_location, end.cx_location); } -std::pair clang::SourceRange::get_source_locations() { - return std::pair(clang_getRangeStart(cx_range), clang_getRangeEnd(cx_range)); -} - -clang::RangeData clang::SourceRange::get_range_data(clang::SourceLocation &start, clang::SourceLocation &end) { - std::string path; - unsigned start_offset, end_offset; - start.get_location_info(&path, NULL, NULL, &start_offset); - end.get_location_info(NULL, NULL, NULL, &end_offset); - RangeData range_data; - range_data.path=path; - range_data.start_offset=start_offset; - range_data.end_offset=end_offset; - return range_data; -} - -clang::RangeData clang::SourceRange::get_range_data() { - auto locations=get_source_locations(); - return get_range_data(locations.first, locations.second); +std::pair clang::SourceRange::get_offsets() { + SourceLocation start(clang_getRangeStart(cx_range)), end(clang_getRangeEnd(cx_range)); + std::pair offsets; + offsets.first=start.get_offset(); + offsets.second=end.get_offset(); + return offsets; } \ No newline at end of file diff --git a/src/SourceRange.h b/src/SourceRange.h index 7a85504..c39eb18 100644 --- a/src/SourceRange.h +++ b/src/SourceRange.h @@ -3,21 +3,14 @@ #include #include "SourceLocation.h" #include +#include namespace clang { - class RangeData { - public: - std::string path; - unsigned start_offset, end_offset; - }; - class SourceRange { public: SourceRange(const CXSourceRange& cx_range) : cx_range(cx_range) {} SourceRange(SourceLocation &start, SourceLocation &end); - std::pair get_source_locations(); - static RangeData get_range_data(SourceLocation &start, SourceLocation &end); - RangeData get_range_data(); + std::pair get_offsets(); CXSourceRange cx_range; }; } // namespace clang diff --git a/src/Token.cc b/src/Token.cc index 30f2c54..ce3da9b 100644 --- a/src/Token.cc +++ b/src/Token.cc @@ -15,12 +15,12 @@ clang::SourceRange clang::Token::get_source_range() { return SourceRange(clang_getTokenExtent(cx_tu, cx_token)); } // returns a string description of this tokens kind -std::string clang::Token::get_token_spelling() { +std::string clang::Token::get_spelling() { CXString s = clang_getTokenSpelling(cx_tu, cx_token); return std::string(clang_getCString(s)); } -const clang::TokenKind clang::Token::kind() { +const clang::TokenKind clang::Token::get_kind() { return (TokenKind) clang_getTokenKind(cx_token); } @@ -59,6 +59,7 @@ std::string clang::Token::get_type() { return spelling; } +//TODO: use clang_Cursor_getBriefCommentText std::string clang::Token::get_brief_comments() { std::string comment_string; auto referenced=clang_getCursorReferenced(cx_cursor); diff --git a/src/Token.h b/src/Token.h index d88817f..15ded6c 100644 --- a/src/Token.h +++ b/src/Token.h @@ -16,12 +16,14 @@ namespace clang { }; class Token { - public: + friend class Tokens; Token(CXTranslationUnit &cx_tu, CXToken &cx_token, CXCursor &cx_cursor): - cx_tu(cx_tu), cx_token(cx_token), cx_cursor(cx_cursor), source_range(get_source_range()) {}; - const TokenKind kind(); - std::string get_token_spelling(); + cx_tu(cx_tu), cx_token(cx_token), cx_cursor(cx_cursor), offsets(get_source_range().get_offsets()) {}; + public: + const TokenKind get_kind(); + std::string get_spelling(); SourceLocation get_source_location(); + SourceRange get_source_range(); clang::Cursor get_cursor() {return clang::Cursor(cx_cursor);} bool has_type(); std::string get_type(); @@ -29,9 +31,7 @@ namespace clang { CXTranslationUnit &cx_tu; CXToken& cx_token; CXCursor& cx_cursor; - SourceRange source_range; - private: - SourceRange get_source_range(); + std::pair offsets; }; } // namespace clang #endif // TOKEN_H_ diff --git a/src/Tokens.cc b/src/Tokens.cc index 390948c..b62b982 100644 --- a/src/Tokens.cc +++ b/src/Tokens.cc @@ -2,14 +2,13 @@ #include using namespace std; -clang::Tokens::Tokens(CXTranslationUnit &cx_tu, SourceRange &range): cx_tu(cx_tu) { - +clang::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range): cx_tu(cx_tu) { clang_tokenize(cx_tu, range.cx_range, &cx_tokens, &num_tokens); cx_cursors.clear(); cx_cursors.reserve(num_tokens); clang_annotateTokens(cx_tu, cx_tokens, num_tokens, cx_cursors.data()); - for (int i = 0; i < num_tokens; i++) { - emplace_back(cx_tu, cx_tokens[i], cx_cursors[i]); + for (unsigned i = 0; i < num_tokens; i++) { + emplace_back(Token(cx_tu, cx_tokens[i], cx_cursors[i])); } } @@ -22,14 +21,57 @@ clang::Tokens::~Tokens() { //Similar tokens defined as tokens with equal referenced cursors. std::vector > clang::Tokens::get_similar_token_offsets(clang::Token& token) { std::vector > offsets; - auto referenced_usr=token.get_cursor().get_referenced_usr(); - if(referenced_usr!="") { + auto referenced=token.get_cursor().get_referenced(); + if(referenced) { + auto referenced_usr=referenced.get_usr(); for(auto &a_token: *this) { - if(referenced_usr==a_token.get_cursor().get_referenced_usr() && token.get_token_spelling()==a_token.get_token_spelling()) { - auto range_data=a_token.source_range.get_range_data(); - offsets.emplace_back(range_data.start_offset, range_data.end_offset); + auto a_referenced=a_token.get_cursor().get_referenced(); + if(a_referenced && referenced_usr==a_referenced.get_usr() && token.get_spelling()==a_token.get_spelling()) { + offsets.emplace_back(a_token.offsets); } } } return offsets; } + +std::vector > clang::Tokens::get_cxx_methods() { + std::vector > methods; + long last_offset=-1; + for(auto &token: *this) { + if(token.get_kind()==clang::Token_Identifier) { + auto cursor=token.get_cursor(); + auto kind=cursor.get_kind(); + if(kind==clang::CursorKind::CXXMethod || kind==clang::CursorKind::Constructor || kind==clang::CursorKind::Destructor) { + auto offset=cursor.get_source_location().get_offset(); + if(offset!=last_offset) { + std::string method; + CXString cxstr; + if(kind==clang::CursorKind::CXXMethod) { + auto type=clang_getResultType(clang_getCursorType(cursor.cx_cursor)); + auto cxstr=clang_getTypeSpelling(type); + method+=clang_getCString(cxstr); + clang_disposeString(cxstr); + auto pos=method.find(" "); + if(pos!=std::string::npos) + method.erase(pos, 1); + method+=" "; + } + + clang::Cursor parent(clang_getCursorSemanticParent(cursor.cx_cursor)); + cxstr=clang_getCursorDisplayName(parent.cx_cursor); + method+=clang_getCString(cxstr); + clang_disposeString(cxstr); + + method+="::"; + + cxstr=clang_getCursorDisplayName(cursor.cx_cursor); + method+=clang_getCString(cxstr); + clang_disposeString(cxstr); + methods.emplace_back(method, offset); + } + last_offset=offset; + } + } + } + return methods; +} diff --git a/src/Tokens.h b/src/Tokens.h index 81693d1..96366cd 100644 --- a/src/Tokens.h +++ b/src/Tokens.h @@ -8,10 +8,13 @@ namespace clang { class Tokens : public std::vector { + friend class TranslationUnit; + friend class Diagnostic; + Tokens(CXTranslationUnit &cx_tu, const SourceRange &range); public: - Tokens(CXTranslationUnit &cx_tu, SourceRange &range); ~Tokens(); std::vector > get_similar_token_offsets(clang::Token& token); + std::vector > get_cxx_methods(); private: CXToken *cx_tokens; unsigned num_tokens; diff --git a/src/TranslationUnit.cc b/src/TranslationUnit.cc index 37f8104..edd2bde 100644 --- a/src/TranslationUnit.cc +++ b/src/TranslationUnit.cc @@ -90,7 +90,7 @@ unsigned clang::TranslationUnit::DefaultFlags() { return CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; } -clang::CodeCompleteResults clang::TranslationUnit::get_code_completions(const std::map &buffers, int line_number, int column) { +clang::CodeCompleteResults clang::TranslationUnit::get_code_completions(const std::map &buffers, unsigned line_number, unsigned column) { auto cxstr=clang_getTranslationUnitSpelling(cx_tu); std::string path=clang_getCString(cxstr); clang_disposeString(cxstr); diff --git a/src/TranslationUnit.h b/src/TranslationUnit.h index 8bf2563..e10d465 100644 --- a/src/TranslationUnit.h +++ b/src/TranslationUnit.h @@ -35,7 +35,7 @@ namespace clang { const std::map &buffers, unsigned flags=DefaultFlags()); - clang::CodeCompleteResults get_code_completions(const std::map &buffers, int line_number, int column); + clang::CodeCompleteResults get_code_completions(const std::map &buffers, unsigned line_number, unsigned column); std::vector get_diagnostics(); std::unique_ptr get_tokens(unsigned start_offset, unsigned end_offset); clang::Cursor get_cursor(std::string path, unsigned offset); diff --git a/tests/CodeCompleteResults_H_Test.cc b/tests/CodeCompleteResults_H_Test.cc index d2e880f..bb75e07 100644 --- a/tests/CodeCompleteResults_H_Test.cc +++ b/tests/CodeCompleteResults_H_Test.cc @@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE(code_complete_results) { auto results=tu.get_code_completions(buffers, 4, 5); bool substr_found=false; - for(int c=0;csize() == 32); - BOOST_CHECK((*tokens)[1].kind() == clang::TokenKind::Token_Identifier); + BOOST_CHECK((*tokens)[1].get_kind() == clang::TokenKind::Token_Identifier); - std::string str = (*tokens)[28].get_token_spelling(); + std::string str = (*tokens)[28].get_spelling(); BOOST_CHECK(str == "return"); }