Add new libclang API, clang_codeCompleteGetObjCSelector(), which

provides the partial Objective-C selector used in a code
completion. From Connor Wakamo!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136084 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2011-07-26 15:24:30 +00:00
Родитель 2ad63cf714
Коммит 0a47d69af8
8 изменённых файлов: 82 добавлений и 7 удалений

Просмотреть файл

@ -3234,6 +3234,21 @@ enum CXCursorKind clang_codeCompleteGetContainerKind(
CINDEX_LINKAGE
CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results);
/**
* \brief Returns the currently-entered selector for an Objective-C message
* send, formatted like "initWithFoo:bar:". Only guaranteed to return a
* non-empty string for CXCompletionContext_ObjCInstanceMessage and
* CXCompletionContext_ObjCClassMessage.
*
* \param Results the code completion results to query
*
* \returns the selector (or partial selector) that has been entered thus far
* for an Objective-C message send.
*/
CINDEX_LINKAGE
CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results);
/**
* @}
*/

Просмотреть файл

@ -268,12 +268,23 @@ private:
/// \brief The type of the base object in a member access expression.
QualType BaseType;
/// \brief The identifiers for Objective-C selector parts.
IdentifierInfo **SelIdents;
/// \brief The number of Objective-C selector parts.
unsigned NumSelIdents;
public:
/// \brief Construct a new code-completion context of the given kind.
CodeCompletionContext(enum Kind Kind) : Kind(Kind) { }
CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(NULL),
NumSelIdents(0) { }
/// \brief Construct a new code-completion context of the given kind.
CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind) {
CodeCompletionContext(enum Kind Kind, QualType T,
IdentifierInfo **SelIdents = NULL,
unsigned NumSelIdents = 0) : Kind(Kind),
SelIdents(SelIdents),
NumSelIdents(NumSelIdents) {
if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess ||
Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage ||
Kind == CCC_ObjCInstanceMessage)
@ -294,6 +305,12 @@ public:
/// expression.
QualType getBaseType() const { return BaseType; }
/// \brief Retrieve the Objective-C selector identifiers.
IdentifierInfo **getSelIdents() const { return SelIdents; }
/// \brief Retrieve the number of Objective-C selector identifiers.
unsigned getNumSelIdents() const { return NumSelIdents; }
/// \brief Determines whether we want C++ constructors as results within this
/// context.
bool wantConstructorResults() const;

Просмотреть файл

@ -4960,7 +4960,7 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
T));
T, SelIdents, NumSelIdents));
AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
AtArgumentExpression, IsSuper, Results);
@ -5025,7 +5025,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
// Build the set of methods we can see.
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
ReceiverType));
ReceiverType, SelIdents, NumSelIdents));
Results.EnterNewScope();

Просмотреть файл

