diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..50f9423 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +IndentWidth: 2 +AccessModifierOffset: -2 +UseTab: Never +ColumnLimit: 0 +MaxEmptyLinesToKeep: 2 +SpaceBeforeParens: Never +BreakBeforeBraces: Custom +BraceWrapping: {BeforeElse: true, BeforeCatch: true} +NamespaceIndentation: All diff --git a/README.md b/README.md index 7e720f2..a601dee 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Developed for [juCi++](https://gitlab.com/cppit/jucipp), a lightweight, platform ## Installation ## See [installation guide](https://gitlab.com/cppit/libclangmm/blob/master/docs/install.md) -# Tests # +## Tests ## To run the unit tests: ```sh mkdir build && cd build @@ -21,3 +21,31 @@ cmake -DBUILD_TESTING=1 .. make make test ``` + +## Coding style +Due to poor lambda support in clang-format, a custom clang-format is used with the following patch applied: +```diff +diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp +index bb8efd61a3..e80a487055 100644 +--- a/lib/Format/ContinuationIndenter.cpp ++++ b/lib/Format/ContinuationIndenter.cpp +@@ -276,6 +276,8 @@ LineState ContinuationIndenter::getInitialState(unsigned FirstIndent, + } + + bool ContinuationIndenter::canBreak(const LineState &State) { ++ if(Style.ColumnLimit==0) ++ return true; + const FormatToken &Current = *State.NextToken; + const FormatToken &Previous = *Current.Previous; + assert(&Previous == Current.Previous); +@@ -325,6 +327,8 @@ bool ContinuationIndenter::canBreak(const LineState &State) { + } + + bool ContinuationIndenter::mustBreak(const LineState &State) { ++ if(Style.ColumnLimit==0) ++ return false; + const FormatToken &Current = *State.NextToken; + const FormatToken &Previous = *Current.Previous; + if (Current.MustBreakBefore || Current.is(TT_InlineASMColon)) +``` + diff --git a/src/clangmm.h b/src/clangmm.h index 500e2f7..80a0597 100644 --- a/src/clangmm.h +++ b/src/clangmm.h @@ -1,17 +1,17 @@ #ifndef CLANGMM_H_ #define CLANGMM_H_ -#include "translation_unit.h" -#include "source_location.h" -#include "source_range.h" -#include "token.h" -#include "tokens.h" +#include "code_complete_results.h" #include "compilation_database.h" -#include "compile_commands.h" #include "compile_command.h" -#include "code_complete_results.h" +#include "compile_commands.h" #include "completion_string.h" -#include "index.h" #include "cursor.h" #include "diagnostic.h" +#include "index.h" +#include "source_location.h" +#include "source_range.h" +#include "token.h" +#include "tokens.h" +#include "translation_unit.h" #include "utility.h" -#endif // CLANGMM_H_ +#endif // CLANGMM_H_ diff --git a/src/code_complete_results.cc b/src/code_complete_results.cc index fd9d4de..f3923d9 100644 --- a/src/code_complete_results.cc +++ b/src/code_complete_results.cc @@ -2,22 +2,22 @@ #include "completion_string.h" #include "utility.h" -clangmm::CodeCompleteResults::CodeCompleteResults(CXTranslationUnit &cx_tu, - const std::string &buffer, - unsigned line_num, unsigned column) { +clangmm::CodeCompleteResults::CodeCompleteResults(CXTranslationUnit &cx_tu, + const std::string &buffer, + unsigned line_num, unsigned column) { CXUnsavedFile files[1]; - auto file_path=to_string(clang_getTranslationUnitSpelling(cx_tu)); + auto file_path = to_string(clang_getTranslationUnitSpelling(cx_tu)); files[0].Filename = file_path.c_str(); files[0].Contents = buffer.c_str(); files[0].Length = buffer.size(); cx_results = clang_codeCompleteAt(cx_tu, - file_path.c_str(), - line_num, - column, - files, - 1, - clang_defaultCodeCompleteOptions()|CXCodeComplete_IncludeBriefComments); + file_path.c_str(), + line_num, + column, + files, + 1, + clang_defaultCodeCompleteOptions() | CXCodeComplete_IncludeBriefComments); if(cx_results) clang_sortCodeCompletionResults(cx_results->Results, cx_results->NumResults); } @@ -27,11 +27,11 @@ clangmm::CodeCompleteResults::CodeCompleteResults(CodeCompleteResults &&rhs) : c } clangmm::CodeCompleteResults &clangmm::CodeCompleteResults::operator=(CodeCompleteResults &&rhs) { - if(this!=&rhs) { + if(this != &rhs) { if(cx_results) clang_disposeCodeCompleteResults(cx_results); - cx_results=rhs.cx_results; - rhs.cx_results=nullptr; + cx_results = rhs.cx_results; + rhs.cx_results = nullptr; } return *this; } diff --git a/src/code_complete_results.h b/src/code_complete_results.h index 05400c5..0652de4 100644 --- a/src/code_complete_results.h +++ b/src/code_complete_results.h @@ -1,16 +1,17 @@ #ifndef CODECOMPLETERESULTS_H_ #define CODECOMPLETERESULTS_H_ +#include "completion_string.h" #include #include #include -#include "completion_string.h" namespace clangmm { class CodeCompleteResults { friend class TranslationUnit; - + CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &buffer, unsigned line_num, unsigned column); + public: CodeCompleteResults(CodeCompleteResults &) = delete; CodeCompleteResults(CodeCompleteResults &&rhs); @@ -23,5 +24,5 @@ namespace clangmm { CXCodeCompleteResults *cx_results; }; -} // namespace clangmm -#endif // CODECOMPLETERESULTS_H_ +} // namespace clangmm +#endif // CODECOMPLETERESULTS_H_ diff --git a/src/compilation_database.h b/src/compilation_database.h index b884b2e..69b7a34 100644 --- a/src/compilation_database.h +++ b/src/compilation_database.h @@ -7,14 +7,15 @@ namespace clangmm { class CompilationDatabase { CXCompilationDatabase_Error cx_db_error; + public: explicit CompilationDatabase(const std::string &project_path); ~CompilationDatabase(); - + operator bool() const; CXCompilationDatabase cx_db; }; -} +} // namespace clangmm -#endif // COMPILATIONDATABASE_H_ +#endif // COMPILATIONDATABASE_H_ diff --git a/src/compile_command.cc b/src/compile_command.cc index 4c7d12d..cafa6bf 100644 --- a/src/compile_command.cc +++ b/src/compile_command.cc @@ -5,7 +5,7 @@ std::vector clangmm::CompileCommand::get_arguments() { unsigned size = clang_CompileCommand_getNumArgs(cx_command); std::vector arguments; - for (unsigned i = 0; i < size; i++) + for(unsigned i = 0; i < size; i++) arguments.emplace_back(to_string(clang_CompileCommand_getArg(cx_command, i))); return arguments; } diff --git a/src/compile_command.h b/src/compile_command.h index f442ad0..69c99df 100644 --- a/src/compile_command.h +++ b/src/compile_command.h @@ -1,16 +1,16 @@ #ifndef COMPILECOMMAND_H_ #define COMPILECOMMAND_H_ #include -#include #include +#include namespace clangmm { class CompileCommand { public: - CompileCommand(const CXCompileCommand& cx_command) : cx_command(cx_command) {}; + CompileCommand(const CXCompileCommand &cx_command) : cx_command(cx_command){}; std::vector get_arguments(); CXCompileCommand cx_command; }; -} -#endif // COMPILECOMMAND_H_ +} // namespace clangmm +#endif // COMPILECOMMAND_H_ diff --git a/src/compile_commands.cc b/src/compile_commands.cc index 0083b04..e6ba74b 100644 --- a/src/compile_commands.cc +++ b/src/compile_commands.cc @@ -3,7 +3,7 @@ clangmm::CompileCommands::CompileCommands(const std::string &filename, CompilationDatabase &db) { if(!filename.empty()) cx_commands = clang_CompilationDatabase_getCompileCommands(db.cx_db, filename.c_str()); - if(filename.empty() || clang_CompileCommands_getSize(cx_commands)==0) + if(filename.empty() || clang_CompileCommands_getSize(cx_commands) == 0) cx_commands = clang_CompilationDatabase_getAllCompileCommands(db.cx_db); } @@ -15,7 +15,7 @@ std::vector clangmm::CompileCommands::get_commands() { unsigned size = clang_CompileCommands_getSize(cx_commands); std::vector commands; commands.reserve(size); - for (unsigned i = 0; i < size; i++) + for(unsigned i = 0; i < size; i++) commands.emplace_back(clang_CompileCommands_getCommand(cx_commands, i)); return commands; } diff --git a/src/compile_commands.h b/src/compile_commands.h index fe3d872..83e50c5 100644 --- a/src/compile_commands.h +++ b/src/compile_commands.h @@ -15,5 +15,5 @@ namespace clangmm { CXCompileCommands cx_commands; }; -} -#endif // COMPILECOMMANDS_H_ +} // namespace clangmm +#endif // COMPILECOMMANDS_H_ diff --git a/src/completion_string.cc b/src/completion_string.cc index 148d686..cda0050 100644 --- a/src/completion_string.cc +++ b/src/completion_string.cc @@ -39,96 +39,96 @@ clangmm::Cursor clangmm::CompletionString::get_cursor(CXTranslationUnit &tu) con public: static void remove_template_argument_and_namespace(std::string &chunk) { size_t pos1, pos2; - if((pos1=chunk.find('<'))!=std::string::npos && (pos2=chunk.rfind('>'))!=std::string::npos) - chunk=chunk.substr(0, pos1)+chunk.substr(pos2+1); - if((pos2=chunk.rfind("::"))!=std::string::npos) { - pos1=pos2-1; - while(pos1!=std::string::npos && ((chunk[pos1]>='a' && chunk[pos1]<='z') || (chunk[pos1]>='A' && chunk[pos1]<='Z') || - (chunk[pos1]>='0' && chunk[pos1]<='9') || chunk[pos1]==':' || chunk[pos1]=='_')) + if((pos1 = chunk.find('<')) != std::string::npos && (pos2 = chunk.rfind('>')) != std::string::npos) + chunk = chunk.substr(0, pos1) + chunk.substr(pos2 + 1); + if((pos2 = chunk.rfind("::")) != std::string::npos) { + pos1 = pos2 - 1; + while(pos1 != std::string::npos && ((chunk[pos1] >= 'a' && chunk[pos1] <= 'z') || (chunk[pos1] >= 'A' && chunk[pos1] <= 'Z') || + (chunk[pos1] >= '0' && chunk[pos1] <= '9') || chunk[pos1] == ':' || chunk[pos1] == '_')) --pos1; - chunk=chunk.substr(0, pos1+1)+chunk.substr(pos2+2); + chunk = chunk.substr(0, pos1 + 1) + chunk.substr(pos2 + 2); } } }; std::vector chunks; - for(unsigned i=0;i parent_parts; if(!parent.empty()) { - size_t pos=0; - size_t last_pos=0; - while((pos=parent.find("::", pos))!=std::string::npos) { - parent_parts.emplace_back(parent.substr(last_pos, pos-last_pos)); - pos+=2; - last_pos=pos; + size_t pos = 0; + size_t last_pos = 0; + while((pos = parent.find("::", pos)) != std::string::npos) { + parent_parts.emplace_back(parent.substr(last_pos, pos - last_pos)); + pos += 2; + last_pos = pos; } parent_parts.emplace_back(parent.substr(last_pos)); } - + VisitorData visitor_data{chunks, parent_parts, clangmm::Cursor()}; - + clang_visitChildren(clang_getTranslationUnitCursor(tu), [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData cx_data) { auto data = static_cast(cx_data); - - bool equal=true; - auto cx_tmp_cursor=cx_parent; - if(clang_getCursorKind(cx_tmp_cursor)!=CXCursorKind::CXCursor_TranslationUnit) { - int c=0; - auto it=data->parent_parts.rbegin(); - for(;it!=data->parent_parts.rend();++it) { - auto name=clangmm::to_string(clang_getCursorDisplayName(cx_tmp_cursor)); + + bool equal = true; + auto cx_tmp_cursor = cx_parent; + if(clang_getCursorKind(cx_tmp_cursor) != CXCursorKind::CXCursor_TranslationUnit) { + int c = 0; + auto it = data->parent_parts.rbegin(); + for(; it != data->parent_parts.rend(); ++it) { + auto name = clangmm::to_string(clang_getCursorDisplayName(cx_tmp_cursor)); size_t pos; - if((pos=name.find('<'))!=std::string::npos) - name=name.substr(0, pos); - if(name!=*it) { - equal=false; + if((pos = name.find('<')) != std::string::npos) + name = name.substr(0, pos); + if(name != *it) { + equal = false; break; } - cx_tmp_cursor=clang_getCursorSemanticParent(cx_tmp_cursor); - if(clang_getCursorKind(cx_tmp_cursor)==CXCursorKind::CXCursor_TranslationUnit) { + cx_tmp_cursor = clang_getCursorSemanticParent(cx_tmp_cursor); + if(clang_getCursorKind(cx_tmp_cursor) == CXCursorKind::CXCursor_TranslationUnit) { ++it; break; } ++c; } - if(it!=data->parent_parts.rend()) - equal=false; + if(it != data->parent_parts.rend()) + equal = false; } else if(!data->parent_parts.empty()) return CXChildVisit_Recurse; - + if(equal) { auto completion_string = clang_getCursorCompletionString(cx_cursor); - auto num_completion_chunks=clang_getNumCompletionChunks(completion_string); - if(num_completion_chunks>=data->completion_chunks.size()) { - bool equal=true; - for(unsigned i=0;icompletion_chunks.size() && i= data->completion_chunks.size()) { + bool equal = true; + for(unsigned i = 0; i < data->completion_chunks.size() && i < num_completion_chunks; ++i) { auto kind = clang_getCompletionChunkKind(completion_string, i); if(kind != CXCompletionChunk_Optional && kind != CXCompletionChunk_Informative) { - auto chunk=clangmm::to_string(clang_getCompletionChunkText(completion_string, i)); + auto chunk = clangmm::to_string(clang_getCompletionChunkText(completion_string, i)); ChunkString::remove_template_argument_and_namespace(chunk); - if(data->completion_chunks[i]!=chunk) { - equal=false; + if(data->completion_chunks[i] != chunk) { + equal = false; break; } } } if(equal) { - data->found_cursor=cx_cursor; + data->found_cursor = cx_cursor; return CXChildVisit_Break; } } } - + return CXChildVisit_Recurse; }, &visitor_data); - + return Cursor(visitor_data.found_cursor); } diff --git a/src/completion_string.h b/src/completion_string.h index 0aa327c..c14c4be 100644 --- a/src/completion_string.h +++ b/src/completion_string.h @@ -1,13 +1,13 @@ #ifndef COMPLETIONSTRING_H_ #define COMPLETIONSTRING_H_ +#include "cursor.h" #include #include #include -#include "cursor.h" namespace clangmm { enum CompletionChunkKind { - CompletionChunk_Optional, CompletionChunk_TypedText, + CompletionChunk_Optional, CompletionChunk_TypedText, CompletionChunk_Text, CompletionChunk_Placeholder, CompletionChunk_Informative, CompletionChunk_CurrentParameter, CompletionChunk_LeftParen, CompletionChunk_RightParen, @@ -34,11 +34,11 @@ namespace clangmm { std::vector get_chunks() const; unsigned get_num_chunks() const; std::string get_brief_comment() const; - + /// Search for the corresponding cursor Cursor get_cursor(CXTranslationUnit &tu) const; - + CXCompletionString cx_completion_string; }; -} // namespace clangmm -#endif // COMPLETIONSTRING_H_ +} // namespace clangmm +#endif // COMPLETIONSTRING_H_ diff --git a/src/cursor.cc b/src/cursor.cc index da18044..2ed307e 100644 --- a/src/cursor.cc +++ b/src/cursor.cc @@ -14,7 +14,7 @@ clangmm::Cursor clangmm::Cursor::Type::get_cursor() const { return Cursor(clang_getTypeDeclaration(cx_type)); } -bool clangmm::Cursor::Type::operator==(const Cursor::Type& rhs) const { +bool clangmm::Cursor::Type::operator==(const Cursor::Type &rhs) const { return clang_equalTypes(cx_type, rhs.cx_type); } @@ -27,24 +27,24 @@ std::string clangmm::Cursor::get_kind_spelling() const { } bool clangmm::Cursor::is_similar_kind(Kind kind, Kind other_kind) { - auto is_function_or_method=[](Kind kind) { - if(kind==Kind::FunctionDecl || kind==Kind::CXXMethod || kind==Kind::FunctionTemplate) + auto is_function_or_method = [](Kind kind) { + if(kind == Kind::FunctionDecl || kind == Kind::CXXMethod || kind == Kind::FunctionTemplate) return true; return false; }; - auto is_class_or_struct=[](Kind kind) { - if(kind==Kind::ClassDecl || kind==Kind::StructDecl || kind==Kind::ClassTemplate || - kind==Cursor::Kind::Constructor || kind==Cursor::Kind::Destructor || kind==Cursor::Kind::FunctionTemplate) + auto is_class_or_struct = [](Kind kind) { + if(kind == Kind::ClassDecl || kind == Kind::StructDecl || kind == Kind::ClassTemplate || + kind == Cursor::Kind::Constructor || kind == Cursor::Kind::Destructor || kind == Cursor::Kind::FunctionTemplate) return true; return false; }; - if(kind==Kind::FunctionTemplate) + if(kind == Kind::FunctionTemplate) return is_function_or_method(other_kind) || is_class_or_struct(other_kind); if(is_function_or_method(kind)) return is_function_or_method(other_kind); if(is_class_or_struct(kind)) return is_class_or_struct(other_kind); - return kind==other_kind; + return kind == other_kind; } clangmm::Cursor::Type clangmm::Cursor::get_type() const { @@ -68,15 +68,15 @@ std::string clangmm::Cursor::get_display_name() const { } std::string clangmm::Cursor::get_token_spelling() const { - auto spelling=get_spelling(); - for(size_t i=0;i0 && spelling[0]=='~') - return spelling.substr(1, i-1); + auto spelling = get_spelling(); + for(size_t i = 0; i < spelling.size(); ++i) { + if(spelling[i] == '<' || spelling[i] == '(') { + if(i > 0 && spelling[0] == '~') + return spelling.substr(1, i - 1); return spelling.substr(0, i); } } - if(!spelling.empty() && spelling[0]=='~') + if(!spelling.empty() && spelling[0] == '~') return spelling.substr(1); return spelling; } @@ -88,38 +88,38 @@ std::string clangmm::Cursor::get_usr() const { std::string clangmm::Cursor::get_usr_extended() const { if(!is_valid_kind()) return std::string(); - - auto cursor=*this; - auto kind=cursor.get_kind(); + + auto cursor = *this; + auto kind = cursor.get_kind(); // If constructor, destructor or function template, and the token spelling is equal, set cursor to parent - if(kind==Cursor::Kind::Constructor || kind==Cursor::Kind::Destructor || - kind==Cursor::Kind::FunctionTemplate) { - auto parent=cursor.get_semantic_parent(); - auto parent_kind=parent.get_kind(); - if((parent_kind==Cursor::Kind::ClassDecl || parent_kind==Cursor::Kind::StructDecl || parent_kind==Cursor::Kind::ClassTemplate) && - cursor.get_token_spelling()==parent.get_token_spelling()) - cursor=parent; + if(kind == Cursor::Kind::Constructor || kind == Cursor::Kind::Destructor || + kind == Cursor::Kind::FunctionTemplate) { + auto parent = cursor.get_semantic_parent(); + auto parent_kind = parent.get_kind(); + if((parent_kind == Cursor::Kind::ClassDecl || parent_kind == Cursor::Kind::StructDecl || parent_kind == Cursor::Kind::ClassTemplate) && + cursor.get_token_spelling() == parent.get_token_spelling()) + cursor = parent; } - - std::string usr=cursor.get_token_spelling(); - auto parent=cursor.get_semantic_parent(); - while((kind=parent.get_kind())!=Kind::TranslationUnit && parent.is_valid_kind()) { - if(kind==Kind::CXXMethod || kind==Kind::FunctionDecl || kind==Kind::FunctionTemplate || - kind==Kind::Constructor || kind==Kind::Destructor) { - auto canonical=cursor.get_canonical(); - auto location=canonical.get_source_location(); - auto offset=location.get_offset(); - return std::to_string(offset.line)+':'+std::to_string(offset.index)+':'+location.get_path(); + + std::string usr = cursor.get_token_spelling(); + auto parent = cursor.get_semantic_parent(); + while((kind = parent.get_kind()) != Kind::TranslationUnit && parent.is_valid_kind()) { + if(kind == Kind::CXXMethod || kind == Kind::FunctionDecl || kind == Kind::FunctionTemplate || + kind == Kind::Constructor || kind == Kind::Destructor) { + auto canonical = cursor.get_canonical(); + auto location = canonical.get_source_location(); + auto offset = location.get_offset(); + return std::to_string(offset.line) + ':' + std::to_string(offset.index) + ':' + location.get_path(); } - usr+=':'+parent.get_token_spelling(); - parent=parent.get_semantic_parent(); + usr += ':' + parent.get_token_spelling(); + parent = parent.get_semantic_parent(); } return usr; } std::unordered_set clangmm::Cursor::get_all_usr_extended() const { std::unordered_set usrs; - if(get_kind()==Kind::CXXMethod) { + if(get_kind() == Kind::CXXMethod) { class Recursive { public: static void overridden(std::unordered_set &usrs, const Cursor &cursor) { @@ -127,7 +127,7 @@ std::unordered_set clangmm::Cursor::get_all_usr_extended() const { CXCursor *cursors; unsigned size; clang_getOverriddenCursors(cursor.cx_cursor, &cursors, &size); - for(unsigned c=0;c clangmm::Cursor::get_children() const { std::vector result; - clang_visitChildren(cx_cursor, - [](CXCursor cur, CXCursor /*parent*/, CXClientData data) { - static_cast*>(data)->emplace_back(cur); - return CXChildVisit_Continue; - }, - &result - ); + clang_visitChildren(cx_cursor, [](CXCursor cur, CXCursor /*parent*/, CXClientData data) { + static_cast *>(data)->emplace_back(cur); + return CXChildVisit_Continue; + }, &result); return result; } std::vector clangmm::Cursor::get_arguments() const { std::vector cursors; - auto size=clang_Cursor_getNumArguments(cx_cursor); - for(int c=0;c clangmm::Cursor::get_all_overridden_cursors() const { std::vector result; - if(get_kind()!=Kind::CXXMethod) + if(get_kind() != Kind::CXXMethod) return result; - + class Recursive { public: static void overridden(std::vector &result, const Cursor &cursor, int depth) { - if(depth>0) + if(depth > 0) result.emplace_back(cursor); CXCursor *cursors; unsigned size; clang_getOverriddenCursors(cursor.cx_cursor, &cursors, &size); - for(unsigned c=0;cKind::UnexposedDecl && (kindKind::LastInvalid); + auto kind = get_kind(); + return kind > Kind::UnexposedDecl && (kind < Kind::FirstInvalid || kind > Kind::LastInvalid); } std::string clangmm::Cursor::get_type_description() const { std::string spelling; - auto referenced=clang_getCursorReferenced(cx_cursor); + auto referenced = clang_getCursorReferenced(cx_cursor); if(!clang_Cursor_isNull(referenced)) { - auto type=clang_getCursorType(referenced); - spelling=to_string(clang_getTypeSpelling(type)); - -#if CINDEX_VERSION_MAJOR==0 && CINDEX_VERSION_MINOR<32 - const std::string auto_str="auto"; - if(spelling.size()>=4 && std::equal(auto_str.begin(), auto_str.end(), spelling.begin())) { - auto canonical_type=clang_getCanonicalType(clang_getCursorType(cx_cursor)); - auto canonical_spelling=to_string(clang_getTypeSpelling(canonical_type)); - if(spelling.size()>5 && spelling[4]==' ' && spelling[5]=='&' && spelling!=canonical_spelling) - return canonical_spelling+" &"; + auto type = clang_getCursorType(referenced); + spelling = to_string(clang_getTypeSpelling(type)); + +#if CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR < 32 + const std::string auto_str = "auto"; + if(spelling.size() >= 4 && std::equal(auto_str.begin(), auto_str.end(), spelling.begin())) { + auto canonical_type = clang_getCanonicalType(clang_getCursorType(cx_cursor)); + auto canonical_spelling = to_string(clang_getTypeSpelling(canonical_type)); + if(spelling.size() > 5 && spelling[4] == ' ' && spelling[5] == '&' && spelling != canonical_spelling) + return canonical_spelling + " &"; else return canonical_spelling; } - - const std::string const_auto_str="const auto"; - if(spelling.size()>=10 && std::equal(const_auto_str.begin(), const_auto_str.end(), spelling.begin())) { - auto canonical_type=clang_getCanonicalType(clang_getCursorType(cx_cursor)); - auto canonical_spelling=to_string(clang_getTypeSpelling(canonical_type)); - if(spelling.size()>11 && spelling[10]==' ' && spelling[11]=='&' && spelling!=canonical_spelling) - return canonical_spelling+" &"; + + const std::string const_auto_str = "const auto"; + if(spelling.size() >= 10 && std::equal(const_auto_str.begin(), const_auto_str.end(), spelling.begin())) { + auto canonical_type = clang_getCanonicalType(clang_getCursorType(cx_cursor)); + auto canonical_spelling = to_string(clang_getTypeSpelling(canonical_type)); + if(spelling.size() > 11 && spelling[10] == ' ' && spelling[11] == '&' && spelling != canonical_spelling) + return canonical_spelling + " &"; else return canonical_spelling; } #endif } - + if(spelling.empty()) return get_spelling(); - + return spelling; } std::string clangmm::Cursor::get_brief_comments() const { std::string comment_string; - auto referenced=get_referenced(); + auto referenced = get_referenced(); if(referenced) { - comment_string=to_string(clang_Cursor_getBriefCommentText(referenced.cx_cursor)); + comment_string = to_string(clang_Cursor_getBriefCommentText(referenced.cx_cursor)); } return comment_string; } diff --git a/src/cursor.h b/src/cursor.h index 6334304..5d71f22 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -1,11 +1,11 @@ #ifndef CURSOR_H_ #define CURSOR_H_ -#include #include "source_location.h" #include "source_range.h" +#include #include -#include #include +#include namespace clangmm { class Cursor { @@ -183,12 +183,12 @@ namespace clangmm { std::string get_spelling() const; Type get_result() const; Cursor get_cursor() const; - bool operator==(const Cursor::Type& rhs) const; - + bool operator==(const Cursor::Type &rhs) const; + CXType cx_type; }; - - Cursor() { cx_cursor=clang_getNullCursor(); } + + Cursor() { cx_cursor = clang_getNullCursor(); } Cursor(const CXCursor &cx_cursor) : cx_cursor(cx_cursor) {} Kind get_kind() const; std::string get_kind_spelling() const; @@ -212,19 +212,19 @@ namespace clangmm { std::vector get_arguments() const; std::vector get_all_overridden_cursors() const; operator bool() const; - bool operator==(const Cursor& rhs) const; + bool operator==(const Cursor &rhs) const; unsigned hash() const; - + bool is_valid_kind() const; std::string get_type_description() const; std::string get_brief_comments() const; - + friend std::ostream &operator<<(std::ostream &os, const Cursor &cursor) { os << cursor.get_source_range() << ' ' << cursor.get_spelling(); return os; } - + CXCursor cx_cursor; }; -} // namespace clangmm -#endif // CURSOR_H_ +} // namespace clangmm +#endif // CURSOR_H_ diff --git a/src/diagnostic.cc b/src/diagnostic.cc index a85e78a..b4efc1d 100644 --- a/src/diagnostic.cc +++ b/src/diagnostic.cc @@ -3,22 +3,22 @@ #include "tokens.h" #include "utility.h" -clangmm::Diagnostic::Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic) { - severity=static_cast(clang_getDiagnosticSeverity(cx_diagnostic)); - spelling=to_string(clang_getDiagnosticSpelling(cx_diagnostic)); - +clangmm::Diagnostic::Diagnostic(CXTranslationUnit &cx_tu, CXDiagnostic &cx_diagnostic) { + severity = static_cast(clang_getDiagnosticSeverity(cx_diagnostic)); + spelling = to_string(clang_getDiagnosticSpelling(cx_diagnostic)); + SourceLocation location(clang_getDiagnosticLocation(cx_diagnostic)); - path=location.get_path(); - auto offset=location.get_offset(); - auto corrected_location=SourceLocation(cx_tu, path.c_str(), offset.line, offset.index); // to avoid getting macro tokens + path = location.get_path(); + auto offset = location.get_offset(); + auto corrected_location = SourceLocation(cx_tu, path.c_str(), offset.line, offset.index); // to avoid getting macro tokens Tokens tokens(cx_tu, SourceRange(corrected_location, corrected_location), false); - if(tokens.size()==1) - offsets={offset, tokens.begin()->get_source_range().get_offsets().second}; - - unsigned num_fix_its=clang_getDiagnosticNumFixIts(cx_diagnostic); - for(unsigned c=0;cget_source_range().get_offsets().second}; + + unsigned num_fix_its = clang_getDiagnosticNumFixIts(cx_diagnostic); + for(unsigned c = 0; c < num_fix_its; c++) { CXSourceRange fix_it_range; - auto source=to_string(clang_getDiagnosticFixIt(cx_diagnostic, c, &fix_it_range)); + auto source = to_string(clang_getDiagnosticFixIt(cx_diagnostic, c, &fix_it_range)); fix_its.emplace_back(source, SourceRange(fix_it_range).get_offsets()); } } diff --git a/src/diagnostic.h b/src/diagnostic.h index 5d7dadd..f13f488 100644 --- a/src/diagnostic.h +++ b/src/diagnostic.h @@ -1,14 +1,15 @@ #ifndef DIAGNOSTIC_H_ #define DIAGNOSTIC_H_ +#include "source_range.h" +#include #include #include -#include -#include "source_range.h" namespace clangmm { class Diagnostic { friend class TranslationUnit; - Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic); + Diagnostic(CXTranslationUnit &cx_tu, CXDiagnostic &cx_diagnostic); + public: enum class Severity { Ignored = 0, @@ -17,11 +18,11 @@ namespace clangmm { Error, Fatal }; - + class FixIt { public: - FixIt(const std::string &source, const std::pair &offsets): - source(source), offsets(offsets) {} + FixIt(const std::string &source, const std::pair &offsets) + : source(source), offsets(offsets) {} std::string source; std::pair offsets; }; @@ -32,6 +33,6 @@ namespace clangmm { std::pair offsets; std::vector fix_its; }; -} +} // namespace clangmm -#endif // DIAGNOSTIC_H_ +#endif // DIAGNOSTIC_H_ diff --git a/src/index.h b/src/index.h index 387d956..66dda38 100644 --- a/src/index.h +++ b/src/index.h @@ -9,5 +9,5 @@ namespace clangmm { ~Index(); CXIndex cx_index; }; -} // namespace clangmm -#endif // INDEX_H_ +} // namespace clangmm +#endif // INDEX_H_ diff --git a/src/source_location.cc b/src/source_location.cc index c21ab6d..3b0a8cc 100644 --- a/src/source_location.cc +++ b/src/source_location.cc @@ -25,15 +25,14 @@ clangmm::Offset clangmm::SourceLocation::get_offset() const { return {line, index}; } -void clangmm::SourceLocation::get_data(std::string* path, unsigned *line, unsigned *column, unsigned *offset) const { - if(path==nullptr) +void clangmm::SourceLocation::get_data(std::string *path, unsigned *line, unsigned *column, unsigned *offset) const { + 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) { - *path=to_string(clang_getFileName(file)); + if(file != NULL) { + *path = to_string(clang_getFileName(file)); } } } - diff --git a/src/source_location.h b/src/source_location.h index f671cf2..c4336ea 100644 --- a/src/source_location.h +++ b/src/source_location.h @@ -1,45 +1,46 @@ #ifndef SOURCELOCATION_H_ #define SOURCELOCATION_H_ #include -#include #include +#include namespace clangmm { class Offset { public: - bool operator==(const Offset &o) const {return line==o.line && index==o.index;} - bool operator!=(const Offset &o) const {return !(*this==o);} - bool operator<(const Offset &o) const {return line(const Offset &o) const {return o < *this;} - bool operator<=(const Offset &o) const {return (*this == o) || (*this < o);} - bool operator>=(const Offset &o) const {return (*this == o) || (*this > o);} + bool operator==(const Offset &o) const { return line == o.line && index == o.index; } + bool operator!=(const Offset &o) const { return !(*this == o); } + bool operator<(const Offset &o) const { return line < o.line || (line == o.line && index < o.index); } + bool operator>(const Offset &o) const { return o < *this; } + bool operator<=(const Offset &o) const { return (*this == o) || (*this < o); } + bool operator>=(const Offset &o) const { return (*this == o) || (*this > o); } unsigned line; unsigned index; //byte index in line (not char number) }; - + class SourceLocation { friend class TranslationUnit; friend class Diagnostic; SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset); SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned line, unsigned column); + public: - SourceLocation(const CXSourceLocation& cx_location) : cx_location(cx_location) {} + SourceLocation(const CXSourceLocation &cx_location) : cx_location(cx_location) {} public: std::string get_path() const; clangmm::Offset get_offset() const; friend std::ostream &operator<<(std::ostream &os, const SourceLocation &location) { - auto offset=location.get_offset(); + auto offset = location.get_offset(); os << location.get_path() << ':' << offset.line << ':' << offset.index; return os; } CXSourceLocation cx_location; - + private: void get_data(std::string *path, unsigned *line, unsigned *column, unsigned *offset) const; }; -} // namespace clangmm -#endif // SOURCELOCATION_H_ +} // namespace clangmm +#endif // SOURCELOCATION_H_ diff --git a/src/source_range.h b/src/source_range.h index 6b393b4..d344e87 100644 --- a/src/source_range.h +++ b/src/source_range.h @@ -1,25 +1,25 @@ #ifndef SOURCERANGE_H_ #define SOURCERANGE_H_ -#include #include "source_location.h" +#include #include #include -namespace clangmm { +namespace clangmm { class SourceRange { public: - SourceRange(const CXSourceRange& cx_range) : cx_range(cx_range) {} + SourceRange(const CXSourceRange &cx_range) : cx_range(cx_range) {} SourceRange(const SourceLocation &start, const SourceLocation &end); SourceLocation get_start() const; SourceLocation get_end() const; std::pair get_offsets() const; - + friend std::ostream &operator<<(std::ostream &os, const SourceRange &range) { os << range.get_start() << '-' << range.get_end(); return os; } - + CXSourceRange cx_range; }; -} // namespace clangmm -#endif // SOURCERANGE_H_ +} // namespace clangmm +#endif // SOURCERANGE_H_ diff --git a/src/token.cc b/src/token.cc index 1756505..d0ee71e 100644 --- a/src/token.cc +++ b/src/token.cc @@ -25,20 +25,20 @@ clangmm::Token::Kind clangmm::Token::get_kind() const { } bool clangmm::Token::is_identifier() const { - auto token_kind=get_kind(); - auto cursor=get_cursor(); - if(token_kind==clangmm::Token::Kind::Identifier && cursor.is_valid_kind()) + auto token_kind = get_kind(); + auto cursor = get_cursor(); + if(token_kind == clangmm::Token::Kind::Identifier && cursor.is_valid_kind()) return true; - else if(token_kind==clangmm::Token::Kind::Keyword && cursor.is_valid_kind()) { - auto spelling=get_spelling(); - if(spelling=="operator" || (spelling=="bool" && get_cursor().get_spelling()=="operator bool")) + else if(token_kind == clangmm::Token::Kind::Keyword && cursor.is_valid_kind()) { + auto spelling = get_spelling(); + if(spelling == "operator" || (spelling == "bool" && get_cursor().get_spelling() == "operator bool")) return true; } - else if(token_kind==clangmm::Token::Kind::Punctuation && cursor.is_valid_kind()) { - auto referenced=cursor.get_referenced(); + else if(token_kind == clangmm::Token::Kind::Punctuation && cursor.is_valid_kind()) { + auto referenced = cursor.get_referenced(); if(referenced) { - auto referenced_kind=referenced.get_kind(); - if(referenced_kind==Cursor::Kind::FunctionDecl || referenced_kind==Cursor::Kind::CXXMethod || referenced_kind==Cursor::Kind::Constructor) + auto referenced_kind = referenced.get_kind(); + if(referenced_kind == Cursor::Kind::FunctionDecl || referenced_kind == Cursor::Kind::CXXMethod || referenced_kind == Cursor::Kind::Constructor) return true; } } diff --git a/src/token.h b/src/token.h index 8e216c2..0d2e5d9 100644 --- a/src/token.h +++ b/src/token.h @@ -1,14 +1,15 @@ #ifndef TOKEN_H_ #define TOKEN_H_ -#include +#include "cursor.h" #include "source_location.h" #include "source_range.h" -#include "cursor.h" +#include #include namespace clangmm { class Token { friend class Tokens; + public: enum Kind { Punctuation, @@ -17,26 +18,28 @@ namespace clangmm { Literal, Comment }; + private: - Token(CXTranslationUnit &cx_tu, CXToken &cx_token, CXCursor &cx_cursor): - cx_tu(cx_tu), cx_token(cx_token), cx_cursor(cx_cursor) {} + Token(CXTranslationUnit &cx_tu, CXToken &cx_token, CXCursor &cx_cursor) + : cx_tu(cx_tu), cx_token(cx_token), cx_cursor(cx_cursor) {} + public: Kind get_kind() const; std::string get_spelling() const; SourceLocation get_source_location() const; SourceRange get_source_range() const; - clangmm::Cursor get_cursor() const {return clangmm::Cursor(cx_cursor);} + clangmm::Cursor get_cursor() const { return clangmm::Cursor(cx_cursor); } bool is_identifier() const; - + friend std::ostream &operator<<(std::ostream &os, const Token &token) { os << token.get_source_range() << ' ' << token.get_spelling(); return os; } CXTranslationUnit &cx_tu; - CXToken& cx_token; - CXCursor& cx_cursor; + CXToken &cx_token; + CXCursor &cx_cursor; }; -} // namespace clangmm -#endif // TOKEN_H_ +} // namespace clangmm +#endif // TOKEN_H_ diff --git a/src/tokens.cc b/src/tokens.cc index 2166a68..e15b71a 100644 --- a/src/tokens.cc +++ b/src/tokens.cc @@ -1,42 +1,42 @@ #include "tokens.h" #include "utility.h" -#include #include #include +#include -clangmm::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range, bool annotate_tokens): cx_tu(cx_tu) { +clangmm::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range, bool annotate_tokens) : cx_tu(cx_tu) { unsigned num_tokens; clang_tokenize(cx_tu, range.cx_range, &cx_tokens, &num_tokens); - + if(!annotate_tokens) { - cx_cursors=std::unique_ptr(new CXCursor[num_tokens]); - for (unsigned i = 0; i < num_tokens; i++) { - cx_cursors[i]=clang_getNullCursor(); + cx_cursors = std::unique_ptr(new CXCursor[num_tokens]); + for(unsigned i = 0; i < num_tokens; i++) { + cx_cursors[i] = clang_getNullCursor(); emplace_back(Token(cx_tu, cx_tokens[i], cx_cursors[i])); } return; } - - cx_cursors=std::unique_ptr(new CXCursor[num_tokens]); // To avoid allocation with initialization + + cx_cursors = std::unique_ptr(new CXCursor[num_tokens]); // To avoid allocation with initialization clang_annotateTokens(cx_tu, cx_tokens, num_tokens, cx_cursors.get()); - - bool tu_cursors=SourceRange(clang_getCursorExtent(clang_getTranslationUnitCursor(cx_tu))).get_start().get_path()==range.get_start().get_path(); + + bool tu_cursors = SourceRange(clang_getCursorExtent(clang_getTranslationUnitCursor(cx_tu))).get_start().get_path() == range.get_start().get_path(); std::map invalid_tokens; - - for (unsigned i = 0; i < num_tokens; i++) { - if(cx_cursors[i].kind==CXCursor_DeclRefExpr) { // Temporary fix to a libclang bug - auto real_cursor=clang_getCursor(cx_tu, clang_getTokenLocation(cx_tu, cx_tokens[i])); - cx_cursors[i]=real_cursor; + + for(unsigned i = 0; i < num_tokens; i++) { + if(cx_cursors[i].kind == CXCursor_DeclRefExpr) { // Temporary fix to a libclang bug + auto real_cursor = clang_getCursor(cx_tu, clang_getTokenLocation(cx_tu, cx_tokens[i])); + cx_cursors[i] = real_cursor; } // Corrects: when getting tokens from a header, FieldDecl tokens are getting ClassDecl or StructDecl cursors - else if(!tu_cursors && (cx_cursors[i].kind==CXCursor_ClassDecl || cx_cursors[i].kind==CXCursor_StructDecl)) { + else if(!tu_cursors && (cx_cursors[i].kind == CXCursor_ClassDecl || cx_cursors[i].kind == CXCursor_StructDecl)) { Token token(cx_tu, cx_tokens[i], cx_cursors[i]); - auto cursor=token.get_cursor(); - auto token_offsets=token.get_source_range().get_offsets(); - if(token_offsets.second!=cursor.get_source_range().get_offsets().second && token_offsets.first!=cursor.get_source_location().get_offset() && token.is_identifier()) + auto cursor = token.get_cursor(); + auto token_offsets = token.get_source_range().get_offsets(); + if(token_offsets.second != cursor.get_source_range().get_offsets().second && token_offsets.first != cursor.get_source_location().get_offset() && token.is_identifier()) invalid_tokens.emplace(i, token_offsets.first); } - + emplace_back(Token(cx_tu, cx_tokens[i], cx_cursors[i])); } if(!tu_cursors && !invalid_tokens.empty()) { @@ -50,23 +50,23 @@ clangmm::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range, bool VisitorData data{this, range.get_start().get_path(), invalid_tokens, {}}; auto translation_unit_cursor = clang_getTranslationUnitCursor(cx_tu); clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data_) { - auto data=static_cast(data_); + auto data = static_cast(data_); Cursor cursor(cx_cursor); - if(cursor.get_source_location().get_path()==data->path) + if(cursor.get_source_location().get_path() == data->path) data->cursors.emplace_back(cursor); return CXChildVisit_Continue; }, &data); - - for(auto &cursor: data.cursors) { + + for(auto &cursor : data.cursors) { clang_visitChildren(cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data_) { - auto data=static_cast(data_); - if(clang_getCursorKind(cx_cursor)==CXCursor_FieldDecl) { + auto data = static_cast(data_); + if(clang_getCursorKind(cx_cursor) == CXCursor_FieldDecl) { Cursor cursor(cx_cursor); - auto clang_offset=cursor.get_source_location().get_offset(); - for(auto it=data->invalid_tokens.begin();it!=data->invalid_tokens.end();) { - if(it->second==clang_offset) { - (*data->tokens)[it->first].cx_cursor=cursor.cx_cursor; - it=data->invalid_tokens.erase(it); + auto clang_offset = cursor.get_source_location().get_offset(); + for(auto it = data->invalid_tokens.begin(); it != data->invalid_tokens.end();) { + if(it->second == clang_offset) { + (*data->tokens)[it->first].cx_cursor = cursor.cx_cursor; + it = data->invalid_tokens.erase(it); if(data->invalid_tokens.empty()) return CXChildVisit_Break; break; @@ -87,22 +87,22 @@ clangmm::Tokens::~Tokens() { clang_disposeTokens(cx_tu, cx_tokens, size()); } -//This works across TranslationUnits. Similar tokens defined as tokens with equal canonical cursors. -std::vector > clangmm::Tokens::get_similar_token_offsets(Cursor::Kind kind, const std::string &spelling, - const std::unordered_set &usrs) { - std::vector > offsets; - for(auto &token: *this) { +//This works across TranslationUnits. Similar tokens defined as tokens with equal canonical cursors. +std::vector> clangmm::Tokens::get_similar_token_offsets(Cursor::Kind kind, const std::string &spelling, + const std::unordered_set &usrs) { + std::vector> offsets; + for(auto &token : *this) { if(token.is_identifier()) { - auto referenced=token.get_cursor().get_referenced(); + auto referenced = token.get_cursor().get_referenced(); if(referenced && Cursor::is_similar_kind(referenced.get_kind(), kind)) { - bool equal_spelling=false; - auto cx_string=clang_getTokenSpelling(cx_tu, token.cx_token); + bool equal_spelling = false; + auto cx_string = clang_getTokenSpelling(cx_tu, token.cx_token); if(cx_string.data) - equal_spelling=std::strcmp(static_cast(cx_string.data), spelling.c_str())==0; + equal_spelling = std::strcmp(static_cast(cx_string.data), spelling.c_str()) == 0; clang_disposeString(cx_string); if(equal_spelling) { - auto referenced_usrs=referenced.get_all_usr_extended(); - for(auto &usr: referenced_usrs) { + auto referenced_usrs = referenced.get_all_usr_extended(); + for(auto &usr : referenced_usrs) { if(usrs.count(usr)) { offsets.emplace_back(token.get_source_range().get_offsets()); break; diff --git a/src/tokens.h b/src/tokens.h index c7946aa..0fe86e8 100644 --- a/src/tokens.h +++ b/src/tokens.h @@ -1,25 +1,27 @@ #ifndef TOKENS_H_ #define TOKENS_H_ -#include #include "source_range.h" #include "token.h" +#include +#include #include #include -#include namespace clangmm { class Tokens : public std::vector { friend class TranslationUnit; friend class Diagnostic; - Tokens(CXTranslationUnit &cx_tu, const SourceRange &range, bool annotate_tokens=true); + Tokens(CXTranslationUnit &cx_tu, const SourceRange &range, bool annotate_tokens = true); + public: ~Tokens(); - std::vector > get_similar_token_offsets(Cursor::Kind kind, const std::string &spelling, - const std::unordered_set &usrs); + std::vector> get_similar_token_offsets(Cursor::Kind kind, const std::string &spelling, + const std::unordered_set &usrs); + private: CXToken *cx_tokens; std::unique_ptr cx_cursors; - CXTranslationUnit& cx_tu; + CXTranslationUnit &cx_tu; }; -} // namespace clangmm -#endif // TOKENS_H_ +} // namespace clangmm +#endif // TOKENS_H_ diff --git a/src/translation_unit.cc b/src/translation_unit.cc index 839d121..8a82d6b 100644 --- a/src/translation_unit.cc +++ b/src/translation_unit.cc @@ -5,22 +5,22 @@ #include #include -#include //TODO: remove +#include //TODO: remove using namespace std; //TODO: remove clangmm::TranslationUnit::TranslationUnit(Index &index, const std::string &file_path, const std::vector &command_line_args, const std::string &buffer, int flags) { - std::vector args; - for(auto &a: command_line_args) { + std::vector args; + for(auto &a : command_line_args) { args.push_back(a.c_str()); } - + CXUnsavedFile files[1]; - files[0].Filename=file_path.c_str(); - files[0].Contents=buffer.c_str(); - files[0].Length=buffer.size(); - + files[0].Filename = file_path.c_str(); + files[0].Contents = buffer.c_str(); + files[0].Length = buffer.size(); + cx_tu = clang_parseTranslationUnit(index.cx_index, file_path.c_str(), args.data(), args.size(), files, 1, flags); } @@ -28,11 +28,11 @@ clangmm::TranslationUnit::TranslationUnit(Index &index, const std::string &file_ clangmm::TranslationUnit::TranslationUnit(Index &index, const std::string &file_path, const std::vector &command_line_args, int flags) { - std::vector args; - for(auto &a: command_line_args) { + std::vector args; + for(auto &a : command_line_args) { args.push_back(a.c_str()); } - + cx_tu = clang_parseTranslationUnit(index.cx_index, file_path.c_str(), args.data(), args.size(), NULL, 0, flags); } @@ -43,39 +43,39 @@ clangmm::TranslationUnit::~TranslationUnit() { void clangmm::TranslationUnit::parse(Index &index, const std::string &file_path, const std::vector &command_line_args, - const std::map &buffers, int flags) { + const std::map &buffers, int flags) { std::vector files; - for (auto &buffer : buffers) { + for(auto &buffer : buffers) { CXUnsavedFile file; file.Filename = buffer.first.c_str(); file.Contents = buffer.second.c_str(); file.Length = buffer.second.size(); files.push_back(file); } - std::vector args; - for(auto &a: command_line_args) { + std::vector args; + for(auto &a : command_line_args) { args.push_back(a.c_str()); } - cx_tu = clang_parseTranslationUnit(index.cx_index, file_path.c_str(), args.data(), + cx_tu = clang_parseTranslationUnit(index.cx_index, file_path.c_str(), args.data(), args.size(), files.data(), files.size(), flags); } int clangmm::TranslationUnit::reparse(const std::string &buffer, int flags) { CXUnsavedFile files[1]; - - auto file_path=to_string(clang_getTranslationUnitSpelling(cx_tu)); - - files[0].Filename=file_path.c_str(); - files[0].Contents=buffer.c_str(); - files[0].Length=buffer.size(); - + + auto file_path = to_string(clang_getTranslationUnitSpelling(cx_tu)); + + files[0].Filename = file_path.c_str(); + files[0].Contents = buffer.c_str(); + files[0].Length = buffer.size(); + return clang_reparseTranslationUnit(cx_tu, 1, files, flags); } int clangmm::TranslationUnit::DefaultFlags() { - int flags=CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; -#if CINDEX_VERSION_MAJOR>0 || (CINDEX_VERSION_MAJOR==0 && CINDEX_VERSION_MINOR>=35) - flags|=CXTranslationUnit_KeepGoing; + int flags = CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; +#if CINDEX_VERSION_MAJOR > 0 || (CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR >= 35) + flags |= CXTranslationUnit_KeepGoing; #endif return flags; } @@ -88,8 +88,8 @@ clangmm::CodeCompleteResults clangmm::TranslationUnit::get_code_completions(cons std::vector clangmm::TranslationUnit::get_diagnostics() { std::vector diagnostics; - for(unsigned c=0;c clangmm::TranslationUnit::get_tokens(const std: } std::unique_ptr clangmm::TranslationUnit::get_tokens(unsigned start_offset, unsigned end_offset) { - auto path=clangmm::to_string(clang_getTranslationUnitSpelling(cx_tu)); + auto path = clangmm::to_string(clang_getTranslationUnitSpelling(cx_tu)); SourceLocation start_location(cx_tu, path, start_offset); SourceLocation end_location(cx_tu, path, end_offset); SourceRange range(start_location, end_location); @@ -118,7 +118,7 @@ std::unique_ptr clangmm::TranslationUnit::get_tokens(unsigned s std::unique_ptr clangmm::TranslationUnit::get_tokens(unsigned start_line, unsigned start_column, unsigned end_line, unsigned end_column) { - auto path=to_string(clang_getTranslationUnitSpelling(cx_tu)); + auto path = to_string(clang_getTranslationUnitSpelling(cx_tu)); SourceLocation start_location(cx_tu, path, start_line, start_column); SourceLocation end_location(cx_tu, path, end_line, end_column); SourceRange range(start_location, end_location); diff --git a/src/translation_unit.h b/src/translation_unit.h index eda2cf4..5475ff7 100644 --- a/src/translation_unit.h +++ b/src/translation_unit.h @@ -1,15 +1,15 @@ #ifndef TRANSLATIONUNIT_H_ #define TRANSLATIONUNIT_H_ +#include "code_complete_results.h" +#include "cursor.h" +#include "diagnostic.h" +#include "index.h" +#include "tokens.h" #include -#include -#include #include #include -#include "index.h" -#include "diagnostic.h" -#include "tokens.h" -#include "code_complete_results.h" -#include "cursor.h" +#include +#include namespace clangmm { class TranslationUnit { @@ -17,21 +17,21 @@ namespace clangmm { TranslationUnit(Index &index, const std::string &file_path, const std::vector &command_line_args, const std::string &buffer, - int flags=DefaultFlags()); + int flags = DefaultFlags()); TranslationUnit(Index &index, const std::string &file_path, const std::vector &command_line_args, - int flags=DefaultFlags()); + int flags = DefaultFlags()); ~TranslationUnit(); - - int reparse(const std::string &buffer, int flags=DefaultFlags()); - + + int reparse(const std::string &buffer, int flags = DefaultFlags()); + static int DefaultFlags(); - + void parse(Index &index, const std::string &file_path, const std::vector &command_line_args, const std::map &buffers, - int flags=DefaultFlags()); + int flags = DefaultFlags()); CodeCompleteResults get_code_completions(const std::string &buffer, unsigned line_number, unsigned column); @@ -50,6 +50,5 @@ namespace clangmm { CXTranslationUnit cx_tu; }; -} // namespace clangmm -#endif // TRANSLATIONUNIT_H_ - +} // namespace clangmm +#endif // TRANSLATIONUNIT_H_ diff --git a/src/utility.cc b/src/utility.cc index 2f12c89..8c52edc 100644 --- a/src/utility.cc +++ b/src/utility.cc @@ -3,22 +3,22 @@ std::string clangmm::to_string(CXString cx_string) { std::string string; - if(cx_string.data!=NULL) { - string=clang_getCString(cx_string); + if(cx_string.data != NULL) { + string = clang_getCString(cx_string); clang_disposeString(cx_string); } return string; } clangmm::String::String(const CXString &cx_string) : cx_string(cx_string) { - if(cx_string.data!=NULL) - c_str=clang_getCString(cx_string); + if(cx_string.data != NULL) + c_str = clang_getCString(cx_string); else - c_str=""; + c_str = ""; } clangmm::String::~String() { - if(cx_string.data!=NULL) + if(cx_string.data != NULL) clang_disposeString(cx_string); } @@ -28,76 +28,77 @@ void clangmm::remove_include_guard(std::string &buffer) { static std::regex define_regex("^[ \t]*#[ \t]*define[ \t]+([A-Za-z0-9_]+).*$"); static std::regex endif_regex("^[ \t]*#[ \t]*endif.*$"); std::vector> ranges; - bool found_ifndef=false, found_define=false; - bool line_comment=false, multiline_comment=false; - size_t start_of_line=0; + bool found_ifndef = false, found_define = false; + bool line_comment = false, multiline_comment = false; + size_t start_of_line = 0; std::string line; std::string preprocessor_identifier; - for(size_t c=0;c #include #include +#include int main() { - std::string tests_path=LIBCLANGMM_TESTS_PATH; - std::string path(tests_path+"/case/main.cpp"); + std::string tests_path = LIBCLANGMM_TESTS_PATH; + std::string path(tests_path + "/case/main.cpp"); std::vector arguments; - auto clang_version_string=clangmm::to_string(clang_getClangVersion()); + auto clang_version_string = clangmm::to_string(clang_getClangVersion()); const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$"); std::smatch sm; if(std::regex_match(clang_version_string, sm, clang_version_regex)) { - auto clang_version=sm[1].str(); - arguments.emplace_back("-I/usr/lib/clang/"+clang_version+"/include"); - arguments.emplace_back("-I/usr/lib64/clang/"+clang_version+"/include"); // For Fedora + auto clang_version = sm[1].str(); + arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include"); + arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora } clangmm::Index index(0, 0); clangmm::TranslationUnit tu(index, path, arguments); - std::string buffer="#include \n" - "int main(int argc, char *argv[]) {\n" - "std::string str;\n" - "str.\n" - "return 0\n" - "}"; + std::string buffer = "#include \n" + "int main(int argc, char *argv[]) {\n" + "std::string str;\n" + "str.\n" + "return 0\n" + "}"; tu.reparse(buffer); - auto results=tu.get_code_completions(buffer, 4, 5); + auto results = tu.get_code_completions(buffer, 4, 5); - bool substr_found=false; - for(unsigned c=0;c #include #include +#include int main() { { clangmm::CompletionChunk str("(", clangmm::CompletionChunk_LeftBrace); - + assert(str.text == "("); assert(str.kind == clangmm::CompletionChunk_LeftBrace); } - + { - std::string tests_path=LIBCLANGMM_TESTS_PATH; - std::string path(tests_path+"/case/main.cpp"); - + std::string tests_path = LIBCLANGMM_TESTS_PATH; + std::string path(tests_path + "/case/main.cpp"); + std::vector arguments; - auto clang_version_string=clangmm::to_string(clang_getClangVersion()); + auto clang_version_string = clangmm::to_string(clang_getClangVersion()); const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$"); std::smatch sm; if(std::regex_match(clang_version_string, sm, clang_version_regex)) { - auto clang_version=sm[1].str(); - arguments.emplace_back("-I/usr/lib/clang/"+clang_version+"/include"); - arguments.emplace_back("-I/usr/lib64/clang/"+clang_version+"/include"); // For Fedora + auto clang_version = sm[1].str(); + arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include"); + arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora } - + clangmm::Index index(0, 0); clangmm::TranslationUnit tu(index, path, arguments); - - std::string buffer="#include \n" - "int main(int argc, char *argv[]) {\n" - "std::string str;\n" - "str.\n" - "return 0\n" - "}"; - + + std::string buffer = "#include \n" + "int main(int argc, char *argv[]) {\n" + "std::string str;\n" + "str.\n" + "return 0\n" + "}"; + tu.reparse(buffer); - auto results=tu.get_code_completions(buffer, 4, 5); - + auto results = tu.get_code_completions(buffer, 4, 5); + auto str = results.get(0); - - assert(str.get_num_chunks()>0); - assert(str.get_chunks().size()>0); + + assert(str.get_num_chunks() > 0); + assert(str.get_chunks().size() > 0); } } diff --git a/tests/cursor_test.cc b/tests/cursor_test.cc index c1d573a..c89acf9 100644 --- a/tests/cursor_test.cc +++ b/tests/cursor_test.cc @@ -1,27 +1,27 @@ #include "clangmm.h" -#include #include #include +#include int main() { - std::string tests_path=LIBCLANGMM_TESTS_PATH; - std::string path(tests_path+"/case/main.cpp"); + std::string tests_path = LIBCLANGMM_TESTS_PATH; + std::string path(tests_path + "/case/main.cpp"); clangmm::Index index(0, 0); - + std::vector arguments; - auto clang_version_string=clangmm::to_string(clang_getClangVersion()); + auto clang_version_string = clangmm::to_string(clang_getClangVersion()); const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$"); std::smatch sm; if(std::regex_match(clang_version_string, sm, clang_version_regex)) { - auto clang_version=sm[1].str(); - arguments.emplace_back("-I/usr/lib/clang/"+clang_version+"/include"); - arguments.emplace_back("-I/usr/lib64/clang/"+clang_version+"/include"); // For Fedora + auto clang_version = sm[1].str(); + arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include"); + arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora } - + clangmm::TranslationUnit tu(index, path, arguments); - auto cursor=tu.get_cursor(path, 103); + auto cursor = tu.get_cursor(path, 103); assert(cursor.get_kind() == clangmm::Cursor::Kind::ReturnStmt); } diff --git a/tests/diagnostics_test.cc b/tests/diagnostics_test.cc index d73f7c4..4df561d 100644 --- a/tests/diagnostics_test.cc +++ b/tests/diagnostics_test.cc @@ -1,31 +1,31 @@ #include "clangmm.h" -#include -#include #include +#include +#include #include using namespace std; int main() { - std::string tests_path=LIBCLANGMM_TESTS_PATH; - std::string path(tests_path+"/case/main_error.cpp"); + std::string tests_path = LIBCLANGMM_TESTS_PATH; + std::string path(tests_path + "/case/main_error.cpp"); clangmm::Index index(0, 0); std::vector arguments; - auto clang_version_string=clangmm::to_string(clang_getClangVersion()); + auto clang_version_string = clangmm::to_string(clang_getClangVersion()); const static std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$"); std::smatch sm; if(std::regex_match(clang_version_string, sm, clang_version_regex)) { - auto clang_version=sm[1].str(); - arguments.emplace_back("-I/usr/lib/clang/"+clang_version+"/include"); - arguments.emplace_back("-I/usr/lib64/clang/"+clang_version+"/include"); // For Fedora + auto clang_version = sm[1].str(); + arguments.emplace_back("-I/usr/lib/clang/" + clang_version + "/include"); + arguments.emplace_back("-I/usr/lib64/clang/" + clang_version + "/include"); // For Fedora } clangmm::TranslationUnit tu(index, path, arguments); - - auto diagnostics=tu.get_diagnostics(); - assert(diagnostics.size()>0); + + auto diagnostics = tu.get_diagnostics(); + assert(diagnostics.size() > 0); assert(!diagnostics[0].spelling.empty()); - assert(diagnostics[0].severity==clangmm::Diagnostic::Severity::Error); + assert(diagnostics[0].severity == clangmm::Diagnostic::Severity::Error); } diff --git a/tests/source_location_test.cc b/tests/source_location_test.cc index a0d2956..499cddf 100644 --- a/tests/source_location_test.cc +++ b/tests/source_location_test.cc @@ -1,18 +1,18 @@ #include "clangmm.h" -#include #include +#include int main() { - std::string tests_path=LIBCLANGMM_TESTS_PATH; - std::string path(tests_path+"/case/main.cpp"); + std::string tests_path = LIBCLANGMM_TESTS_PATH; + std::string path(tests_path + "/case/main.cpp"); clangmm::Index index(0, 0); clangmm::TranslationUnit tu(index, path, {}); - auto tokens=tu.get_tokens(0, 113); + auto tokens = tu.get_tokens(0, 113); + + auto offsets = (*tokens)[28].get_source_range().get_offsets(); - auto offsets=(*tokens)[28].get_source_range().get_offsets(); - assert(offsets.first.line == 6 && offsets.first.index == 3); assert(offsets.second.line == 6 && offsets.second.index == 9); } diff --git a/tests/token_test.cc b/tests/token_test.cc index 1ffd22a..950c5b4 100644 --- a/tests/token_test.cc +++ b/tests/token_test.cc @@ -1,20 +1,20 @@ #include "clangmm.h" -#include #include +#include int main() { - std::string tests_path=LIBCLANGMM_TESTS_PATH; - std::string path(tests_path+"/case/main.cpp"); + std::string tests_path = LIBCLANGMM_TESTS_PATH; + std::string path(tests_path + "/case/main.cpp"); clangmm::Index index(0, 0); clangmm::TranslationUnit tu(index, path, {}); - - auto tokens=tu.get_tokens(0, 113); + + auto tokens = tu.get_tokens(0, 113); assert(tokens->size() == 32); assert((*tokens)[1].get_kind() == clangmm::Token::Kind::Identifier); std::string str = (*tokens)[28].get_spelling(); - assert(str == "return"); + assert(str == "return"); } diff --git a/tests/translation_unit_test.cc b/tests/translation_unit_test.cc index 0dbefc3..cd0a550 100644 --- a/tests/translation_unit_test.cc +++ b/tests/translation_unit_test.cc @@ -1,14 +1,14 @@ #include "clangmm.h" -#include -#include #include +#include +#include int main() { - std::string tests_path=LIBCLANGMM_TESTS_PATH; - std::string path(tests_path+"/case/main.cpp"); + std::string tests_path = LIBCLANGMM_TESTS_PATH; + std::string path(tests_path + "/case/main.cpp"); clangmm::Index index(0, 0); - + clangmm::TranslationUnit tu(index, path, {}); std::string buffer = "int main(int argc, char *argv[]) {\n"