IdentifierInfo **SelIdents,
unsigned NumSelIdents,
DeclContext *CurContext,
- ResultBuilder &Results) {
+ ResultBuilder &Results,
+ bool InOriginalClass = true) {
typedef CodeCompleteConsumer::Result Result;
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
MEnd = Container->meth_end();
Result R = Result(*M, 0);
R.StartParameter = NumSelIdents;
R.AllParametersAreInformative = (WantKind != MK_Any);
+ if (!InOriginalClass)
+ R.Priority += CCD_InBaseClass;
Results.MaybeAddResult(R, CurContext);
}
}
E = Protocols.end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
- CurContext, Results);
+ CurContext, Results, false);
// Add methods in categories.
for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
CatDecl = CatDecl->getNextClassCategory()) {
AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, InOriginalClass);
// Add a categories protocol methods.
const ObjCList<ObjCProtocolDecl> &Protocols
E = Protocols.end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, false);
// Add methods in category implementations.
if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, InOriginalClass);
}
// Add methods in superclass.
if (IFace->getSuperClass())
AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
- SelIdents, NumSelIdents, CurContext, Results);
+ SelIdents, NumSelIdents, CurContext, Results, false);
// Add methods in our implementation, if any.
if (ObjCImplementationDecl *Impl = IFace->getImplementation())
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, InOriginalClass);
}
Results.data(),Results.size());
}
-typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
+// Mapping from selectors to the methods that implement that selector, along
+// with the "in original class" flag.
+typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
+ KnownMethodsMap;
/// \brief Find all of the methods that reside in the given container
/// (and its superclasses, protocols, etc.) that meet the given
bool WantInstanceMethods,
QualType ReturnType,
bool IsInImplementation,
- KnownMethodsMap &KnownMethods) {
+ KnownMethodsMap &KnownMethods,
+ bool InOriginalClass = true) {
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
// Recurse into protocols.
const ObjCList<ObjCProtocolDecl> &Protocols
E = Protocols.end();
I != E; ++I)
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ InOriginalClass);
// If we're not in the implementation of a class, also visit the
// superclass.
if (!IsInImplementation && IFace->getSuperClass())
FindImplementableMethods(Context, IFace->getSuperClass(),
WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ false);
// Add methods from any class extensions (but not from categories;
// those should go into category implementations).
Cat = Cat->getNextClassExtension())
FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ InOriginalClass);
}
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
E = Protocols.end();
I != E; ++I)
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ InOriginalClass);
}
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
E = Protocols.end();
I != E; ++I)
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods, false);
}
// Add methods in this container. This operation occurs last because
!Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
continue;
- KnownMethods[(*M)->getSelector()] = *M;
+ KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
}
}
}
for (KnownMethodsMap::iterator M = KnownMethods.begin(),
MEnd = KnownMethods.end();
M != MEnd; ++M) {
- ObjCMethodDecl *Method = M->second;
+ ObjCMethodDecl *Method = M->second.first;
CodeCompletionString *Pattern = new CodeCompletionString;
// If the result type was not already provided, add it to the
Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
}
- Results.AddResult(Result(Pattern, CCP_CodePattern,
+ unsigned Priority = CCP_CodePattern;
+ if (!M->second.second)
+ Priority += CCD_InBaseClass;
+
+ Results.AddResult(Result(Pattern, Priority,
Method->isInstanceMethod()
? CXCursor_ObjCInstanceMethodDecl
: CXCursor_ObjCClassMethodDecl));