From: Alex Lorenz Date: Tue, 24 Oct 2017 16:39:37 +0000 (+0000) Subject: [code completion] Complete ObjC methods in @implementation without leading X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=53710bdec511dfcfb69ee4d234b7f579b4955101;p=clang [code completion] Complete ObjC methods in @implementation without leading '-'/'+' prefix rdar://12040840 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316458 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 368ae18bab..ba9b604ebc 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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 IsInstanceMethod, ParsedType ReturnType); void CodeCompleteObjCMethodDeclSelector(Scope *S, bool IsInstanceMethod, diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index e24735dfc6..0b07ba1888 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -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: diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index fdfc39993d..06246d469f 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -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 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 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(); diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m index 8a17142266..f561f81496 100644 --- a/test/Index/complete-method-decls.m +++ b/test/Index/complete-method-decls.m @@ -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)