mirror of
https://github.com/intel/llvm.git
synced 2026-01-27 06:06:34 +08:00
Code completion for Objective-C @ keywords that are statements or expressions
llvm-svn: 90757
This commit is contained in:
@@ -2420,6 +2420,12 @@ public:
|
||||
virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
|
||||
bool InInterface) { }
|
||||
|
||||
/// \brief Code completion after the '@' in a statement.
|
||||
virtual void CodeCompleteObjCAtStatement(Scope *S) { }
|
||||
|
||||
/// \brief Code completion after the '@' in an expression.
|
||||
virtual void CodeCompleteObjCAtExpression(Scope *S) { }
|
||||
|
||||
/// \brief Code completion for an ObjC property decl.
|
||||
///
|
||||
/// This code completion action is invoked when the code-completion token is
|
||||
|
||||
@@ -1563,7 +1563,11 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
|
||||
}
|
||||
|
||||
Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
|
||||
if (Tok.isObjCAtKeyword(tok::objc_try)) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCAtStatement(CurScope);
|
||||
ConsumeToken();
|
||||
return StmtError();
|
||||
} else if (Tok.isObjCAtKeyword(tok::objc_try)) {
|
||||
return ParseObjCTryStmt(AtLoc);
|
||||
} else if (Tok.isObjCAtKeyword(tok::objc_throw))
|
||||
return ParseObjCThrowStmt(AtLoc);
|
||||
@@ -1584,6 +1588,11 @@ Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
|
||||
|
||||
Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
||||
switch (Tok.getKind()) {
|
||||
case tok::code_completion:
|
||||
Actions.CodeCompleteObjCAtExpression(CurScope);
|
||||
ConsumeToken();
|
||||
return ExprError();
|
||||
|
||||
case tok::string_literal: // primary-expression: string-literal
|
||||
case tok::wide_string_literal:
|
||||
return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
|
||||
|
||||
@@ -3780,6 +3780,8 @@ public:
|
||||
|
||||
virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
|
||||
bool InInterface);
|
||||
virtual void CodeCompleteObjCAtStatement(Scope *S);
|
||||
virtual void CodeCompleteObjCAtExpression(Scope *S);
|
||||
virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
|
||||
virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods,
|
||||
|
||||
@@ -778,7 +778,7 @@ static unsigned CollectLookupResults(Scope *S,
|
||||
}
|
||||
|
||||
/// \brief Add type specifiers for the current language as keyword results.
|
||||
static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
|
||||
static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
|
||||
ResultBuilder &Results) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
Results.MaybeAddResult(Result("short", Rank));
|
||||
@@ -1935,6 +1935,95 @@ void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
CodeCompletionString *Pattern = 0;
|
||||
|
||||
// @encode ( type-name )
|
||||
Pattern = new CodeCompletionString;
|
||||
Pattern->AddTypedTextChunk("encode");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Pattern->AddPlaceholderChunk("type-name");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Results.MaybeAddResult(Result(Pattern, Rank));
|
||||
|
||||
// @protocol ( protocol-name )
|
||||
Pattern = new CodeCompletionString;
|
||||
Pattern->AddTypedTextChunk("protocol");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Pattern->AddPlaceholderChunk("protocol-name");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Results.MaybeAddResult(Result(Pattern, Rank));
|
||||
|
||||
// @selector ( selector )
|
||||
Pattern = new CodeCompletionString;
|
||||
Pattern->AddTypedTextChunk("selector");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Pattern->AddPlaceholderChunk("selector");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Results.MaybeAddResult(Result(Pattern, Rank));
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCAtStatement(Scope *S) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
CodeCompletionString *Pattern = 0;
|
||||
|
||||
// @try { statements } @catch ( declaration ) { statements } @finally
|
||||
// { statements }
|
||||
Pattern = new CodeCompletionString;
|
||||
Pattern->AddTypedTextChunk("try");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
|
||||
Pattern->AddPlaceholderChunk("statements");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
|
||||
Pattern->AddTextChunk("@catch");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Pattern->AddPlaceholderChunk("parameter");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
|
||||
Pattern->AddPlaceholderChunk("statements");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
|
||||
Pattern->AddTextChunk("@finally");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
|
||||
Pattern->AddPlaceholderChunk("statements");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
|
||||
Results.MaybeAddResult(Result(Pattern, 0));
|
||||
|
||||
// @throw
|
||||
Pattern = new CodeCompletionString;
|
||||
Pattern->AddTypedTextChunk("throw");
|
||||
Pattern->AddTextChunk(" ");
|
||||
Pattern->AddPlaceholderChunk("expression");
|
||||
Pattern->AddTextChunk(";");
|
||||
Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
|
||||
|
||||
// @synchronized ( expression ) { statements }
|
||||
Pattern = new CodeCompletionString;
|
||||
Pattern->AddTypedTextChunk("synchronized");
|
||||
Pattern->AddTextChunk(" ");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Pattern->AddPlaceholderChunk("expression");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
|
||||
Pattern->AddPlaceholderChunk("statements");
|
||||
Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
|
||||
Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
|
||||
|
||||
AddObjCExpressionResults(0, Results);
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCAtExpression(Scope *S) {
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
AddObjCExpressionResults(0, Results);
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
/// \brief Determine whether the addition of the given flag to an Objective-C
|
||||
/// property's attributes will cause a conflict.
|
||||
static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
|
||||
|
||||
23
clang/test/Index/complete-at-exprstmt.m
Normal file
23
clang/test/Index/complete-at-exprstmt.m
Normal file
@@ -0,0 +1,23 @@
|
||||
/* The run lines are below, because this test is line- and
|
||||
column-number sensitive. */
|
||||
@interface MyClass { }
|
||||
- (int)myMethod:(int)arg;
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (int)myMethod:(int)arg {
|
||||
@synchronized (@encode(MyClass)) { }
|
||||
}
|
||||
@end
|
||||
// RUN: c-index-test -code-completion-at=%s:9:4 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
|
||||
// CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
|
||||
// CHECK-CC1: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )}
|
||||
// CHECK-CC1: {TypedText synchronized}{Text }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}
|
||||
// CHECK-CC1: {TypedText throw}{Text }{Placeholder expression}{Text ;}
|
||||
// CHECK-CC1: {TypedText try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }}
|
||||
// RUN: c-index-test -code-completion-at=%s:9:19 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
|
||||
// CHECK-CC2: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
|
||||
// CHECK-CC2: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )}
|
||||
|
||||
Reference in New Issue
Block a user