[code completion] Complete ObjC methods in @implementation without leading

'-'/'+' prefix

rdar://12040840

llvm-svn: 316458
This commit is contained in:
Alex Lorenz 2017-10-24 16:39:37 +00:00
parent 1bc62f03a5
commit b874042e32
4 changed files with 49 additions and 15 deletions

View File

@ -10210,8 +10210,7 @@ public:
void CodeCompleteObjCPropertyDefinition(Scope *S);
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
IdentifierInfo *PropertyName);
void CodeCompleteObjCMethodDecl(Scope *S,
bool IsInstanceMethod,
void CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod,
ParsedType ReturnType);
void CodeCompleteObjCMethodDeclSelector(Scope *S,
bool IsInstanceMethod,

View File

@ -753,9 +753,15 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
SingleDecl = ParseObjCMethodDefinition();
break;
case tok::code_completion:
Actions.CodeCompleteOrdinaryName(getCurScope(),
CurParsedObjCImpl? Sema::PCC_ObjCImplementation
: Sema::PCC_Namespace);
if (CurParsedObjCImpl) {
// Code-complete Objective-C methods even without leading '-'/'+' prefix.
Actions.CodeCompleteObjCMethodDecl(getCurScope(),
/*IsInstanceMethod=*/None,
/*ReturnType=*/nullptr);
}
Actions.CodeCompleteOrdinaryName(
getCurScope(),
CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
cutOffParsing();
return nullptr;
case tok::kw_export:

View File

@ -6647,7 +6647,7 @@ typedef llvm::DenseMap<
/// indexed by selector so they can be easily found.
static void FindImplementableMethods(ASTContext &Context,
ObjCContainerDecl *Container,
bool WantInstanceMethods,
Optional<bool> WantInstanceMethods,
QualType ReturnType,
KnownMethodsMap &KnownMethods,
bool InOriginalClass = true) {
@ -6718,7 +6718,7 @@ static void FindImplementableMethods(ASTContext &Context,
// we want the methods from this container to override any methods
// we've previously seen with the same selector.
for (auto *M : Container->methods()) {
if (M->isInstanceMethod() == WantInstanceMethods) {
if (!WantInstanceMethods || M->isInstanceMethod() == *WantInstanceMethods) {
if (!ReturnType.isNull() &&
!Context.hasSameUnqualifiedType(ReturnType, M->getReturnType()))
continue;
@ -7390,8 +7390,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
}
}
void Sema::CodeCompleteObjCMethodDecl(Scope *S,
bool IsInstanceMethod,
void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod,
ParsedType ReturnTy) {
// Determine the return type of the method we're declaring, if
// provided.
@ -7446,7 +7445,13 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
ObjCMethodDecl *Method = M->second.getPointer();
CodeCompletionBuilder Builder(Results.getAllocator(),
Results.getCodeCompletionTUInfo());
// Add the '-'/'+' prefix if it wasn't provided yet.
if (!IsInstanceMethod) {
Builder.AddTextChunk(Method->isInstanceMethod() ? "-" : "+");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
}
// If the result type was not already provided, add it to the
// pattern as (type).
if (ReturnType.isNull()) {
@ -7548,11 +7553,13 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
if (IFace)
for (auto *Cat : IFace->visible_categories())
Containers.push_back(Cat);
for (unsigned I = 0, N = Containers.size(); I != N; ++I)
for (auto *P : Containers[I]->instance_properties())
AddObjCKeyValueCompletions(P, IsInstanceMethod, ReturnType, Context,
KnownSelectors, Results);
if (IsInstanceMethod) {
for (unsigned I = 0, N = Containers.size(); I != N; ++I)
for (auto *P : Containers[I]->instance_properties())
AddObjCKeyValueCompletions(P, *IsInstanceMethod, ReturnType, Context,
KnownSelectors, Results);
}
}
Results.ExitScope();

View File

@ -236,3 +236,25 @@ typedef A *MyObjectRef;
// RUN: c-index-test -code-completion-at=%s:107:2 %s -target x86_64-apple-macosx10.7 | FileCheck -check-prefix=CHECK-NULLABILITY2 %s
// CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text instancetype}{RightParen )}{TypedText getI3} (40)
// CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text I3 *}{RightParen )}{TypedText produceI3}{TypedText :}{LeftParen (}{Text I3 *}{RightParen )}{Text i3} (40)
@interface CompleteWithoutLeadingPrefix
- (void)aMethod;
+ (int)aClassMethod:(int)x;
@property int p;
@end
@implementation CompleteWithoutLeadingPrefix
@end
// RUN: c-index-test -code-completion-at=%s:250:1 %s | FileCheck -check-prefix=CHECK-COMP-NO-PREFIX %s
// CHECK-COMP-NO-PREFIX: NotImplemented:{TypedText @end} (40)
// CHECK-COMP-NO-PREFIX: ObjCClassMethodDecl:{Text +}{HorizontalSpace }{LeftParen (}{Text int}{RightParen )}{TypedText aClassMethod}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x} (40)
// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText aMethod} (40)
// CHECK-COMP-NO-PREFIX: ObjCInterfaceDecl:{TypedText I1}
// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text int}{RightParen )}{TypedText p} (40)
// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText setP}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text p} (40)