forked from OSchip/llvm-project
Code completion for Objective-C class names after @interface,
@implementation, and in the declaration of the superclass of an @interface. llvm-svn: 89207
This commit is contained in:
parent
c14422223b
commit
49c22a74eb
|
@ -2371,6 +2371,24 @@ public:
|
|||
///
|
||||
/// \param S the scope in which the protocol declaration occurs.
|
||||
virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
|
||||
|
||||
/// \brief Code completion for an Objective-C interface, after the
|
||||
/// @interface but before any identifier.
|
||||
virtual void CodeCompleteObjCInterfaceDecl(Scope *S) { }
|
||||
|
||||
/// \brief Code completion for the superclass of an Objective-C
|
||||
/// interface, after the ':'.
|
||||
///
|
||||
/// \param S the scope in which the interface declaration occurs.
|
||||
///
|
||||
/// \param ClassName the name of the class being defined.
|
||||
virtual void CodeCompleteObjCSuperclass(Scope *S,
|
||||
IdentifierInfo *ClassName) {
|
||||
}
|
||||
|
||||
/// \brief Code completion for an Objective-C implementation, after the
|
||||
/// @implementation but before any identifier.
|
||||
virtual void CodeCompleteObjCImplementationDecl(Scope *S) { }
|
||||
//@}
|
||||
};
|
||||
|
||||
|
|
|
@ -123,6 +123,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
|||
"ParseObjCAtInterfaceDeclaration(): Expected @interface");
|
||||
ConsumeToken(); // the "interface" identifier
|
||||
|
||||
// Code completion after '@interface'.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCInterfaceDecl(CurScope);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing class or category name.
|
||||
return DeclPtrTy();
|
||||
|
@ -181,6 +187,13 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
|||
|
||||
if (Tok.is(tok::colon)) { // a super class is specified.
|
||||
ConsumeToken();
|
||||
|
||||
// Code completion of superclass names.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCSuperclass(CurScope, nameId);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing super class name.
|
||||
return DeclPtrTy();
|
||||
|
@ -1078,6 +1091,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
|
|||
"ParseObjCAtImplementationDeclaration(): Expected @implementation");
|
||||
ConsumeToken(); // the "implementation" identifier
|
||||
|
||||
// Code completion after '@implementation'.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCImplementationDecl(CurScope);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing class or category name.
|
||||
return DeclPtrTy();
|
||||
|
|
|
@ -3645,7 +3645,11 @@ public:
|
|||
virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
|
||||
unsigned NumProtocols);
|
||||
virtual void CodeCompleteObjCProtocolDecl(Scope *S);
|
||||
//@}
|
||||
virtual void CodeCompleteObjCInterfaceDecl(Scope *S);
|
||||
virtual void CodeCompleteObjCSuperclass(Scope *S,
|
||||
IdentifierInfo *ClassName);
|
||||
virtual void CodeCompleteObjCImplementationDecl(Scope *S);
|
||||
//@}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Extra semantic analysis beyond the C type system
|
||||
|
|
|
@ -1885,3 +1885,73 @@ void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
|
|||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
/// \brief Add all of the Objective-C interface declarations that we find in
|
||||
/// the given (translation unit) context.
|
||||
static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
|
||||
bool OnlyForwardDeclarations,
|
||||
bool OnlyUnimplemented,
|
||||
ResultBuilder &Results) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
||||
for (DeclContext::decl_iterator D = Ctx->decls_begin(),
|
||||
DEnd = Ctx->decls_end();
|
||||
D != DEnd; ++D) {
|
||||
// Record any interfaces we find.
|
||||
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
|
||||
if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
|
||||
(!OnlyUnimplemented || !Class->getImplementation()))
|
||||
Results.MaybeAddResult(Result(Class, 0), CurContext);
|
||||
|
||||
// Record any forward-declared interfaces we find.
|
||||
if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
|
||||
for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
|
||||
C != CEnd; ++C)
|
||||
if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
|
||||
(!OnlyUnimplemented || !C->getInterface()->getImplementation()))
|
||||
Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// Add all classes.
|
||||
AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
|
||||
false, Results);
|
||||
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// Make sure that we ignore the class we're currently defining.
|
||||
NamedDecl *CurClass
|
||||
= LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
|
||||
if (isa<ObjCInterfaceDecl>(CurClass))
|
||||
Results.Ignore(CurClass);
|
||||
|
||||
// Add all classes.
|
||||
AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
|
||||
false, Results);
|
||||
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// Add all unimplemented classes.
|
||||
AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
|
||||
true, Results);
|
||||
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* Note: the RUN lines are near the end of the file, since line/column
|
||||
matter for this test. */
|
||||
|
||||
@class Int1, Int2, Int3, Int4;
|
||||
|
||||
@interface Int3
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@interface Int2 : Int3
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Int2
|
||||
@end
|
||||
|
||||
@implementation Int3
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:6:12 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int2}
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int2}
|
||||
// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:11:19 %s | FileCheck -check-prefix=CHECK-CC3 %s
|
||||
// CHECK-CC3: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:16:17 %s | FileCheck -check-prefix=CHECK-CC4 %s
|
||||
// CHECK-CC4: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int2}
|
||||
// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
|
||||
// CHECK-CC5: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
Loading…
Reference in New Issue