summaryrefslogtreecommitdiffstats
path: root/tools/libclang
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-05-17 11:50:03 +0200
committerIvan Donchevskii <ivan.donchevskii@qt.io>2018-06-14 06:14:52 +0000
commite775457c4ede090c31de56fe20e5c59b6fe46b95 (patch)
treebb0158197bc7651e87b1beabbd6ea942d41bc992 /tools/libclang
parent74dff2b4165421e67427db09f02d6a52ae1fa96d (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.cpp36
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp57
-rw-r--r--tools/libclang/libclang.exports3
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