@ -228,6 +228,7 @@ void test_block_invoke(A *(^block1)(int),
// RUN: c-index-test -code-completion-at=%s:95:24 %s | FileCheck -check-prefix=CHECK-CC9 %s
// CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)}
// CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)}
// CHECK-CC9: Objective-C selector: Method:Arg1:
// RUN: c-index-test -code-completion-at=%s:61:11 %s | FileCheck -check-prefix=CHECK-CCA %s
// CHECK-CCA: TypedefDecl:{TypedText Class}
// CHECK-CCA-NEXT: ObjCInterfaceDecl:{TypedText Foo}
@ -253,6 +254,7 @@ void test_block_invoke(A *(^block1)(int),
// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)}{HorizontalSpace }{TypedText OtherArg:}{Placeholder (id)}
// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)}{HorizontalSpace }{TypedText OtherArg:}{Placeholder (id)}
// CHECK-CCD-NOT: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText }
// CHECK-CCD: Objective-C selector: Method:
// RUN: c-index-test -code-completion-at=%s:116:30 %s | FileCheck -check-prefix=CHECK-CCE %s
// CHECK-CCE: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)}
// CHECK-CCE: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)}

Просмотреть файл

@ -1201,6 +1201,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
unsigned i, n = results->NumResults, containerIsIncomplete = 0;
unsigned long long contexts;
enum CXCursorKind containerKind;
CXString objCSelector;
const char *selectorString;
if (!timing_only) {
/* Sort the code-completion results based on the typed text. */
clang_sortCodeCompletionResults(results->Results, results->NumResults);
@ -1218,7 +1220,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
contexts = clang_codeCompleteGetContexts(results);
print_completion_contexts(contexts, stdout);
containerKind = clang_codeCompleteGetContainerKind(results, &containerIsIncomplete);
containerKind = clang_codeCompleteGetContainerKind(results,
&containerIsIncomplete);
if (containerKind != CXCursor_InvalidCode) {
/* We have found a container */
@ -1239,6 +1242,13 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
clang_disposeString(containerUSR);
}
objCSelector = clang_codeCompleteGetObjCSelector(results);
selectorString = clang_getCString(objCSelector);
if (selectorString && strlen(selectorString) > 0) {
printf("Objective-C selector: %s\n", selectorString);
}
clang_disposeString(objCSelector);
clang_disposeCodeCompleteResults(results);
}
clang_disposeTranslationUnit(TU);

Просмотреть файл

@ -247,10 +247,17 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// current context.
unsigned long long Contexts;
/// \brief The kind of the container for the current context for completions.
enum CXCursorKind ContainerKind;
/// \brief The USR of the container for the current context for completions.
CXString ContainerUSR;
/// \brief a boolean value indicating whether there is complete information
/// about the container
unsigned ContainerIsIncomplete;
/// \brief A string containing the Objective-C selector entered thus far for a
/// message send.
std::string Selector;
};
/// \brief Tracks the number of code-completion result objects that are
@ -495,6 +502,18 @@ namespace {
AllocatedResults.ContextKind = contextKind;
AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
AllocatedResults.Selector = "";
if (Context.getNumSelIdents() > 0) {
for (unsigned i = 0; i < Context.getNumSelIdents(); i++) {
IdentifierInfo *selIdent = Context.getSelIdents()[i];
if (selIdent != NULL) {
StringRef selectorString = Context.getSelIdents()[i]->getName();
AllocatedResults.Selector += selectorString.str();
}
AllocatedResults.Selector += ":";
}
}
QualType baseType = Context.getBaseType();
NamedDecl *D = NULL;
@ -677,7 +696,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
}
pchName.push_back('\0');
struct stat stat_results;
if (stat(pchName.data(), &stat_results) == 0)
if (stat(pchName.str().c_str(), &stat_results) == 0)
usesPCH = true;
continue;
}
@ -811,6 +830,16 @@ CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
return createCXString(clang_getCString(Results->ContainerUSR));
}
CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
AllocatedCXCodeCompleteResults *Results =
static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
if (!Results)
return createCXString("");
return createCXString(Results->Selector);
}
} // end extern "C"
/// \brief Simple utility function that appends a \p New string to the given

Просмотреть файл

@ -10,6 +10,7 @@ _clang_codeCompleteGetNumDiagnostics
_clang_codeCompleteGetContainerKind
_clang_codeCompleteGetContainerUSR
_clang_codeCompleteGetContexts
_clang_codeCompleteGetObjCSelector
_clang_constructUSR_ObjCCategory
_clang_constructUSR_ObjCClass
_clang_constructUSR_ObjCIvar

Просмотреть файл

@ -10,6 +10,7 @@ clang_codeCompleteGetNumDiagnostics
clang_codeCompleteGetContainerKind
clang_codeCompleteGetContainerUSR
clang_codeCompleteGetContexts
clang_codeCompleteGetObjCSelector
clang_constructUSR_ObjCCategory
clang_constructUSR_ObjCClass
clang_constructUSR_ObjCIvar