mirror of
https://github.com/intel/llvm.git
synced 2026-02-01 08:56:15 +08:00
Introduce priorities into the code-completion results.
llvm-svn: 104751
This commit is contained in:
@@ -1794,6 +1794,21 @@ clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_getNumCompletionChunks(CXCompletionString completion_string);
|
||||
|
||||
/**
|
||||
* \brief Determine the priority of this code completion.
|
||||
*
|
||||
* The priority of a code completion indicates how likely it is that this
|
||||
* particular completion is the completion that the user will select. The
|
||||
* priority is selected by various internal heuristics.
|
||||
*
|
||||
* \param completion_string The completion string to query.
|
||||
*
|
||||
* \returns The priority of this completion string. Smaller values indicate
|
||||
* higher-priority (more likely) completions.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_getCompletionPriority(CXCompletionString completion_string);
|
||||
|
||||
/**
|
||||
* \brief Contains the results of code-completion.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,41 @@ class raw_ostream;
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief Default priority values for code-completion results based
|
||||
/// on their kind.
|
||||
enum {
|
||||
/// \brief Priority for a declaration that is in the local scope.
|
||||
CCP_LocalDeclaration = 8,
|
||||
/// \brief Priority for a member declaration found from the current
|
||||
/// method or member function.
|
||||
CCP_MemberDeclaration = 20,
|
||||
/// \brief Priority for a language keyword (that isn't any of the other
|
||||
/// categories).
|
||||
CCP_Keyword = 30,
|
||||
/// \brief Priority for a code pattern.
|
||||
CCP_CodePattern = 30,
|
||||
/// \brief Priority for a type.
|
||||
CCP_Type = 40,
|
||||
/// \brief Priority for a non-type declaration.
|
||||
CCP_Declaration = 50,
|
||||
/// \brief Priority for a constant value (e.g., enumerator).
|
||||
CCP_Constant = 60,
|
||||
/// \brief Priority for a preprocessor macro.
|
||||
CCP_Macro = 70,
|
||||
/// \brief Priority for a nested-name-specifier.
|
||||
CCP_NestedNameSpecifier = 75,
|
||||
/// \brief Priority for a result that isn't likely to be what the user wants,
|
||||
/// but is included for completeness.
|
||||
CCP_Unlikely = 80
|
||||
};
|
||||
|
||||
/// \brief Priority value deltas that are applied to code-completion results
|
||||
/// based on the context of the result.
|
||||
enum {
|
||||
/// \brief The result is in a base class.
|
||||
CCD_InBaseClass = 2
|
||||
};
|
||||
|
||||
class FunctionDecl;
|
||||
class FunctionType;
|
||||
class FunctionTemplateDecl;
|
||||
@@ -156,13 +191,14 @@ private:
|
||||
|
||||
public:
|
||||
CodeCompletionString() { }
|
||||
~CodeCompletionString();
|
||||
~CodeCompletionString() { clear(); }
|
||||
|
||||
typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator;
|
||||
iterator begin() const { return Chunks.begin(); }
|
||||
iterator end() const { return Chunks.end(); }
|
||||
bool empty() const { return Chunks.empty(); }
|
||||
unsigned size() const { return Chunks.size(); }
|
||||
void clear();
|
||||
|
||||
Chunk &operator[](unsigned I) {
|
||||
assert(I < size() && "Chunk index out-of-range");
|
||||
@@ -232,8 +268,9 @@ public:
|
||||
void Serialize(llvm::raw_ostream &OS) const;
|
||||
|
||||
/// \brief Deserialize a code-completion string from the given string.
|
||||
static CodeCompletionString *Deserialize(const char *&Str,
|
||||
const char *StrEnd);
|
||||
///
|
||||
/// \returns true if successful, false otherwise.
|
||||
bool Deserialize(const char *&Str, const char *StrEnd);
|
||||
};
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
|
||||
@@ -284,8 +321,11 @@ public:
|
||||
/// \brief When Kind == RK_Macro, the identifier that refers to a macro.
|
||||
IdentifierInfo *Macro;
|
||||
};
|
||||
|
||||
/// \brief Specifiers which parameter (of a function, Objective-C method,
|
||||
|
||||
/// \brief The priority of this particular code-completion result.
|
||||
unsigned Priority;
|
||||
|
||||
/// \brief Specifies which parameter (of a function, Objective-C method,
|
||||
/// macro, etc.) we should start with when formatting the result.
|
||||
unsigned StartParameter;
|
||||
|
||||
@@ -313,29 +353,30 @@ public:
|
||||
NestedNameSpecifier *Qualifier = 0,
|
||||
bool QualifierIsInformative = false)
|
||||
: Kind(RK_Declaration), Declaration(Declaration),
|
||||
StartParameter(0), Hidden(false),
|
||||
QualifierIsInformative(QualifierIsInformative),
|
||||
Priority(getPriorityFromDecl(Declaration)), StartParameter(0),
|
||||
Hidden(false), QualifierIsInformative(QualifierIsInformative),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(Qualifier) { }
|
||||
Qualifier(Qualifier) {
|
||||
}
|
||||
|
||||
/// \brief Build a result that refers to a keyword or symbol.
|
||||
Result(const char *Keyword)
|
||||
: Kind(RK_Keyword), Keyword(Keyword), StartParameter(0),
|
||||
Hidden(false), QualifierIsInformative(0),
|
||||
Result(const char *Keyword, unsigned Priority = CCP_Keyword)
|
||||
: Kind(RK_Keyword), Keyword(Keyword), Priority(Priority),
|
||||
StartParameter(0), Hidden(false), QualifierIsInformative(0),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(0) { }
|
||||
|
||||
/// \brief Build a result that refers to a macro.
|
||||
Result(IdentifierInfo *Macro)
|
||||
: Kind(RK_Macro), Macro(Macro), StartParameter(0),
|
||||
Result(IdentifierInfo *Macro, unsigned Priority = CCP_Macro)
|
||||
: Kind(RK_Macro), Macro(Macro), Priority(Priority), StartParameter(0),
|
||||
Hidden(false), QualifierIsInformative(0),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(0) { }
|
||||
|
||||
/// \brief Build a result that refers to a pattern.
|
||||
Result(CodeCompletionString *Pattern)
|
||||
: Kind(RK_Pattern), Pattern(Pattern), StartParameter(0),
|
||||
Hidden(false), QualifierIsInformative(0),
|
||||
Result(CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern)
|
||||
: Kind(RK_Pattern), Pattern(Pattern), Priority(Priority),
|
||||
StartParameter(0), Hidden(false), QualifierIsInformative(0),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(0) { }
|
||||
|
||||
@@ -356,6 +397,9 @@ public:
|
||||
CodeCompletionString *CreateCodeCompletionString(Sema &S);
|
||||
|
||||
void Destroy();
|
||||
|
||||
/// brief Determine a base priority for the given declaration.
|
||||
static unsigned getPriorityFromDecl(NamedDecl *ND);
|
||||
};
|
||||
|
||||
class OverloadCandidate {
|
||||
|
||||
@@ -210,9 +210,10 @@ CodeCompletionString::Chunk::Destroy() {
|
||||
}
|
||||
}
|
||||
|
||||
CodeCompletionString::~CodeCompletionString() {
|
||||
void CodeCompletionString::clear() {
|
||||
std::for_each(Chunks.begin(), Chunks.end(),
|
||||
std::mem_fun_ref(&Chunk::Destroy));
|
||||
Chunks.clear();
|
||||
}
|
||||
|
||||
std::string CodeCompletionString::getAsString() const {
|
||||
@@ -310,15 +311,13 @@ void CodeCompletionString::Serialize(llvm::raw_ostream &OS) const {
|
||||
}
|
||||
}
|
||||
|
||||
CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str,
|
||||
const char *StrEnd) {
|
||||
bool CodeCompletionString::Deserialize(const char *&Str, const char *StrEnd) {
|
||||
if (Str == StrEnd || *Str == 0)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
CodeCompletionString *Result = new CodeCompletionString;
|
||||
unsigned NumBlocks;
|
||||
if (ReadUnsigned(Str, StrEnd, NumBlocks))
|
||||
return Result;
|
||||
return false;
|
||||
|
||||
for (unsigned I = 0; I != NumBlocks; ++I) {
|
||||
if (Str + 1 >= StrEnd)
|
||||
@@ -327,7 +326,7 @@ CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str,
|
||||
// Parse the next kind.
|
||||
unsigned KindValue;
|
||||
if (ReadUnsigned(Str, StrEnd, KindValue))
|
||||
return Result;
|
||||
return false;
|
||||
|
||||
switch (ChunkKind Kind = (ChunkKind)KindValue) {
|
||||
case CK_TypedText:
|
||||
@@ -338,16 +337,17 @@ CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str,
|
||||
case CK_CurrentParameter: {
|
||||
unsigned StrLen;
|
||||
if (ReadUnsigned(Str, StrEnd, StrLen) || (Str + StrLen > StrEnd))
|
||||
return Result;
|
||||
return false;
|
||||
|
||||
Result->AddChunk(Chunk(Kind, StringRef(Str, StrLen)));
|
||||
AddChunk(Chunk(Kind, StringRef(Str, StrLen)));
|
||||
Str += StrLen;
|
||||
break;
|
||||
}
|
||||
|
||||
case CK_Optional: {
|
||||
std::auto_ptr<CodeCompletionString> Optional(Deserialize(Str, StrEnd));
|
||||
Result->AddOptionalChunk(Optional);
|
||||
std::auto_ptr<CodeCompletionString> Optional(new CodeCompletionString());
|
||||
if (Optional->Deserialize(Str, StrEnd))
|
||||
AddOptionalChunk(Optional);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -365,12 +365,12 @@ CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str,
|
||||
case CK_Equal:
|
||||
case CK_HorizontalSpace:
|
||||
case CK_VerticalSpace:
|
||||
Result->AddChunk(Chunk(Kind));
|
||||
AddChunk(Chunk(Kind));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return Result;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CodeCompleteConsumer::Result::Destroy() {
|
||||
@@ -380,6 +380,25 @@ void CodeCompleteConsumer::Result::Destroy() {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned CodeCompleteConsumer::Result::getPriorityFromDecl(NamedDecl *ND) {
|
||||
if (!ND)
|
||||
return CCP_Unlikely;
|
||||
|
||||
// Context-based decisions.
|
||||
DeclContext *DC = ND->getDeclContext()->getLookupContext();
|
||||
if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC))
|
||||
return CCP_LocalDeclaration;
|
||||
if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
|
||||
return CCP_MemberDeclaration;
|
||||
|
||||
// Content-based decisions.
|
||||
if (isa<EnumConstantDecl>(ND))
|
||||
return CCP_Constant;
|
||||
if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
|
||||
return CCP_Type;
|
||||
return CCP_Declaration;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Code completion overload candidate implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -584,6 +603,7 @@ CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
|
||||
}
|
||||
|
||||
WriteUnsigned(OS, Kind);
|
||||
WriteUnsigned(OS, Results[I].Priority);
|
||||
CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(SemaRef);
|
||||
assert(CCS && "No code-completion string?");
|
||||
CCS->Serialize(OS);
|
||||
@@ -598,6 +618,7 @@ CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
|
||||
unsigned NumCandidates) {
|
||||
for (unsigned I = 0; I != NumCandidates; ++I) {
|
||||
WriteUnsigned(OS, CXCursor_NotImplemented);
|
||||
WriteUnsigned(OS, /*Priority=*/0);
|
||||
CodeCompletionString *CCS
|
||||
= Candidates[I].CreateSignatureString(CurrentArg, SemaRef);
|
||||
assert(CCS && "No code-completion string?");
|
||||
|
||||
@@ -539,8 +539,10 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
|
||||
|
||||
// If the filter is for nested-name-specifiers, then this result starts a
|
||||
// nested-name-specifier.
|
||||
if (AsNestedNameSpecifier)
|
||||
if (AsNestedNameSpecifier) {
|
||||
R.StartsNestedNameSpecifier = true;
|
||||
R.Priority = CCP_NestedNameSpecifier;
|
||||
}
|
||||
|
||||
// If this result is supposed to have an informative qualifier, add one.
|
||||
if (R.QualifierIsInformative && !R.Qualifier &&
|
||||
@@ -588,8 +590,10 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
|
||||
|
||||
// If the filter is for nested-name-specifiers, then this result starts a
|
||||
// nested-name-specifier.
|
||||
if (AsNestedNameSpecifier)
|
||||
if (AsNestedNameSpecifier) {
|
||||
R.StartsNestedNameSpecifier = true;
|
||||
R.Priority = CCP_NestedNameSpecifier;
|
||||
}
|
||||
else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
|
||||
isa<CXXRecordDecl>(R.Declaration->getDeclContext()
|
||||
->getLookupContext()))
|
||||
@@ -608,6 +612,10 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
|
||||
R.QualifierIsInformative = false;
|
||||
}
|
||||
|
||||
// Adjust the priority if this result comes from a base class.
|
||||
if (InBaseClass)
|
||||
R.Priority += CCD_InBaseClass;
|
||||
|
||||
// Insert this result into the set of results.
|
||||
Results.push_back(R);
|
||||
}
|
||||
@@ -751,34 +759,34 @@ namespace {
|
||||
static void AddTypeSpecifierResults(const LangOptions &LangOpts,
|
||||
ResultBuilder &Results) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
Results.AddResult(Result("short"));
|
||||
Results.AddResult(Result("long"));
|
||||
Results.AddResult(Result("signed"));
|
||||
Results.AddResult(Result("unsigned"));
|
||||
Results.AddResult(Result("void"));
|
||||
Results.AddResult(Result("char"));
|
||||
Results.AddResult(Result("int"));
|
||||
Results.AddResult(Result("float"));
|
||||
Results.AddResult(Result("double"));
|
||||
Results.AddResult(Result("enum"));
|
||||
Results.AddResult(Result("struct"));
|
||||
Results.AddResult(Result("union"));
|
||||
Results.AddResult(Result("const"));
|
||||
Results.AddResult(Result("volatile"));
|
||||
Results.AddResult(Result("short", CCP_Type));
|
||||
Results.AddResult(Result("long", CCP_Type));
|
||||
Results.AddResult(Result("signed", CCP_Type));
|
||||
Results.AddResult(Result("unsigned", CCP_Type));
|
||||
Results.AddResult(Result("void", CCP_Type));
|
||||
Results.AddResult(Result("char", CCP_Type));
|
||||
Results.AddResult(Result("int", CCP_Type));
|
||||
Results.AddResult(Result("float", CCP_Type));
|
||||
Results.AddResult(Result("double", CCP_Type));
|
||||
Results.AddResult(Result("enum", CCP_Type));
|
||||
Results.AddResult(Result("struct", CCP_Type));
|
||||
Results.AddResult(Result("union", CCP_Type));
|
||||
Results.AddResult(Result("const", CCP_Type));
|
||||
Results.AddResult(Result("volatile", CCP_Type));
|
||||
|
||||
if (LangOpts.C99) {
|
||||
// C99-specific
|
||||
Results.AddResult(Result("_Complex"));
|
||||
Results.AddResult(Result("_Imaginary"));
|
||||
Results.AddResult(Result("_Bool"));
|
||||
Results.AddResult(Result("restrict"));
|
||||
Results.AddResult(Result("_Complex", CCP_Type));
|
||||
Results.AddResult(Result("_Imaginary", CCP_Type));
|
||||
Results.AddResult(Result("_Bool", CCP_Type));
|
||||
Results.AddResult(Result("restrict", CCP_Type));
|
||||
}
|
||||
|
||||
if (LangOpts.CPlusPlus) {
|
||||
// C++-specific
|
||||
Results.AddResult(Result("bool"));
|
||||
Results.AddResult(Result("class"));
|
||||
Results.AddResult(Result("wchar_t"));
|
||||
Results.AddResult(Result("bool", CCP_Type));
|
||||
Results.AddResult(Result("class", CCP_Type));
|
||||
Results.AddResult(Result("wchar_t", CCP_Type));
|
||||
|
||||
if (Results.includeCodePatterns()) {
|
||||
// typename qualified-id
|
||||
@@ -790,10 +798,17 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts,
|
||||
}
|
||||
|
||||
if (LangOpts.CPlusPlus0x) {
|
||||
Results.AddResult(Result("auto"));
|
||||
Results.AddResult(Result("char16_t"));
|
||||
Results.AddResult(Result("char32_t"));
|
||||
Results.AddResult(Result("decltype"));
|
||||
Results.AddResult(Result("auto", CCP_Type));
|
||||
Results.AddResult(Result("char16_t", CCP_Type));
|
||||
Results.AddResult(Result("char32_t", CCP_Type));
|
||||
if (Results.includeCodePatterns()) {
|
||||
CodeCompletionString *Pattern = new CodeCompletionString;
|
||||
Pattern->AddTypedTextChunk("decltype");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Pattern->AddPlaceholderChunk("expression-or-type");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Results.AddResult(Result(Pattern));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1299,6 +1314,8 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
|
||||
Pattern->AddPlaceholderChunk("expression");
|
||||
Results.AddResult(Result(Pattern));
|
||||
}
|
||||
|
||||
// FIXME: Rethrow?
|
||||
}
|
||||
|
||||
if (SemaRef.getLangOptions().ObjC1) {
|
||||
|
||||
@@ -8,8 +8,11 @@ int test(int i, int j, int k, int l) {
|
||||
}
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )}
|
||||
// CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )}
|
||||
// CHECK-CC1: macro definition:{TypedText __VERSION__} (70)
|
||||
// CHECK-CC1: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (50)
|
||||
// CHECK-CC1: NotImplemented:{TypedText float} (40)
|
||||
// CHECK-CC1: ParmDecl:{ResultType int}{TypedText j} (8)
|
||||
// CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
|
||||
// RUN: c-index-test -code-completion-at=%s:7:14 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// RUN: c-index-test -code-completion-at=%s:7:18 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// RUN: c-index-test -code-completion-at=%s:7:22 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
|
||||
@@ -26,5 +26,5 @@ void test_props(Int* ptr) {
|
||||
// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText prop1}
|
||||
// CHECK-CC1: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp}
|
||||
// RUN: c-index-test -code-completion-at=%s:22:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText IVar}
|
||||
// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText SuperIVar}
|
||||
// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText IVar} (20)
|
||||
// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText SuperIVar} (22)
|
||||
|
||||
@@ -782,7 +782,8 @@ void print_completion_result(CXCompletionResult *completion_result,
|
||||
clang_disposeString(ks);
|
||||
|
||||
print_completion_string(completion_result->CompletionString, file);
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, " (%u)\n",
|
||||
clang_getCompletionPriority(completion_result->CompletionString));
|
||||
}
|
||||
|
||||
int perform_code_completion(int argc, const char **argv) {
|
||||
|
||||
@@ -37,12 +37,27 @@
|
||||
using namespace clang;
|
||||
using namespace clang::cxstring;
|
||||
|
||||
namespace {
|
||||
/// \brief Stored representation of a completion string.
|
||||
///
|
||||
/// This is the representation behind a CXCompletionString.
|
||||
class CXStoredCodeCompletionString : public CodeCompletionString {
|
||||
unsigned Priority;
|
||||
|
||||
public:
|
||||
CXStoredCodeCompletionString(unsigned Priority) : Priority(Priority) { }
|
||||
|
||||
unsigned getPriority() const { return Priority; }
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
enum CXCompletionChunkKind
|
||||
clang_getCompletionChunkKind(CXCompletionString completion_string,
|
||||
unsigned chunk_number) {
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
if (!CCStr || chunk_number >= CCStr->size())
|
||||
return CXCompletionChunk_Text;
|
||||
|
||||
@@ -97,7 +112,8 @@ clang_getCompletionChunkKind(CXCompletionString completion_string,
|
||||
|
||||
CXString clang_getCompletionChunkText(CXCompletionString completion_string,
|
||||
unsigned chunk_number) {
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
if (!CCStr || chunk_number >= CCStr->size())
|
||||
return createCXString(0);
|
||||
|
||||
@@ -140,7 +156,8 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
|
||||
CXCompletionString
|
||||
clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
|
||||
unsigned chunk_number) {
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
if (!CCStr || chunk_number >= CCStr->size())
|
||||
return 0;
|
||||
|
||||
@@ -177,10 +194,17 @@ clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
|
||||
}
|
||||
|
||||
unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
return CCStr? CCStr->size() : 0;
|
||||
}
|
||||
|
||||
unsigned clang_getCompletionPriority(CXCompletionString completion_string) {
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
return CCStr? CCStr->getPriority() : CCP_Unlikely;
|
||||
}
|
||||
|
||||
static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
|
||||
unsigned &Value) {
|
||||
if (Memory + sizeof(unsigned) > MemoryEnd)
|
||||
@@ -226,7 +250,7 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults()
|
||||
|
||||
AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
|
||||
for (unsigned I = 0, N = NumResults; I != N; ++I)
|
||||
delete (CodeCompletionString *)Results[I].CompletionString;
|
||||
delete (CXStoredCodeCompletionString *)Results[I].CompletionString;
|
||||
delete [] Results;
|
||||
delete Buffer;
|
||||
|
||||
@@ -376,10 +400,16 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
|
||||
if (ReadUnsigned(Str, StrEnd, KindValue))
|
||||
break;
|
||||
|
||||
CodeCompletionString *CCStr
|
||||
= CodeCompletionString::Deserialize(Str, StrEnd);
|
||||
if (!CCStr)
|
||||
unsigned Priority;
|
||||
if (ReadUnsigned(Str, StrEnd, Priority))
|
||||
break;
|
||||
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= new CXStoredCodeCompletionString(Priority);
|
||||
if (!CCStr->Deserialize(Str, StrEnd)) {
|
||||
delete CCStr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!CCStr->empty()) {
|
||||
// Vend the code-completion result to the caller.
|
||||
|
||||
@@ -30,6 +30,7 @@ _clang_getClangVersion
|
||||
_clang_getCompletionChunkCompletionString
|
||||
_clang_getCompletionChunkKind
|
||||
_clang_getCompletionChunkText
|
||||
_clang_getCompletionPriority
|
||||
_clang_getCursor
|
||||
_clang_getCursorDefinition
|
||||
_clang_getCursorExtent
|
||||
|
||||
@@ -30,6 +30,7 @@ clang_getClangVersion
|
||||
clang_getCompletionChunkCompletionString
|
||||
clang_getCompletionChunkKind
|
||||
clang_getCompletionChunkText
|
||||
clang_getCompletionPriority
|
||||
clang_getCursor
|
||||
clang_getCursorDefinition
|
||||
clang_getCursorExtent
|
||||
|
||||
Reference in New Issue
Block a user