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.

llvm-svn: 112149
This commit is contained in:
Douglas Gregor 2010-08-26 02:23:45 +00:00
parent b45a1e735a
commit 78ecc499eb
8 changed files with 82 additions and 7 deletions

View File

@ -2349,6 +2349,17 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
unsigned num_unsaved_files, unsigned num_unsaved_files,
unsigned options); 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. * \brief Free the given set of code-completion results.
*/ */

View File

@ -1678,9 +1678,7 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
Next.ProcessCodeCompleteResults(S, Context, Results, NumResults); Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
return; 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(), Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
AllResults.size()); AllResults.size());

View File

@ -443,6 +443,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
CodeCompletionContext Context, CodeCompletionContext Context,
CodeCompletionResult *Results, CodeCompletionResult *Results,
unsigned NumResults) { unsigned NumResults) {
std::stable_sort(Results, Results + NumResults);
// Print the results. // Print the results.
for (unsigned I = 0; I != NumResults; ++I) { for (unsigned I = 0; I != NumResults; ++I) {
OS << "COMPLETION: "; OS << "COMPLETION: ";
@ -660,6 +662,11 @@ bool clang::operator<(const CodeCompletionResult &X,
if (cmp) if (cmp)
return cmp < 0; 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. // Non-hidden names precede hidden names.
if (X.Hidden != Y.Hidden) if (X.Hidden != Y.Hidden)
return !X.Hidden; return !X.Hidden;
@ -695,7 +702,7 @@ CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
unsigned NumCandidates) { unsigned NumCandidates) {
for (unsigned I = 0; I != NumCandidates; ++I) { for (unsigned I = 0; I != NumCandidates; ++I) {
WriteUnsigned(OS, CXCursor_NotImplemented); WriteUnsigned(OS, CXCursor_NotImplemented);
WriteUnsigned(OS, /*Priority=*/0); WriteUnsigned(OS, /*Priority=*/I);
WriteUnsigned(OS, /*Availability=*/CXAvailability_Available); WriteUnsigned(OS, /*Availability=*/CXAvailability_Available);
CodeCompletionString *CCS CodeCompletionString *CCS
= Candidates[I].CreateSignatureString(CurrentArg, SemaRef); = Candidates[I].CreateSignatureString(CurrentArg, SemaRef);

View File

@ -2277,8 +2277,6 @@ static void HandleCodeCompleteResults(Sema *S,
CodeCompletionContext Context, CodeCompletionContext Context,
CodeCompletionResult *Results, CodeCompletionResult *Results,
unsigned NumResults) { unsigned NumResults) {
std::stable_sort(Results, Results + NumResults);
if (CodeCompleter) if (CodeCompleter)
CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults); CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);

View File

@ -1,6 +1,7 @@
/* c-index-test.c */ /* c-index-test.c */
#include "clang-c/Index.h" #include "clang-c/Index.h"
#include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -903,6 +904,25 @@ void print_completion_result(CXCompletionResult *completion_result,
fprintf(file, "\n"); 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) { int perform_code_completion(int argc, const char **argv, int timing_only) {
const char *input = argv[1]; const char *input = argv[1];
char *filename = 0; char *filename = 0;
@ -958,9 +978,13 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
if (results) { if (results) {
unsigned i, n = results->NumResults; 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) for (i = 0; i != n; ++i)
print_completion_result(results->Results + i, stdout); print_completion_result(results->Results + i, stdout);
}
n = clang_codeCompleteGetNumDiagnostics(results); n = clang_codeCompleteGetNumDiagnostics(results);
for (i = 0; i != n; ++i) { for (i = 0; i != n; ++i) {
CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i); CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i);

View File

@ -582,6 +582,8 @@ namespace {
AllocatedResults.Results[I].CompletionString = StoredCompletion; AllocatedResults.Results[I].CompletionString = StoredCompletion;
} }
} }
// FIXME: Add ProcessOverloadCandidates?
}; };
} }
@ -784,3 +786,36 @@ clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
} // end extern "C" } // 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());
}
}

View File

@ -99,5 +99,6 @@ _clang_parseTranslationUnit
_clang_reparseTranslationUnit _clang_reparseTranslationUnit
_clang_saveTranslationUnit _clang_saveTranslationUnit
_clang_setUseExternalASTGeneration _clang_setUseExternalASTGeneration
_clang_sortCodeCompletionResults
_clang_tokenize _clang_tokenize
_clang_visitChildren _clang_visitChildren

View File

@ -99,5 +99,6 @@ clang_parseTranslationUnit
clang_reparseTranslationUnit clang_reparseTranslationUnit
clang_saveTranslationUnit clang_saveTranslationUnit
clang_setUseExternalASTGeneration clang_setUseExternalASTGeneration
clang_sortCodeCompletionResults
clang_tokenize clang_tokenize
clang_visitChildren clang_visitChildren