diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-05-17 11:50:03 +0200 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-06-14 06:14:52 +0000 |
commit | e775457c4ede090c31de56fe20e5c59b6fe46b95 (patch) | |
tree | bb0158197bc7651e87b1beabbd6ea942d41bc992 /tools/libclang | |
parent | 74dff2b4165421e67427db09f02d6a52ae1fa96d (diff) |
[backported/clang-7][libclang] Optionally add code completion results for arrow instead of dot
--------------------------------------------------------------------------
* https://reviews.llvm.org/D46862
--------------------------------------------------------------------------
Follow up for https://reviews.llvm.org/D41537 -
libclang part is extracted into this review
Change-Id: Ib166eb7b8675be605c81330df0c5f342942815ce
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'tools/libclang')
-rw-r--r-- | tools/libclang/CIndex.cpp | 36 | ||||
-rw-r--r-- | tools/libclang/CIndexCodeCompletion.cpp | 57 | ||||
-rw-r--r-- | tools/libclang/libclang.exports | 3 |
3 files changed, 92 insertions, 4 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 884206d9d1..c44c72e2ed 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -6642,6 +6642,42 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range, } while (Lex.getBufferLocation() < EffectiveBufferEnd); } +CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) { + LOG_FUNC_SECTION { + *Log << TU << ' ' << Location; + } + + if (isNotUsableTU(TU)) { + LOG_BAD_TU(TU); + return nullptr; + } + + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); + if (!CXXUnit) + return nullptr; + + SourceLocation Begin = cxloc::translateSourceLocation(Location); + if (Begin.isInvalid()) + return nullptr; + SourceManager &SM = CXXUnit->getSourceManager(); + std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin); + DecomposedEnd.second += Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts()); + + SourceLocation End = SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second); + + SmallVector<CXToken, 32> CXTokens; + getTokens(CXXUnit, SourceRange(Begin, End), CXTokens); + + if (CXTokens.empty()) + return nullptr; + + CXTokens.resize(1); + CXToken *Token = (CXToken *)malloc(sizeof(CXToken)); + + memmove(Token, CXTokens.data(), sizeof(CXToken)); + return Token; +} + void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens, unsigned *NumTokens) { LOG_FUNC_SECTION { diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp index d4af0870c0..32fc7325f0 100644 --- a/tools/libclang/CIndexCodeCompletion.cpp +++ b/tools/libclang/CIndexCodeCompletion.cpp @@ -16,6 +16,7 @@ #include "CIndexDiagnostic.h" #include "CLog.h" #include "CXCursor.h" +#include "CXSourceLocation.h" #include "CXString.h" #include "CXTranslationUnit.h" #include "clang/AST/Decl.h" @@ -302,10 +303,53 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults { /// \brief A string containing the Objective-C selector entered thus far for a /// message send. std::string Selector; + + /// \brief Vector of fix-its for each completion result that *must* be applied + /// before that result for the corresponding completion item. + std::vector<std::vector<FixItHint>> FixItsVector; }; } // end anonymous namespace +unsigned clang_getCompletionNumFixIts(CXCodeCompleteResults *results, + unsigned completion_index) { + AllocatedCXCodeCompleteResults *allocated_results = (AllocatedCXCodeCompleteResults *)results; + + if (!allocated_results || allocated_results->FixItsVector.size() <= completion_index) + return 0; + + return static_cast<unsigned>(allocated_results->FixItsVector[completion_index].size()); +} + +CXString clang_getCompletionFixIt(CXCodeCompleteResults *results, + unsigned completion_index, + unsigned fixit_index, + CXSourceRange *replacement_range) { + AllocatedCXCodeCompleteResults *allocated_results = (AllocatedCXCodeCompleteResults *)results; + + if (!allocated_results || allocated_results->FixItsVector.size() <= completion_index) { + if (replacement_range) + *replacement_range = clang_getNullRange(); + return cxstring::createNull(); + } + + ArrayRef<FixItHint> FixIts = allocated_results->FixItsVector[completion_index]; + if (FixIts.size() <= fixit_index) { + if (replacement_range) + *replacement_range = clang_getNullRange(); + return cxstring::createNull(); + } + + const FixItHint &FixIt = FixIts[fixit_index]; + if (replacement_range) { + *replacement_range = cxloc::translateSourceRange( + *allocated_results->SourceMgr, allocated_results->LangOpts, + FixIt.RemoveRange); + } + + return cxstring::createRef(FixIt.CodeToInsert.c_str()); +} + /// \brief Tracks the number of code-completion result objects that are /// currently active. /// @@ -531,8 +575,10 @@ namespace { CodeCompletionResult *Results, unsigned NumResults) override { StoredResults.reserve(StoredResults.size() + NumResults); + if (includeFixIts()) + AllocatedResults.FixItsVector.reserve(NumResults); for (unsigned I = 0; I != NumResults; ++I) { - CodeCompletionString *StoredCompletion + CodeCompletionString *StoredCompletion = Results[I].CreateCodeCompletionString(S, Context, getAllocator(), getCodeCompletionTUInfo(), includeBriefComments()); @@ -541,8 +587,10 @@ namespace { R.CursorKind = Results[I].CursorKind; R.CompletionString = StoredCompletion; StoredResults.push_back(R); + if (includeFixIts()) + AllocatedResults.FixItsVector.emplace_back(std::move(Results[I].FixIts)); } - + enum CodeCompletionContext::Kind contextKind = Context.getKind(); AllocatedResults.ContextKind = contextKind; @@ -643,13 +691,13 @@ clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename, ArrayRef<CXUnsavedFile> unsaved_files, unsigned options) { bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments; + bool IncludeFixIts = options & CXCodeComplete_IncludeCompletionsWithFixIts; #ifdef UDP_CODE_COMPLETION_LOGGER #ifdef UDP_CODE_COMPLETION_LOGGER_PORT const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime(); #endif #endif - bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr; if (cxtu::isNotUsableTU(TU)) { @@ -689,6 +737,7 @@ clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename, // Create a code-completion consumer to capture the results. CodeCompleteOptions Opts; Opts.IncludeBriefComments = IncludeBriefComments; + Opts.IncludeFixIts = IncludeFixIts; CaptureCompletionResults Capture(Opts, *Results, &TU); // Perform completion. @@ -962,7 +1011,7 @@ namespace { = (CodeCompletionString *)XR.CompletionString; CodeCompletionString *Y = (CodeCompletionString *)YR.CompletionString; - + SmallString<256> XBuffer; StringRef XText = GetTypedName(X, XBuffer); SmallString<256> YBuffer; diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 67e4b4334b..8deca1cb50 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -170,6 +170,8 @@ clang_getCompletionBriefComment clang_getCompletionChunkCompletionString clang_getCompletionChunkKind clang_getCompletionChunkText +clang_getCompletionNumFixIts +clang_getCompletionFixIt clang_getCompletionNumAnnotations clang_getCompletionParent clang_getCompletionPriority @@ -259,6 +261,7 @@ clang_getSpecializedCursorTemplate clang_getSpellingLocation clang_getTUResourceUsageName clang_getTemplateCursorKind +clang_getToken clang_getTokenExtent clang_getTokenKind clang_getTokenLocation |