diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a1ae1c..478c921 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,7 @@ message("Searcing for libclang") find_package(LibClang REQUIRED) set(header_files - clangmm.h + clangmm.h CodeCompleteResults.h CompilationDatabase.h CompileCommand.h diff --git a/src/CodeCompleteResults.cc b/src/CodeCompleteResults.cc index 6a281e8..da916f8 100644 --- a/src/CodeCompleteResults.cc +++ b/src/CodeCompleteResults.cc @@ -3,7 +3,7 @@ #include clang::CodeCompleteResults:: -CodeCompleteResults(clang::TranslationUnit *tu, +CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &file_name, const std::map &buffers, int line_num, @@ -16,24 +16,24 @@ CodeCompleteResults(clang::TranslationUnit *tu, file.Length = buffer.second.size(); files.push_back(file); } - results_ = clang_codeCompleteAt(tu->tu_, + cx_results = clang_codeCompleteAt(cx_tu, file_name.c_str(), line_num, column, files.data(), files.size(), clang_defaultCodeCompleteOptions()|CXCodeComplete_IncludeBriefComments); - clang_sortCodeCompletionResults(results_->Results, results_->NumResults); + clang_sortCodeCompletionResults(cx_results->Results, cx_results->NumResults); } clang::CodeCompleteResults::~CodeCompleteResults() { - delete[] results_->Results; - delete results_; + delete[] cx_results->Results; + delete cx_results; } int clang::CodeCompleteResults:: size() { - return results_->NumResults; + return cx_results->NumResults; } clang::CompletionString clang::CodeCompleteResults:: @@ -41,5 +41,5 @@ get(int i) { if (i >= size()) { throw std::invalid_argument("clang::CodeCompleteResults::get(int i): i>=size()"); } - return CompletionString(results_->Results[i].CompletionString); + return CompletionString(cx_results->Results[i].CompletionString); } diff --git a/src/CodeCompleteResults.h b/src/CodeCompleteResults.h index 8446a74..dda4d89 100644 --- a/src/CodeCompleteResults.h +++ b/src/CodeCompleteResults.h @@ -1,14 +1,13 @@ #ifndef CODECOMPLETERESULTS_H_ #define CODECOMPLETERESULTS_H_ #include -#include "TranslationUnit.h" +#include +#include "CompletionString.h" namespace clang { - class CompletionString; - class CodeCompleteResults { public: - CodeCompleteResults(TranslationUnit *tu, + CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &file_name, const std::map &buffers, int line_num, @@ -17,8 +16,7 @@ namespace clang { CompletionString get(int index); int size(); - private: - CXCodeCompleteResults *results_; + CXCodeCompleteResults *cx_results; }; } // namespace clang #endif // CODECOMPLETERESULTS_H_ diff --git a/src/CompilationDatabase.cc b/src/CompilationDatabase.cc index 183570f..cdcc099 100644 --- a/src/CompilationDatabase.cc +++ b/src/CompilationDatabase.cc @@ -4,7 +4,7 @@ clang::CompilationDatabase:: CompilationDatabase(const std::string &project_path) { CXCompilationDatabase_Error error; - db_ = clang_CompilationDatabase_fromDirectory(project_path.c_str(), &error); + cx_db = clang_CompilationDatabase_fromDirectory(project_path.c_str(), &error); if(error) { //TODO: compile_commands.json is missing, create it? } @@ -12,5 +12,5 @@ CompilationDatabase(const std::string &project_path) { clang::CompilationDatabase:: ~CompilationDatabase() { - clang_CompilationDatabase_dispose(db_); + clang_CompilationDatabase_dispose(cx_db); } diff --git a/src/CompilationDatabase.h b/src/CompilationDatabase.h index 8d66a57..0527fdf 100644 --- a/src/CompilationDatabase.h +++ b/src/CompilationDatabase.h @@ -5,15 +5,13 @@ #include namespace clang { - class CompileCommands; class CompilationDatabase { public: explicit CompilationDatabase(const std::string &project_path); CompilationDatabase(); ~CompilationDatabase(); - private: - CXCompilationDatabase db_; - friend CompileCommands; + + CXCompilationDatabase cx_db; }; } diff --git a/src/CompileCommand.cc b/src/CompileCommand.cc index 0582e8d..3d98579 100644 --- a/src/CompileCommand.cc +++ b/src/CompileCommand.cc @@ -1,27 +1,22 @@ #include "CompileCommand.h" #include "CompileCommands.h" -clang::CompileCommand:: -CompileCommand(int nth, clang::CompileCommands *commands) { - command_ = clang_CompileCommands_getCommand(commands->commands_, nth); -} - std::string clang::CompileCommand:: get_command() { std::string res; - unsigned N = clang_CompileCommand_getNumArgs(command_); + unsigned N = clang_CompileCommand_getNumArgs(cx_command); for (int i = 0; i < N; i++) { - res += clang_getCString(clang_CompileCommand_getArg(command_, i)); + res += clang_getCString(clang_CompileCommand_getArg(cx_command, i)); } return res; } std::vector clang::CompileCommand:: get_command_as_args() { - unsigned N = clang_CompileCommand_getNumArgs(command_); + unsigned N = clang_CompileCommand_getNumArgs(cx_command); std::vector res(N); for (int i = 0; i < N; i++) { - res[i] = clang_getCString(clang_CompileCommand_getArg(command_, i)); + res[i] = clang_getCString(clang_CompileCommand_getArg(cx_command, i)); } return res; } diff --git a/src/CompileCommand.h b/src/CompileCommand.h index f56dac8..582d2b4 100644 --- a/src/CompileCommand.h +++ b/src/CompileCommand.h @@ -1,16 +1,17 @@ #ifndef COMPILECOMMAND_H_ #define COMPILECOMMAND_H_ -#include "CompilationDatabase.h" +#include #include +#include namespace clang { class CompileCommand { public: - CompileCommand(int nth, CompileCommands *commands); + CompileCommand(const CXCompileCommand& cx_command) : cx_command(cx_command) {}; std::string get_command(); std::vector get_command_as_args(); - private: - CXCompileCommand command_; + + CXCompileCommand cx_command; }; } #endif // COMPILECOMMAND_H_ diff --git a/src/CompileCommands.cc b/src/CompileCommands.cc index 42a7095..2b5494b 100644 --- a/src/CompileCommands.cc +++ b/src/CompileCommands.cc @@ -1,24 +1,24 @@ #include "CompileCommands.h" clang::CompileCommands:: -CompileCommands(const std::string &filename, CompilationDatabase *db) { - commands_ = - clang_CompilationDatabase_getCompileCommands(db->db_, filename.c_str()); - if(clang_CompileCommands_getSize(commands_)==0) - commands_ = clang_CompilationDatabase_getAllCompileCommands(db->db_); +CompileCommands(const std::string &filename, CompilationDatabase &db) { + cx_commands = + clang_CompilationDatabase_getCompileCommands(db.cx_db, filename.c_str()); + if(clang_CompileCommands_getSize(cx_commands)==0) + cx_commands = clang_CompilationDatabase_getAllCompileCommands(db.cx_db); } clang::CompileCommands:: ~CompileCommands() { - clang_CompileCommands_dispose(commands_); + clang_CompileCommands_dispose(cx_commands); } std::vector clang::CompileCommands:: get_commands() { - unsigned N = clang_CompileCommands_getSize(commands_); + unsigned N = clang_CompileCommands_getSize(cx_commands); std::vector res; for (unsigned i = 0; i < N; i++) { - res.emplace_back(clang::CompileCommand(i, this)); + res.emplace_back(clang_CompileCommands_getCommand(cx_commands, i)); } return res; } diff --git a/src/CompileCommands.h b/src/CompileCommands.h index f56d859..f822d18 100644 --- a/src/CompileCommands.h +++ b/src/CompileCommands.h @@ -9,12 +9,11 @@ namespace clang { class CompileCommands { public: - CompileCommands(const std::string &filename, CompilationDatabase *db); + CompileCommands(const std::string &filename, CompilationDatabase &db); std::vector get_commands(); ~CompileCommands(); - private: - CXCompileCommands commands_; - friend class CompileCommand; + + CXCompileCommands cx_commands; }; } #endif // COMPILECOMMANDS_H_ diff --git a/src/CompletionString.cc b/src/CompletionString.cc index 68cc0f4..1c0cb88 100644 --- a/src/CompletionString.cc +++ b/src/CompletionString.cc @@ -1,23 +1,21 @@ #include "CompletionString.h" clang::CompletionString:: -CompletionString(const CXCompletionString &str) { - str_ = str; -} +CompletionString(const CXCompletionString &cx_str) : cx_str(cx_str) {} bool clang::CompletionString::available() { - return clang_getCompletionAvailability(str_) == CXAvailability_Available; + return clang_getCompletionAvailability(cx_str) == CXAvailability_Available; } int clang::CompletionString::get_num_chunks() { - return clang_getNumCompletionChunks(str_); + return clang_getNumCompletionChunks(cx_str); } std::vector clang::CompletionString::get_chunks() { std::vector res; for (size_t i = 0; i < get_num_chunks(); i++) { - auto cxstr=clang_getCompletionChunkText(str_, i); - res.emplace_back(clang_getCString(cxstr), static_cast (clang_getCompletionChunkKind(str_, i))); + auto cxstr=clang_getCompletionChunkText(cx_str, i); + res.emplace_back(clang_getCString(cxstr), static_cast (clang_getCompletionChunkKind(cx_str, i))); clang_disposeString(cxstr); } return res; @@ -25,7 +23,7 @@ std::vector clang::CompletionString::get_chunks() { std::string clang::CompletionString::get_brief_comments() { std::string brief_comments; - auto cxstr=clang_getCompletionBriefComment(str_); + auto cxstr=clang_getCompletionBriefComment(cx_str); if(cxstr.data!=NULL) { brief_comments=clang_getCString(cxstr); clang_disposeString(cxstr); diff --git a/src/CompletionString.h b/src/CompletionString.h index eee7013..43d953b 100644 --- a/src/CompletionString.h +++ b/src/CompletionString.h @@ -1,7 +1,8 @@ #ifndef COMPLETIONSTRING_H_ #define COMPLETIONSTRING_H_ #include -#include "CodeCompleteResults.h" +#include +#include namespace clang { enum CompletionChunkKind { @@ -27,14 +28,13 @@ namespace clang { class CompletionString { public: + explicit CompletionString(const CXCompletionString &cx_str); bool available(); std::vector get_chunks(); std::string get_brief_comments(); int get_num_chunks(); - private: - explicit CompletionString(const CXCompletionString &str); - CXCompletionString str_; - friend CodeCompleteResults; + + CXCompletionString cx_str; }; } // namespace clang #endif // COMPLETIONSTRING_H_ diff --git a/src/Cursor.cc b/src/Cursor.cc index e6ab0b7..0f5f56c 100644 --- a/src/Cursor.cc +++ b/src/Cursor.cc @@ -1,10 +1,24 @@ #include "Cursor.h" -const clang::CursorKind clang::Cursor::kind() { - return (CursorKind) clang_getCursorKind(this->cursor_); +const clang::CursorKind clang::Cursor::get_kind() { + return (CursorKind) clang_getCursorKind(this->cx_cursor); } clang::Cursor:: -Cursor(clang::TranslationUnit *tu, clang::SourceLocation *source_location) { - cursor_ = clang_getCursor(tu->tu_, source_location->location_); +Cursor(CXTranslationUnit &cx_tu, clang::SourceLocation &source_location) { + cx_cursor = clang_getCursor(cx_tu, source_location.cx_location); } + +clang::SourceLocation clang::Cursor::get_source_location() const { + return SourceLocation(clang_getCursorLocation(cx_cursor)); +} + +clang::SourceRange clang::Cursor::get_source_range() const { + return SourceRange(clang_getCursorExtent(cx_cursor)); +} + +bool clang::Cursor::operator==(const Cursor& rhs) const { + auto lhs_rd=get_source_range().get_range_data(); + auto rhs_rd=rhs.get_source_range().get_range_data(); + return lhs_rd.path==rhs_rd.path && lhs_rd.start_offset==rhs_rd.start_offset && lhs_rd.end_offset==rhs_rd.end_offset; +} \ No newline at end of file diff --git a/src/Cursor.h b/src/Cursor.h index 5740226..4b5fc10 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -1,9 +1,10 @@ #ifndef CURSOR_H_ #define CURSOR_H_ -#include "TranslationUnit.h" +#include #include "SourceLocation.h" +#include "SourceRange.h" -namespace clang { +namespace clang { enum class CursorKind { UnexposedDecl = 1, StructDecl = 2, @@ -174,14 +175,13 @@ namespace clang { class Cursor { public: - Cursor() {} - Cursor(TranslationUnit *tu, SourceLocation *source_location); - const CursorKind kind(); - private: - CXCursor cursor_; - friend SourceRange; - friend SourceLocation; - friend Tokens; + Cursor(const CXCursor &cx_cursor) : cx_cursor(cx_cursor) {} + Cursor(CXTranslationUnit &cx_tu, SourceLocation &source_location); + const CursorKind get_kind(); + SourceLocation get_source_location() const; + SourceRange get_source_range() const; + bool operator==(const Cursor& rhs) const; + CXCursor cx_cursor; }; } // namespace clang #endif // CURSOR_H_ diff --git a/src/Diagnostic.cc b/src/Diagnostic.cc index 5712527..bc9bc8b 100644 --- a/src/Diagnostic.cc +++ b/src/Diagnostic.cc @@ -2,29 +2,18 @@ #include "SourceLocation.h" #include "Tokens.h" -clang::Diagnostic::Diagnostic(clang::TranslationUnit& tu, CXDiagnostic& clang_diagnostic) { - severity=clang_getDiagnosticSeverity(clang_diagnostic); +clang::Diagnostic::Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic) { + severity=clang_getDiagnosticSeverity(cx_diagnostic); severity_spelling=get_severity_spelling(severity); - spelling=clang_getCString(clang_getDiagnosticSpelling(clang_diagnostic)); - clang::SourceLocation location(clang_getDiagnosticLocation(clang_diagnostic)); - std::string tmp_path; - unsigned line, column, offset; - location.get_location_info(&tmp_path, &line, &column, &offset); - path=tmp_path; - start_location.line=line; - start_location.column=column; - start_location.offset=offset; + spelling=clang_getCString(clang_getDiagnosticSpelling(cx_diagnostic)); + clang::SourceLocation location(clang_getDiagnosticLocation(cx_diagnostic)); - clang::SourceRange range(&location, &location); - clang::Tokens tokens(&tu, &range); + clang::SourceRange range(location, location); + clang::Tokens tokens(cx_tu, range); if(tokens.size()==1) { auto& token=tokens[0]; - clang::SourceRange range=token.get_source_range(&tu); - clang::SourceLocation location(&range, false); - location.get_location_info(NULL, &line, &column, &offset); - end_location.line=line; - end_location.column=column; - end_location.offset=offset; + auto locations=token.source_range.get_source_locations(); + this->range=SourceRange::get_range_data(location, locations.second); } } diff --git a/src/Diagnostic.h b/src/Diagnostic.h index c858d33..a01e776 100644 --- a/src/Diagnostic.h +++ b/src/Diagnostic.h @@ -3,25 +3,19 @@ #include #include #include -#include "TranslationUnit.h" +#include "SourceRange.h" -namespace clang { +namespace clang { class Diagnostic { public: - class LocationData { - public: - unsigned line, column, offset; - }; - - Diagnostic(clang::TranslationUnit& tu, CXDiagnostic& clang_diagnostic); + Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic); static const std::string get_severity_spelling(unsigned severity); unsigned severity; std::string severity_spelling; std::string spelling; - std::string path; - LocationData start_location, end_location; + RangeData range; }; } diff --git a/src/Index.cc b/src/Index.cc index 89c1313..8208c7d 100644 --- a/src/Index.cc +++ b/src/Index.cc @@ -2,6 +2,6 @@ clang::Index:: Index(int excludeDeclarationsFromPCH, int displayDiagnostics) { - index_ = clang_createIndex(excludeDeclarationsFromPCH, + cx_index = clang_createIndex(excludeDeclarationsFromPCH, displayDiagnostics); } diff --git a/src/Index.h b/src/Index.h index f93feab..5ac32d0 100644 --- a/src/Index.h +++ b/src/Index.h @@ -1,16 +1,12 @@ #ifndef INDEX_H_ #define INDEX_H_ - #include namespace clang { - class TranslationUnit; class Index { public: Index(int excludeDeclarationsFromPCH, int displayDiagnostics); - private: - CXIndex index_; - friend TranslationUnit; + CXIndex cx_index; }; } // namespace clang #endif // INDEX_H_ diff --git a/src/SourceLocation.cc b/src/SourceLocation.cc index c68d32f..976eb01 100644 --- a/src/SourceLocation.cc +++ b/src/SourceLocation.cc @@ -4,43 +4,25 @@ // SourceLocation // // // // // // // // // clang::SourceLocation:: -SourceLocation(clang::TranslationUnit *tu, +SourceLocation(CXTranslationUnit &tu, const std::string &filename, int line_number, int line_offset) { - CXFile file = clang_getFile(tu->tu_, + CXFile file = clang_getFile(tu, filename.c_str()); - location_ = clang_getLocation(tu->tu_, + cx_location = clang_getLocation(tu, file, line_number, line_offset); - } - -clang::SourceLocation:: -SourceLocation(Cursor *cursor) { - location_ = clang_getCursorLocation(cursor->cursor_); -} - -clang::SourceLocation:: -SourceLocation(clang::SourceRange *range, bool start) { - location_ = start ? clang_getRangeStart(range->range_) : - clang_getRangeEnd(range->range_); -} - -clang::SourceLocation:: -SourceLocation(TranslationUnit *tu, - Token *token) { - location_ = clang_getTokenLocation(tu->tu_, - token->token_); } clang::SourceLocation:: -SourceLocation(clang::TranslationUnit *tu, +SourceLocation(CXTranslationUnit &tu, const std::string &filepath, int offset) { - CXFile file = clang_getFile(tu->tu_, + CXFile file = clang_getFile(tu, filepath.c_str()); - location_ = clang_getLocationForOffset(tu->tu_, + cx_location = clang_getLocationForOffset(tu, file, offset); } @@ -51,7 +33,7 @@ get_location_info(std::string* path, unsigned *column, unsigned *offset) { CXFile file; - clang_getExpansionLocation(location_, &file, line, column, offset); + clang_getExpansionLocation(cx_location, &file, line, column, offset); if (path != NULL && file!=NULL) { path->operator=(((clang_getCString((clang_getFileName(file)))))); } diff --git a/src/SourceLocation.h b/src/SourceLocation.h index 286ddbb..0837dc1 100644 --- a/src/SourceLocation.h +++ b/src/SourceLocation.h @@ -1,39 +1,29 @@ #ifndef SOURCELOCATION_H_ #define SOURCELOCATION_H_ -#include "TranslationUnit.h" -#include "Token.h" -#include "Cursor.h" +#include +#include namespace clang { + class SourceLocation { public: - SourceLocation(TranslationUnit* tu, + SourceLocation(const CXSourceLocation& cx_location) : cx_location(cx_location) {} + + SourceLocation(CXTranslationUnit &cx_tu, const std::string &filename, int line_number, int column); - SourceLocation(TranslationUnit *tu, - Token *token); - - SourceLocation(SourceRange *range, bool start); - - SourceLocation(TranslationUnit *tu, + SourceLocation(CXTranslationUnit &tu, const std::string &filepath, int offset); - SourceLocation(CXSourceLocation location) {location_=location;} - - explicit SourceLocation(Cursor *cursor); - - void get_location_info(std::string* path, + void get_location_info(std::string *path, unsigned *line, unsigned *column, unsigned *offset); - private: - CXSourceLocation location_; - friend SourceRange; - friend Cursor; + CXSourceLocation cx_location; }; } // namespace clang diff --git a/src/SourceRange.cc b/src/SourceRange.cc index 87581d4..ae3bd24 100644 --- a/src/SourceRange.cc +++ b/src/SourceRange.cc @@ -1,15 +1,27 @@ #include "SourceRange.h" clang::SourceRange:: -SourceRange(clang::TranslationUnit *tu, clang::Token *token) { - range_ = clang_getTokenExtent(tu->tu_, token->token_); +SourceRange(clang::SourceLocation &start, clang::SourceLocation &end) { + cx_range = clang_getRange(start.cx_location, end.cx_location); } -clang::SourceRange:: -SourceRange(clang::SourceLocation *start, clang::SourceLocation *end) { - range_ = clang_getRange(start->location_, end->location_); +std::pair clang::SourceRange::get_source_locations() { + return std::pair(clang_getRangeStart(cx_range), clang_getRangeEnd(cx_range)); } -clang::SourceRange::SourceRange(Cursor *cursor) { - range_ = clang_getCursorExtent(cursor->cursor_); +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); +} \ No newline at end of file diff --git a/src/SourceRange.h b/src/SourceRange.h index d1f772b..7a85504 100644 --- a/src/SourceRange.h +++ b/src/SourceRange.h @@ -1,23 +1,24 @@ #ifndef SOURCERANGE_H_ #define SOURCERANGE_H_ -#include "TranslationUnit.h" -#include "Token.h" -#include "Cursor.h" +#include +#include "SourceLocation.h" +#include -namespace clang { +namespace clang { + class RangeData { + public: + std::string path; + unsigned start_offset, end_offset; + }; + class SourceRange { public: - SourceRange() {} - SourceRange(TranslationUnit *tu, Token *token); - SourceRange(SourceLocation *start, - SourceLocation *end); - explicit SourceRange(Cursor *cursor); - - private: - CXSourceRange range_; - friend Tokens; - friend SourceLocation; - friend Diagnostic; + 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(); + CXSourceRange cx_range; }; } // namespace clang #endif // SOURCERANGE_H_ diff --git a/src/Token.cc b/src/Token.cc index 455da1a..8cd376e 100644 --- a/src/Token.cc +++ b/src/Token.cc @@ -4,29 +4,110 @@ // Token // // // // // // -// clang::Token instansiates an token -clang::Token::Token(const CXToken &token) : - token_(token) { -} - // returns gets an source location for this token objekt // based on the translationunit given -clang::SourceLocation clang::Token:: - get_source_location(clang::TranslationUnit *tu) { - return SourceLocation(tu, this); +clang::SourceLocation clang::Token::get_source_location() { + return SourceLocation(clang_getTokenLocation(cx_tu, cx_token)); } // returns a sourcerange that covers this token -clang::SourceRange clang::Token:: - get_source_range(clang::TranslationUnit *tu) { - return SourceRange(tu, this); +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(clang::TranslationUnit *tu) { - CXString s = clang_getTokenSpelling(tu->tu_, token_); +std::string clang::Token::get_token_spelling() { + CXString s = clang_getTokenSpelling(cx_tu, cx_token); return std::string(clang_getCString(s)); } const clang::TokenKind clang::Token::kind() { - return (TokenKind) clang_getTokenKind(token_); + return (TokenKind) clang_getTokenKind(cx_token); +} + +bool clang::Token::has_type() { + auto referenced=clang_getCursorReferenced(cx_cursor); + if(clang_Cursor_isNull(referenced)) + return false; + auto type=clang_getCursorType(referenced); + auto cxstr=clang_getTypeSpelling(type); + std::string spelling=clang_getCString(cxstr); + clang_disposeString(cxstr); + return spelling!=""; +} + +std::string clang::Token::get_type() { + std::string spelling; + auto referenced=clang_getCursorReferenced(cx_cursor); + if(!clang_Cursor_isNull(referenced)) { + auto type=clang_getCursorType(referenced); + auto cxstr=clang_getTypeSpelling(type); + spelling=clang_getCString(cxstr); + clang_disposeString(cxstr); + std::string auto_end=""; + //TODO fix const auto + if((spelling.size()>=4 && spelling.substr(0, 4)=="auto")) { + auto_end=spelling.substr(4); + auto type=clang_getCanonicalType(clang_getCursorType(cx_cursor)); + auto cxstr=clang_getTypeSpelling(type); + spelling=clang_getCString(cxstr); + clang_disposeString(cxstr); + if(spelling.find(" ")==std::string::npos) + spelling+=auto_end; + } + } + return spelling; +} + +std::string clang::Token::get_brief_comments() { + std::string comment_string; + auto referenced=clang_getCursorReferenced(cx_cursor); + auto comment=clang_Cursor_getParsedComment(referenced); + if(clang_Comment_getKind(comment)==CXComment_FullComment) { + size_t para_c=0; + for(unsigned c=0;c=2) + break; + for(unsigned c=0;c0) + comment_string.pop_back(); + if(clang_InlineCommandComment_getNumArgs(grandchild_comment)==0) + comment_string+=clang_getCString(cxstr); + clang_disposeString(cxstr); + for(unsigned arg_c=0;arg_c0) + comment_string+=" "; + comment_string+=clang_getCString(cxstr); + clang_disposeString(cxstr); + } + } + } + } + } + /*cout << " " << clang_Comment_getKind(child_comment) << ", children: " << clang_Comment_getNumChildren(child_comment) << endl; + auto cxstr=clang_FullComment_getAsHTML(child_comment); + cout << " " << clang_getCString(cxstr) << endl; + clang_disposeString(cxstr);*/ + } + while(comment_string.size()>0 && (comment_string.back()=='\n' || comment_string.back()==' ')) + comment_string.pop_back(); + } + + return comment_string; } diff --git a/src/Token.h b/src/Token.h index dd8efe4..d88817f 100644 --- a/src/Token.h +++ b/src/Token.h @@ -1,8 +1,10 @@ #ifndef TOKEN_H_ #define TOKEN_H_ +#include #include "SourceLocation.h" #include "SourceRange.h" -#include "TranslationUnit.h" +#include "Cursor.h" +#include namespace clang { enum TokenKind { @@ -15,17 +17,21 @@ namespace clang { class Token { public: + 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(TranslationUnit *tu); - SourceLocation get_source_location(TranslationUnit *tu); - SourceRange get_source_range(TranslationUnit *tu); - std::string type; + std::string get_token_spelling(); + SourceLocation get_source_location(); + clang::Cursor get_cursor() {return clang::Cursor(cx_cursor);} + bool has_type(); + std::string get_type(); + std::string get_brief_comments(); + CXTranslationUnit &cx_tu; + CXToken& cx_token; + CXCursor& cx_cursor; + SourceRange source_range; private: - explicit Token(const CXToken &token); - friend SourceRange; - friend SourceLocation; - friend Tokens; - const CXToken& token_; + SourceRange get_source_range(); }; } // namespace clang #endif // TOKEN_H_ diff --git a/src/Tokens.cc b/src/Tokens.cc index 571d0db..b1c5893 100644 --- a/src/Tokens.cc +++ b/src/Tokens.cc @@ -2,135 +2,102 @@ #include using namespace std; -clang::Tokens::Tokens(clang::TranslationUnit *tu, clang::SourceRange *range): tu(*tu) { - clang_tokenize(tu->tu_, - range->range_, - &tokens_, - &num_tokens_); - for (int i = 0; i < num_tokens_; i++) { - push_back(clang::Token(tokens_[i])); +clang::Tokens::Tokens(CXTranslationUnit &cx_tu, 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]); } } clang::Tokens::~Tokens() { - clang_disposeTokens(tu.tu_, tokens_, size()); + clang_disposeTokens(cx_tu, cx_tokens, size()); } -void clang::Tokens::update_types(clang::TranslationUnit *tu) { - clang_cursors.clear(); - clang_cursors.reserve(size()); - clang_annotateTokens(tu->tu_, tokens_, size(), clang_cursors.data()); +/*CXCursor clang::Tokens::find_referenced() { + cursors.clear(); + cursors.reserve(size()); + clang_annotateTokens(tu, tokens.data(), size(), cursors.data()); + + auto kind=clang_getCursorKind(cursors[0]); + cout << " " << kind << endl; + cout << " Decl: " << clang_isDeclaration(kind) << endl; + cout << " Attr: " << clang_isAttribute(kind) << endl; + cout << " Ref: " << clang_isReference(kind) << endl; + cout << " Expr: " << clang_isExpression(kind) << endl; + + auto referenced=clang_getCursorReferenced(cursors[0]); + kind=clang_getCursorKind(referenced); + cout << " " << kind << endl; + cout << " Decl: " << clang_isDeclaration(kind) << endl; + cout << " Attr: " << clang_isAttribute(kind) << endl; + cout << " Ref: " << clang_isReference(kind) << endl; + cout << " Expr: " << clang_isExpression(kind) << endl; + + //TODO: To find similar function declarations, these must be equal (if cursor is declaration): + //TODO: How do we know it is a function? clang_getCursorKind(cursor)==CXCursor_CXXMethod? + cout << " " << clang_getCString(clang_getTypeSpelling(clang_getCursorType(referenced))) << endl; + cout << " " << clang_getCString(clang_getTypeSpelling(clang_getCursorType(clang_getCursorSemanticParent(referenced)))) << endl; + cout << " " << clang_getCString(clang_getCursorSpelling(referenced)) << endl; + + return referenced; +}*/ + +void clang::Tokens::rename(CXCursor &referenced) { for(size_t c=0;c=4 && spelling.substr(0, 4)=="auto")) { - auto_end=spelling.substr(4); - auto type=clang_getCanonicalType(clang_getCursorType(clang_cursors[c])); - auto cxstr=clang_getTypeSpelling(type); - spelling=clang_getCString(cxstr); - clang_disposeString(cxstr); - if(spelling.find(" ")==std::string::npos) - spelling+=auto_end; - } - - (*this)[c].type=spelling; - //std::cout << clang_getCString(clang_getTypeSpelling(type)) << ": " << type.kind << endl; - ////auto cursor=clang_getTypeDeclaration(type); - ////tks[c].type=clang_getCString(clang_getCursorSpelling(cursor)); - ////auto type=clang_getCursorType(referenced); + auto a_referenced=clang_getCursorReferenced(cx_cursors[c]); + if(Cursor(a_referenced)==Cursor(referenced)) { + std::string path; + unsigned line, column, offset; - } - //Testing: - /*if(tks[c].get_token_spelling(tu)=="text_view") { - cout << tks[c].get_token_spelling(tu) << endl; - auto kind=clang_getCursorKind(cursors[c].cursor_); - cout << " " << kind << endl; - cout << " Decl: " << clang_isDeclaration(kind) << endl; - cout << " Attr: " << clang_isAttribute(kind) << endl; - cout << " Ref: " << clang_isReference(kind) << endl; - cout << " Expr: " << clang_isExpression(kind) << endl; - auto referenced=clang_getCursorReferenced(cursors[c].cursor_); - if(!clang_Cursor_isNull(referenced)) { - cout << " " << clang_getCursorKind(referenced) << endl; - - clang::Cursor referenced_cursor; - referenced_cursor.cursor_=referenced; - auto range=clang::SourceRange(&referenced_cursor); + clang::Cursor cursor(cx_cursors[c]); + auto range=cursor.get_source_range(); + auto locations=range.get_source_locations(); + locations.first.get_location_info(&path, &line, &column, &offset); + cout << " start: " << path << ", " << line << ", " << column << endl; + locations.second.get_location_info(&path, &line, &column, &offset); + cout << " end: " << path << ", " << line << ", " << column << endl; - auto location=clang::SourceLocation(&range, true); - std::string path; - unsigned line, column, offset; - location.get_location_info(&path, &line, &column, &offset); - cout << " start: " << path << ", " << line << ", " << column << endl; + + clang::Cursor referenced_cursor(a_referenced); + range=referenced_cursor.get_source_range(); + locations=range.get_source_locations(); + locations.first.get_location_info(&path, &line, &column, &offset); + cout << " start: " << path << ", " << line << ", " << column << endl; - location=clang::SourceLocation(&range, false); - location.get_location_info(&path, &line, &column, &offset); - cout << " start: " << path << ", " << line << ", " << column << endl; + locations.second.get_location_info(&path, &line, &column, &offset); + cout << " end: " << path << ", " << line << ", " << column << endl; - auto type=clang_getCursorType(referenced); - cout << " " << clang_getCString(clang_getTypeSpelling(type)) << endl; - } - }*/ + auto type=clang_getCursorType(a_referenced); + cout << " " << clang_getCString(clang_getTypeSpelling(type)) << endl; + } } + //clang_visitChildren(clang_getTranslationUnitCursor(tu.tu_), clang::Tokens::clang_visitor, &referenced); } -std::string clang::Tokens::get_brief_comments(size_t cursor_id) { - std::string comment_string; - auto referenced=clang_getCursorReferenced(clang_cursors[cursor_id]); - auto comment=clang_Cursor_getParsedComment(referenced); - if(clang_Comment_getKind(comment)==CXComment_FullComment) { - size_t para_c=0; - for(unsigned c=0;c=2) - break; - for(unsigned c=0;c0) - comment_string.pop_back(); - if(clang_InlineCommandComment_getNumArgs(grandchild_comment)==0) - comment_string+=clang_getCString(cxstr); - clang_disposeString(cxstr); - for(unsigned arg_c=0;arg_c0) - comment_string+=" "; - comment_string+=clang_getCString(cxstr); - clang_disposeString(cxstr); - } - } - } - } - } - /*cout << " " << clang_Comment_getKind(child_comment) << ", children: " << clang_Comment_getNumChildren(child_comment) << endl; - auto cxstr=clang_FullComment_getAsHTML(child_comment); - cout << " " << clang_getCString(cxstr) << endl; - clang_disposeString(cxstr);*/ - } - while(comment_string.size()>0 && (comment_string.back()=='\n' || comment_string.back()==' ')) - comment_string.pop_back(); +/*CXChildVisitResult clang::Tokens::clang_visitor(CXCursor cursor, CXCursor parent, CXClientData clientData) { + CXCursor* referenced=(CXCursor*)clientData; + auto a_referenced=clang_getCursorReferenced(cursor); + if(clang_equalCursors(a_referenced, *referenced)) { + cout << "found" << endl; + clang::Cursor a_cursor; + a_cursor.cursor_=cursor; + auto range=clang::SourceRange(&a_cursor); + + auto location=clang::SourceLocation(range, true); + std::string path; + unsigned line, column, offset; + location.get_location_info(&path, &line, &column, &offset); + cout << " start: " << path << ", " << line << ", " << column << endl; + + location=clang::SourceLocation(range, false); + location.get_location_info(&path, &line, &column, &offset); + cout << " end: " << path << ", " << line << ", " << column << endl; } - return comment_string; -} \ No newline at end of file + return CXChildVisit_Recurse; +}*/ diff --git a/src/Tokens.h b/src/Tokens.h index 8696337..ca60a35 100644 --- a/src/Tokens.h +++ b/src/Tokens.h @@ -1,21 +1,23 @@ #ifndef TOKENS_H_ #define TOKENS_H_ -#include "TranslationUnit.h" +#include #include "SourceRange.h" #include "Token.h" +#include +#include namespace clang { class Tokens : public std::vector { public: - Tokens(TranslationUnit *tu, SourceRange *range); + Tokens(CXTranslationUnit &cx_tu, SourceRange &range); ~Tokens(); - void update_types(clang::TranslationUnit *tu); - std::string get_brief_comments(size_t cursor_id); + void rename(CXCursor &referenced); + //std::unordered_map > private: - CXToken *tokens_; - unsigned num_tokens_; - std::vector clang_cursors; - TranslationUnit& tu; + CXToken *cx_tokens; + unsigned num_tokens; + std::vector cx_cursors; + CXTranslationUnit& cx_tu; }; } // namespace clang #endif // TOKENS_H_ diff --git a/src/TranslationUnit.cc b/src/TranslationUnit.cc index de1c2aa..0fd841d 100644 --- a/src/TranslationUnit.cc +++ b/src/TranslationUnit.cc @@ -6,17 +6,11 @@ clang::TranslationUnit:: ~TranslationUnit() { - clang_disposeTranslationUnit(tu_); -} - -clang::TranslationUnit& clang::TranslationUnit:: -operator=(const clang::TranslationUnit &tu) { - tu_ = tu.tu_; - return *this; + clang_disposeTranslationUnit(cx_tu); } clang::TranslationUnit:: -TranslationUnit(Index *index, +TranslationUnit(Index &index, const std::string &filepath, const std::vector &command_line_args) { std::map buffers; @@ -28,7 +22,7 @@ TranslationUnit(Index *index, } clang::TranslationUnit:: -TranslationUnit(Index *index, +TranslationUnit(Index &index, const std::string &filepath) { std::vector command_line_args; std::map buffers; @@ -40,7 +34,7 @@ TranslationUnit(Index *index, } clang::TranslationUnit:: -TranslationUnit(clang::Index *index, +TranslationUnit(clang::Index &index, const std::string &filepath, const std::vector &command_line_args, const std::map &buffers, @@ -48,7 +42,7 @@ TranslationUnit(clang::Index *index, parse(index, filepath, command_line_args, buffers, flags); } -void clang::TranslationUnit::parse(Index *index, +void clang::TranslationUnit::parse(Index &index, const std::string &filepath, const std::vector &command_line_args, const std::map &buffers, @@ -65,8 +59,8 @@ void clang::TranslationUnit::parse(Index *index, for(auto &a: command_line_args) { args.push_back(a.c_str()); } - tu_ = - clang_parseTranslationUnit(index->index_, + cx_tu = + clang_parseTranslationUnit(index.cx_index, filepath.c_str(), args.data(), args.size(), @@ -76,8 +70,7 @@ void clang::TranslationUnit::parse(Index *index, } int clang::TranslationUnit:: -ReparseTranslationUnit(const std::string &file_path, - const std::map &buffers, +ReparseTranslationUnit(const std::map &buffers, unsigned flags) { std::vector files; for (auto &buffer : buffers) { @@ -87,7 +80,7 @@ ReparseTranslationUnit(const std::string &file_path, file.Length = buffer.second.size(); files.push_back(file); } - return clang_reparseTranslationUnit(tu_, + return clang_reparseTranslationUnit(cx_tu, files.size(), files.data(), flags); @@ -97,11 +90,31 @@ unsigned clang::TranslationUnit::DefaultFlags() { return CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; } -void clang::TranslationUnit::update_diagnostics() { - diagnostics.clear(); - for(unsigned c=0;c &buffers, int line_number, int column) { + auto cxstr=clang_getTranslationUnitSpelling(cx_tu); + std::string path=clang_getCString(cxstr); + clang_disposeString(cxstr); + + clang::CodeCompleteResults results(cx_tu, path, buffers, line_number, column); + return results; +} + +std::vector clang::TranslationUnit::get_diagnostics() { + std::vector diagnostics; + for(unsigned c=0;c clang::TranslationUnit::get_tokens(unsigned start_offset, unsigned end_offset) { + auto cxstr=clang_getTranslationUnitSpelling(cx_tu); + std::string path=clang_getCString(cxstr); + clang_disposeString(cxstr); + clang::SourceLocation start_location(cx_tu, path, start_offset); + clang::SourceLocation end_location(cx_tu, path, end_offset); + clang::SourceRange range(start_location, end_location); + return std::unique_ptr(new Tokens(cx_tu, range)); } diff --git a/src/TranslationUnit.h b/src/TranslationUnit.h index b04a93e..9429031 100644 --- a/src/TranslationUnit.h +++ b/src/TranslationUnit.h @@ -7,51 +7,38 @@ #include #include "Index.h" #include "Diagnostic.h" +#include "Tokens.h" +#include "CodeCompleteResults.h" namespace clang { - class Token; - class Tokens; - class SourceLocation; - class SourceRange; - class Cursor; - class CodeCompleteResults; - class Diagnostic; - class TranslationUnit { public: - TranslationUnit(Index *index, + TranslationUnit(Index &index, const std::string &filepath, const std::vector &command_line_args); - TranslationUnit(Index *index, + TranslationUnit(Index &index, const std::string &filepath, const std::vector &command_line_args, const std::map &buffers, unsigned flags=DefaultFlags()); - TranslationUnit(Index *index, + TranslationUnit(Index &index, const std::string &filepath); ~TranslationUnit(); - TranslationUnit& operator=(const TranslationUnit &tu); - int ReparseTranslationUnit(const std::string &file_path, - const std::map - &buffers, + int ReparseTranslationUnit(const std::map &buffers, unsigned flags=DefaultFlags()); static unsigned DefaultFlags(); - void update_diagnostics(); - std::vector diagnostics; - private: - void parse(Index *index, + void parse(Index &index, const std::string &filepath, const std::vector &command_line_args, const std::map &buffers, unsigned flags=DefaultFlags()); - friend Token; - friend Tokens; - friend SourceLocation; - friend SourceRange; - friend Cursor; - friend CodeCompleteResults; - CXTranslationUnit tu_; + + clang::CodeCompleteResults get_code_completions(const std::map &buffers, int line_number, int column); + std::vector get_diagnostics(); + std::unique_ptr get_tokens(unsigned start_offset, unsigned end_offset); + + CXTranslationUnit cx_tu; }; } // namespace clang #endif // TRANSLATIONUNIT_H_ diff --git a/tests/CodeCompleteResults_H_Test.cc b/tests/CodeCompleteResults_H_Test.cc index c696727..d2e880f 100644 --- a/tests/CodeCompleteResults_H_Test.cc +++ b/tests/CodeCompleteResults_H_Test.cc @@ -9,7 +9,7 @@ BOOST_AUTO_TEST_CASE(code_complete_results) { std::string path("./case/main.cpp"); clang::Index index(0, 0); - clang::TranslationUnit tu(&index, path); + clang::TranslationUnit tu(index, path); // ReparseTranslationUnit takes a map with filepath as key // and buffer as value @@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(code_complete_results) { // ] - clang::CodeCompleteResults results(&tu, path, buffers, 4, 5); + auto results=tu.get_code_completions(buffers, 4, 5); bool substr_found=false; for(int c=0;c args; - clang::TranslationUnit tu(&index, path, args, map_buffers); + clang::TranslationUnit tu(index, path, args, map_buffers); - tu.update_diagnostics(); - BOOST_CHECK(tu.diagnostics.size()==1); - BOOST_CHECK(tu.diagnostics[0].spelling=="use of undeclared identifier 'undeclared_variable'"); - BOOST_CHECK(tu.diagnostics[0].path=="./case/main_error.cpp"); - BOOST_CHECK(tu.diagnostics[0].severity==3); - BOOST_CHECK(tu.diagnostics[0].start_location.line==5); - BOOST_CHECK(tu.diagnostics[0].end_location.line==5); - BOOST_CHECK(tu.diagnostics[0].start_location.column==16); - BOOST_CHECK(tu.diagnostics[0].end_location.column==35); + auto diagnostics=tu.get_diagnostics(); + BOOST_CHECK(diagnostics.size()==1); + BOOST_CHECK(diagnostics[0].spelling=="use of undeclared identifier 'undeclared_variable'"); + BOOST_CHECK(diagnostics[0].range.path=="./case/main_error.cpp"); + BOOST_CHECK(diagnostics[0].severity==3); } diff --git a/tests/SourceLocation_H_Test.cc b/tests/SourceLocation_H_Test.cc index 308fe6a..ab6d1c0 100644 --- a/tests/SourceLocation_H_Test.cc +++ b/tests/SourceLocation_H_Test.cc @@ -7,30 +7,26 @@ BOOST_AUTO_TEST_CASE(source_location) { clang::Index index(0, 0); - clang::TranslationUnit tu(&index, path); - clang::SourceLocation start(&tu, path, 0); - clang::SourceLocation end(&tu, path, 7, 1); - clang::SourceRange range(&start, &end); - clang::Tokens tokens(&tu, &range); + clang::TranslationUnit tu(index, path); + auto tokens=tu.get_tokens(0, 113); - clang::SourceRange token_range = tokens[28].get_source_range(&tu); + clang::SourceRange token_range = (*tokens)[28].source_range; unsigned token_start_line, token_start_column, token_start_offset, token_end_line, token_end_column, token_end_offset; std::string token_start_path, token_end_path; - clang::SourceLocation token_start(&token_range, true); - clang::SourceLocation token_end(&token_range, false); + auto locations=token_range.get_source_locations(); - token_start.get_location_info(&token_start_path, - &token_start_line, - &token_start_column, - &token_start_offset); + locations.first.get_location_info(&token_start_path, + &token_start_line, + &token_start_column, + &token_start_offset); - token_end.get_location_info(&token_end_path, - &token_end_line, - &token_end_column, - &token_end_offset); + locations.second.get_location_info(&token_end_path, + &token_end_line, + &token_end_column, + &token_end_offset); BOOST_CHECK(token_start_path == path); BOOST_CHECK(token_start_line == 6); diff --git a/tests/Token_H_Test.cc b/tests/Token_H_Test.cc index 8befb20..38198c2 100644 --- a/tests/Token_H_Test.cc +++ b/tests/Token_H_Test.cc @@ -7,17 +7,13 @@ BOOST_AUTO_TEST_CASE(token) { clang::Index index(0, 0); - clang::TranslationUnit tu(&index, path); - clang::SourceLocation start(&tu, path, 0); - clang::SourceLocation end(&tu, path, 7, 1); + clang::TranslationUnit tu(index, path); + + auto tokens=tu.get_tokens(0, 113); - clang::SourceRange range(&start, &end); + BOOST_CHECK(tokens->size() == 32); + BOOST_CHECK((*tokens)[1].kind() == clang::TokenKind::Token_Identifier); - clang::Tokens tokens(&tu, &range); - - BOOST_CHECK(tokens.size() == 32); - BOOST_CHECK(tokens[1].kind() == clang::TokenKind::Token_Identifier); - - std::string str = tokens[28].get_token_spelling(&tu); + std::string str = (*tokens)[28].get_token_spelling(); BOOST_CHECK(str == "return"); } diff --git a/tests/TranslationUnit_Test.cc b/tests/TranslationUnit_Test.cc index 408ab9b..acd9fbd 100644 --- a/tests/TranslationUnit_Test.cc +++ b/tests/TranslationUnit_Test.cc @@ -7,7 +7,7 @@ BOOST_AUTO_TEST_CASE(translation_unit) { std::string path("./case/main.cpp"); clang::Index index(0, 0); - clang::TranslationUnit tu(&index, path); + clang::TranslationUnit tu(index, path); // ReparseTranslationUnit takes a map with filepath as key // and buffer as value @@ -20,5 +20,5 @@ BOOST_AUTO_TEST_CASE(translation_unit) { file.append("}"); buffers[path] = file; - BOOST_CHECK(tu.ReparseTranslationUnit(path, buffers) == 0); + BOOST_CHECK(tu.ReparseTranslationUnit(buffers) == 0); }