[cfe-commits] r114379 - in /cfe/trunk: lib/Sema/SemaCodeComplete.cpp test/Index/complete-type-factors.m
Douglas Gregor
dgregor at apple.com
Mon Sep 20 17:03:25 PDT 2010
Author: dgregor
Date: Mon Sep 20 19:03:25 2010
New Revision: 114379
URL: http://llvm.org/viewvc/llvm-project?rev=114379&view=rev
Log:
When providing code completions for an argument in an Objective-C
message send, e.g.,
[[NSString alloc] initWithCString:<CC>
look up all of the possible methods and determine the preferred type
for the argument expression based on the type of the corresponding
parameter.
Modified:
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/test/Index/complete-type-factors.m
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=114379&r1=114378&r2=114379&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Mon Sep 20 19:03:25 2010
@@ -216,6 +216,10 @@
AllowNestedNameSpecifiers = Allow;
}
+ /// \brief Return the semantic analysis object for which we are collecting
+ /// code completion results.
+ Sema &getSema() const { return SemaRef; }
+
/// \brief Determine whether the given declaration is at all interesting
/// as a code-completion result.
///
@@ -4362,6 +4366,40 @@
/*IsSuper=*/true);
}
+/// \brief Given a set of code-completion results for the argument of a message
+/// send, determine the preferred type (if any) for that argument expression.
+static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
+ unsigned NumSelIdents) {
+ typedef CodeCompletionResult Result;
+ ASTContext &Context = Results.getSema().Context;
+
+ QualType PreferredType;
+ unsigned BestPriority = CCP_Unlikely * 2;
+ Result *ResultsData = Results.data();
+ for (unsigned I = 0, N = Results.size(); I != N; ++I) {
+ Result &R = ResultsData[I];
+ if (R.Kind == Result::RK_Declaration &&
+ isa<ObjCMethodDecl>(R.Declaration)) {
+ if (R.Priority <= BestPriority) {
+ ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
+ if (NumSelIdents <= Method->param_size()) {
+ QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
+ ->getType();
+ if (R.Priority < BestPriority || PreferredType.isNull()) {
+ BestPriority = R.Priority;
+ PreferredType = MyPreferredType;
+ } else if (!Context.hasSameUnqualifiedType(PreferredType,
+ MyPreferredType)) {
+ PreferredType = QualType();
+ }
+ }
+ }
+ }
+ }
+
+ return PreferredType;
+}
+
static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
ParsedType Receiver,
IdentifierInfo **SelIdents,
@@ -4446,12 +4484,25 @@
unsigned NumSelIdents,
bool AtArgumentExpression,
bool IsSuper) {
- if (AtArgumentExpression)
- return CodeCompleteOrdinaryName(S, PCC_Expression);
-
ResultBuilder Results(*this);
AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
AtArgumentExpression, IsSuper, Results);
+
+ // If we're actually at the argument expression (rather than prior to the
+ // selector), we're actually performing code completion for an expression.
+ // Determine whether we have a single, best method. If so, we can
+ // code-complete the expression using the corresponding parameter type as
+ // our preferred type, improving completion results.
+ if (AtArgumentExpression) {
+ QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
+ NumSelIdents);
+ if (PreferredType.isNull())
+ CodeCompleteOrdinaryName(S, PCC_Expression);
+ else
+ CodeCompleteExpression(S, PreferredType);
+ return;
+ }
+
HandleCodeCompleteResults(this, CodeCompleter,
CodeCompletionContext::CCC_Other,
Results.data(), Results.size());
@@ -4462,9 +4513,6 @@
unsigned NumSelIdents,
bool AtArgumentExpression,
bool IsSuper) {
- if (AtArgumentExpression)
- return CodeCompleteOrdinaryName(S, PCC_Expression);
-
typedef CodeCompletionResult Result;
Expr *RecExpr = static_cast<Expr *>(Receiver);
@@ -4577,8 +4625,24 @@
}
}
}
-
Results.ExitScope();
+
+
+ // If we're actually at the argument expression (rather than prior to the
+ // selector), we're actually performing code completion for an expression.
+ // Determine whether we have a single, best method. If so, we can
+ // code-complete the expression using the corresponding parameter type as
+ // our preferred type, improving completion results.
+ if (AtArgumentExpression) {
+ QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
+ NumSelIdents);
+ if (PreferredType.isNull())
+ CodeCompleteOrdinaryName(S, PCC_Expression);
+ else
+ CodeCompleteExpression(S, PreferredType);
+ return;
+ }
+
HandleCodeCompleteResults(this, CodeCompleter,
CodeCompletionContext::CCC_Other,
Results.data(),Results.size());
Modified: cfe/trunk/test/Index/complete-type-factors.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-type-factors.m?rev=114379&r1=114378&r2=114379&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-type-factors.m (original)
+++ cfe/trunk/test/Index/complete-type-factors.m Mon Sep 20 19:03:25 2010
@@ -22,9 +22,15 @@
c = color;
}
-// FIXME: It would be great for message sends to have the same
-// benefits as function calls, but we don't quite have the
-// infrastructure yet.
+ at interface A
++ (void)method:(enum Color)color priority:(enum Priority)priority;
+- (void)method:(enum Color)color priority:(enum Priority)priority;
+ at end
+
+void test2(A *a) {
+ [a method:Red priority:High];
+ [A method:Red priority:Low];
+}
// RUN: c-index-test -code-completion-at=%s:16:11 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (32)
@@ -105,3 +111,27 @@
// CHECK-CC6: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (16)
// CHECK-CC6: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
// CHECK-CC6: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (50)
+// RUN: c-index-test -code-completion-at=%s:31:13 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC7 %s
+// RUN: c-index-test -code-completion-at=%s:32:13 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC7 %s
+// CHECK-CC7: ParmDecl:{ResultType A *}{TypedText a} (8)
+// CHECK-CC7: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (16)
+// CHECK-CC7: FunctionDecl:{ResultType int}{TypedText func1}{LeftParen (}{Placeholder enum Color}{RightParen )} (25)
+// CHECK-CC7: FunctionDecl:{ResultType enum Priority}{TypedText func2}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC7: FunctionDecl:{ResultType void}{TypedText func3}{LeftParen (}{Placeholder float}{RightParen )} (50)
+// CHECK-CC7: EnumConstantDecl:{ResultType enum Color}{TypedText Green} (16)
+// CHECK-CC7: EnumConstantDecl:{ResultType enum Priority}{TypedText High} (65)
+// CHECK-CC7: EnumConstantDecl:{ResultType enum Priority}{TypedText Low} (65)
+// CHECK-CC7: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (16)
+// CHECK-CC7: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (50)
+// RUN: c-index-test -code-completion-at=%s:31:26 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC8 %s
+// RUN: c-index-test -code-completion-at=%s:32:26 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC8 %s
+// CHECK-CC8: ParmDecl:{ResultType A *}{TypedText a} (8)
+// CHECK-CC8: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (65)
+// CHECK-CC8: FunctionDecl:{ResultType int}{TypedText func1}{LeftParen (}{Placeholder enum Color}{RightParen )} (25)
+// CHECK-CC8: FunctionDecl:{ResultType enum Priority}{TypedText func2}{LeftParen (}{Placeholder int}{RightParen )} (12)
+// CHECK-CC8: FunctionDecl:{ResultType void}{TypedText func3}{LeftParen (}{Placeholder float}{RightParen )} (50)
+// CHECK-CC8: EnumConstantDecl:{ResultType enum Color}{TypedText Green} (65)
+// CHECK-CC8: EnumConstantDecl:{ResultType enum Priority}{TypedText High} (16)
+// CHECK-CC8: EnumConstantDecl:{ResultType enum Priority}{TypedText Low} (16)
+// CHECK-CC8: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (65)
+// CHECK-CC8: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (12)
More information about the cfe-commits
mailing list