[cfe-commits] r112186 - in /cfe/trunk: include/clang/Sema/Action.h include/clang/Sema/CodeCompleteConsumer.h include/clang/Sema/Sema.h lib/Frontend/ASTUnit.cpp lib/Parse/ParseObjc.cpp lib/Sema/SemaCodeComplete.cpp test/Index/complete-at-exprstmt.m tools/libclang/CIndexCodeCompletion.cpp
Douglas Gregor
dgregor at apple.com
Thu Aug 26 08:07:07 PDT 2010
Author: dgregor
Date: Thu Aug 26 10:07:07 2010
New Revision: 112186
URL: http://llvm.org/viewvc/llvm-project?rev=112186&view=rev
Log:
Implement code completion for @selector expressions
Modified:
cfe/trunk/include/clang/Sema/Action.h
cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/test/Index/complete-at-exprstmt.m
cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
Modified: cfe/trunk/include/clang/Sema/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Action.h?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Action.h (original)
+++ cfe/trunk/include/clang/Sema/Action.h Thu Aug 26 10:07:07 2010
@@ -3078,6 +3078,16 @@
virtual void CodeCompleteObjCForCollection(Scope *S,
DeclGroupPtrTy IterationVar) { }
+ /// \brief Code completion for an Objective-C @selector expression, in which
+ /// we may have already parsed parts of the selector.
+ ///
+ /// \param S The scope in which the @selector expression occurs.
+ /// \param SelIdents The identifiers that describe the selector (thus far).
+ /// \param NumSelIdents The number of identifiers in \p SelIdents.
+ virtual void CodeCompleteObjCSelector(Scope *S,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) { }
+
/// \brief Code completion for a list of protocol references in Objective-C,
/// such as P1 and P2 in \c id<P1,P2>.
///
Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Thu Aug 26 10:07:07 2010
@@ -190,7 +190,9 @@
///
/// This context usually implies that no completions should be added,
/// unless they come from an appropriate natural-language dictionary.
- CCC_NaturalLanguage
+ CCC_NaturalLanguage,
+ /// \brief Code completion for a selector, as in an @selector expression.
+ CCC_SelectorName
};
private:
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Aug 26 10:07:07 2010
@@ -4202,6 +4202,9 @@
unsigned NumSelIdents);
virtual void CodeCompleteObjCForCollection(Scope *S,
DeclGroupPtrTy IterationVar);
+ virtual void CodeCompleteObjCSelector(Scope *S,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents);
virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
unsigned NumProtocols);
virtual void CodeCompleteObjCProtocolDecl(Scope *S);
Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Thu Aug 26 10:07:07 2010
@@ -1554,6 +1554,7 @@
case CodeCompletionContext::CCC_PreprocessorExpression:
case CodeCompletionContext::CCC_PreprocessorDirective:
case CodeCompletionContext::CCC_NaturalLanguage:
+ case CodeCompletionContext::CCC_SelectorName:
// We're looking for nothing, or we're looking for names that cannot
// be hidden.
return;
Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Thu Aug 26 10:07:07 2010
@@ -2194,6 +2194,15 @@
llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
SourceLocation LParenLoc = ConsumeParen();
SourceLocation sLoc;
+
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
+ KeyIdents.size());
+ ConsumeCodeCompletionToken();
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ return ExprError();
+ }
+
IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
return ExprError(Diag(Tok, diag::err_expected_ident));
@@ -2209,6 +2218,15 @@
ConsumeToken(); // Eat the ':'.
if (Tok.is(tok::r_paren))
break;
+
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
+ KeyIdents.size());
+ ConsumeCodeCompletionToken();
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ return ExprError();
+ }
+
// Check for another keyword selector.
SourceLocation Loc;
SelIdent = ParseObjCSelectorPiece(Loc);
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Aug 26 10:07:07 2010
@@ -25,6 +25,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
#include <list>
#include <map>
#include <vector>
@@ -3401,26 +3402,33 @@
MK_OneArgSelector //< One-argument selector.
};
-static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
- ObjCMethodKind WantKind,
- IdentifierInfo **SelIdents,
- unsigned NumSelIdents) {
- Selector Sel = Method->getSelector();
+static bool isAcceptableObjCSelector(Selector Sel,
+ ObjCMethodKind WantKind,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
if (NumSelIdents > Sel.getNumArgs())
return false;
-
+
switch (WantKind) {
- case MK_Any: break;
- case MK_ZeroArgSelector: return Sel.isUnarySelector();
- case MK_OneArgSelector: return Sel.getNumArgs() == 1;
+ case MK_Any: break;
+ case MK_ZeroArgSelector: return Sel.isUnarySelector();
+ case MK_OneArgSelector: return Sel.getNumArgs() == 1;
}
-
+
for (unsigned I = 0; I != NumSelIdents; ++I)
if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
return false;
-
+
return true;
}
+
+static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
+ ObjCMethodKind WantKind,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
+ return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
+ NumSelIdents);
+}
/// \brief Add all of the Objective-C methods in the given Objective-C
/// container to the set of results.
@@ -3979,6 +3987,57 @@
CodeCompleteExpression(S, Data);
}
+void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
+ // If we have an external source, load the entire class method
+ // pool from the AST file.
+ if (ExternalSource) {
+ for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+ I != N; ++I) {
+ Selector Sel = ExternalSource->GetExternalSelector(I);
+ if (Sel.isNull() || MethodPool.count(Sel))
+ continue;
+
+ ReadMethodPool(Sel);
+ }
+ }
+
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+ for (GlobalMethodPool::iterator M = MethodPool.begin(),
+ MEnd = MethodPool.end();
+ M != MEnd; ++M) {
+
+ Selector Sel = M->first;
+ if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
+ continue;
+
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ if (Sel.isUnarySelector()) {
+ Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+ Results.AddResult(Pattern);
+ continue;
+ }
+
+ for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
+ std::string Piece = Sel.getIdentifierInfoForSlot(I)->getName().str();
+ Piece += ':';
+ if (I < NumSelIdents)
+ Pattern->AddInformativeChunk(Piece);
+ else if (I == NumSelIdents)
+ Pattern->AddTypedTextChunk(Piece);
+ else
+ Pattern->AddTextChunk(Piece);
+ }
+ Results.AddResult(Pattern);
+ }
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_SelectorName,
+ Results.data(), Results.size());
+}
+
/// \brief Add all of the protocol declarations that we find in the given
/// (translation unit) context.
static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Modified: cfe/trunk/test/Index/complete-at-exprstmt.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-at-exprstmt.m?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-at-exprstmt.m (original)
+++ cfe/trunk/test/Index/complete-at-exprstmt.m Thu Aug 26 10:07:07 2010
@@ -9,6 +9,16 @@
@synchronized (@encode(MyClass)) { }
}
@end
+
+ at interface A
++ (int)add:(int)x to:(int)y;
++ (int)add:(int)x to:(int)y plus:(int)z;
+ at end
+
+void f() {
+ @selector(add:to:);
+}
+
// RUN: c-index-test -code-completion-at=%s:9:4 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
// CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
@@ -35,3 +45,11 @@
// CHECK-CC3: ObjCInterfaceDecl:{TypedText MyClass}
// CHECK-CC3: TypedefDecl:{TypedText SEL}
// CHECK-CC3: NotImplemented:{ResultType MyClass *}{TypedText self}
+// RUN: c-index-test -code-completion-at=%s:19:13 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{TypedText add:}{Text to:} (30)
+// CHECK-CC4: NotImplemented:{TypedText add:}{Text to:}{Text plus:} (30)
+// CHECK-CC4: NotImplemented:{TypedText myMethod:} (30)
+// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: NotImplemented:{Informative add:}{TypedText to:} (30)
+// CHECK-CC5: NotImplemented:{Informative add:}{TypedText to:}{Text plus:} (30)
+
Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Thu Aug 26 10:07:07 2010
@@ -818,4 +818,4 @@
unsigned NumResults) {
std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
}
-}
\ No newline at end of file
+}
More information about the cfe-commits
mailing list