From be13afea6d9a5dc8877d5553552bd07c733a99bf Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 26 Aug 2010 02:23:45 +0000 Subject: [PATCH] Move the sorting of code-completion results out of the main path and into the clients, e.g., the printing code-completion consumer and c-index-test. Clients may want to re-sort the results anyway. Provide a libclang function that sorts the results. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112149 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang-c/Index.h | 11 ++++++++ lib/Frontend/ASTUnit.cpp | 4 +-- lib/Sema/CodeCompleteConsumer.cpp | 9 ++++++- lib/Sema/SemaCodeComplete.cpp | 2 -- tools/c-index-test/c-index-test.c | 26 +++++++++++++++++- tools/libclang/CIndexCodeCompletion.cpp | 35 +++++++++++++++++++++++++ tools/libclang/libclang.darwin.exports | 1 + tools/libclang/libclang.exports | 1 + 8 files changed, 82 insertions(+), 7 deletions(-) diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 9b80d9f3a5..9abaa516a0 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -2349,6 +2349,17 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, unsigned num_unsaved_files, unsigned options); +/** + * \brief Sort the code-completion results in case-insensitive alphabetical + * order. + * + * \param Results The set of results to sort. + * \param NumResults The number of results in \p Results. + */ +CINDEX_LINKAGE +void clang_sortCodeCompletionResults(CXCompletionResult *Results, + unsigned NumResults); + /** * \brief Free the given set of code-completion results. */ diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 452803acd2..874fd012b3 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -1678,9 +1678,7 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, Next.ProcessCodeCompleteResults(S, Context, Results, NumResults); return; } - - // Sort the completion results before passing them on to the actual consumer. - std::stable_sort(AllResults.begin(), AllResults.end()); + Next.ProcessCodeCompleteResults(S, Context, AllResults.data(), AllResults.size()); diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index 4345123558..c4e7bb4269 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -443,6 +443,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results, unsigned NumResults) { + std::stable_sort(Results, Results + NumResults); + // Print the results. for (unsigned I = 0; I != NumResults; ++I) { OS << "COMPLETION: "; @@ -660,6 +662,11 @@ bool clang::operator<(const CodeCompletionResult &X, if (cmp) return cmp < 0; + // If case-insensitive comparison fails, try case-sensitive comparison. + cmp = XStr.compare(YStr); + if (cmp) + return cmp < 0; + // Non-hidden names precede hidden names. if (X.Hidden != Y.Hidden) return !X.Hidden; @@ -695,7 +702,7 @@ CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef, unsigned NumCandidates) { for (unsigned I = 0; I != NumCandidates; ++I) { WriteUnsigned(OS, CXCursor_NotImplemented); - WriteUnsigned(OS, /*Priority=*/0); + WriteUnsigned(OS, /*Priority=*/I); WriteUnsigned(OS, /*Availability=*/CXAvailability_Available); CodeCompletionString *CCS = Candidates[I].CreateSignatureString(CurrentArg, SemaRef); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index fed6536570..d61ddcdf75 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -2277,8 +2277,6 @@ static void HandleCodeCompleteResults(Sema *S, CodeCompletionContext Context, CodeCompletionResult *Results, unsigned NumResults) { - std::stable_sort(Results, Results + NumResults); - if (CodeCompleter) CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults); diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 3f702904a3..67e0c7724f 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -1,6 +1,7 @@ /* c-index-test.c */ #include "clang-c/Index.h" +#include #include #include #include @@ -903,6 +904,25 @@ void print_completion_result(CXCompletionResult *completion_result, fprintf(file, "\n"); } +int my_stricmp(const char *s1, const char *s2) { + while (*s1 && *s2) { + int c1 = tolower(*s1), c2 = tolower(*s2); + if (c1 < c2) + return -1; + else if (c1 > c2) + return 1; + + ++s1; + ++s2; + } + + if (*s1) + return 1; + else if (*s2) + return -1; + return 0; +} + int perform_code_completion(int argc, const char **argv, int timing_only) { const char *input = argv[1]; char *filename = 0; @@ -958,9 +978,13 @@ int perform_code_completion(int argc, const char **argv, int timing_only) { if (results) { unsigned i, n = results->NumResults; - if (!timing_only) + if (!timing_only) { + /* Sort the code-completion results based on the typed text. */ + clang_sortCodeCompletionResults(results->Results, results->NumResults); + for (i = 0; i != n; ++i) print_completion_result(results->Results + i, stdout); + } n = clang_codeCompleteGetNumDiagnostics(results); for (i = 0; i != n; ++i) { CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i); diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp index 026d0be4ba..825031bd4b 100644 --- a/tools/libclang/CIndexCodeCompletion.cpp +++ b/tools/libclang/CIndexCodeCompletion.cpp @@ -582,6 +582,8 @@ namespace { AllocatedResults.Results[I].CompletionString = StoredCompletion; } } + + // FIXME: Add ProcessOverloadCandidates? }; } @@ -784,3 +786,36 @@ clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn, } // end extern "C" + +namespace { + struct OrderCompletionResults { + bool operator()(const CXCompletionResult &XR, + const CXCompletionResult &YR) const { + CXStoredCodeCompletionString *X + = (CXStoredCodeCompletionString *)XR.CompletionString; + CXStoredCodeCompletionString *Y + = (CXStoredCodeCompletionString *)YR.CompletionString; + + const char *XText = X->getTypedText(); + const char *YText = Y->getTypedText(); + if (!XText || !YText) + return XText != 0; + + int result = llvm::StringRef(XText).compare_lower(YText); + if (result < 0) + return true; + if (result > 0) + return false; + + result = llvm::StringRef(XText).compare(YText); + return result; + } + }; +} + +extern "C" { + void clang_sortCodeCompletionResults(CXCompletionResult *Results, + unsigned NumResults) { + std::stable_sort(Results, Results + NumResults, OrderCompletionResults()); + } +} \ No newline at end of file diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports index 6a36966501..d779190cc1 100644 --- a/tools/libclang/libclang.darwin.exports +++ b/tools/libclang/libclang.darwin.exports @@ -99,5 +99,6 @@ _clang_parseTranslationUnit _clang_reparseTranslationUnit _clang_saveTranslationUnit _clang_setUseExternalASTGeneration +_clang_sortCodeCompletionResults _clang_tokenize _clang_visitChildren diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 8f1d626957..df93a799f7 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -99,5 +99,6 @@ clang_parseTranslationUnit clang_reparseTranslationUnit clang_saveTranslationUnit clang_setUseExternalASTGeneration +clang_sortCodeCompletionResults clang_tokenize clang_visitChildren -- 2.40.0