diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-08-26 15:07:07 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-08-26 15:07:07 +0000 |
commit | 458433d2f0f5c96a9e0d21decdd44bebccf20b11 (patch) | |
tree | 794359d35a7e2ddc77c732b524ab73c367639c6a /lib/Sema/SemaCodeComplete.cpp | |
parent | 9a2d44c5fbc46ce9ee6dd829a7bac8ca750ad090 (diff) |
Implement code completion for @selector expressions
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112186 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 81 |
1 files changed, 70 insertions, 11 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index d61ddcdf75..b75a7d05bb 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -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 @@ enum ObjCMethodKind { 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 @@ void Sema::CodeCompleteObjCForCollection(Scope *S, 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, |