[cfe-commits] r89277 - in /cfe/trunk: include/clang/Sema/CodeCompleteConsumer.h lib/Sema/CodeCompleteConsumer.cpp lib/Sema/SemaCodeComplete.cpp test/CodeCompletion/property.m test/Index/complete-property-flags.m
Douglas Gregor
dgregor at apple.com
Wed Nov 18 16:01:58 PST 2009
Author: dgregor
Date: Wed Nov 18 18:01:57 2009
New Revision: 89277
URL: http://llvm.org/viewvc/llvm-project?rev=89277&view=rev
Log:
Improve code-completion results for the flags in an @property
declaration by providing patterns for "getter = <method>" and "setter
= <method>". As part of this, invented a new "pattern" result kind
that is merely a semantic string. The "pattern" result kind should
help with other kinds of code templates.
Added:
cfe/trunk/test/Index/complete-property-flags.m
- copied, changed from r89264, cfe/trunk/test/CodeCompletion/property.m
Removed:
cfe/trunk/test/CodeCompletion/property.m
Modified:
cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=89277&r1=89276&r2=89277&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Wed Nov 18 18:01:57 2009
@@ -123,6 +123,9 @@
/// \brief Create a new current-parameter chunk.
static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
+ /// \brief Clone the given chunk.
+ Chunk Clone() const;
+
/// \brief Destroy this chunk, deallocating any memory it owns.
void Destroy();
};
@@ -192,15 +195,21 @@
/// \brief Add a new chunk.
void AddChunk(Chunk C) { Chunks.push_back(C); }
+ /// \brief Returns the text in the TypedText chunk.
+ const char *getTypedText() const;
+
/// \brief Retrieve a string representation of the code completion string,
/// which is mainly useful for debugging.
std::string getAsString() const;
+ /// \brief Clone this code-completion string.
+ CodeCompletionString *Clone() const;
+
/// \brief Serialize this code-completion string to the given stream.
void Serialize(llvm::raw_ostream &OS) const;
/// \brief Deserialize a code-completion string from the given string.
- static CodeCompletionString *Deserialize(llvm::StringRef &Str);
+ static CodeCompletionString *Deserialize(llvm::StringRef &Str);
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@@ -220,7 +229,8 @@
enum ResultKind {
RK_Declaration = 0, //< Refers to a declaration
RK_Keyword, //< Refers to a keyword or symbol.
- RK_Macro //< Refers to a macro
+ RK_Macro, //< Refers to a macro
+ RK_Pattern //< Refers to a precomputed pattern.
};
/// \brief The kind of result stored here.
@@ -235,6 +245,10 @@
/// or symbol's spelling.
const char *Keyword;
+ /// \brief When Kind == RK_Pattern, the code-completion string that
+ /// describes the completion text to insert.
+ CodeCompletionString *Pattern;
+
/// \brief When Kind == RK_Macro, the identifier that refers to a macro.
IdentifierInfo *Macro;
};
@@ -277,6 +291,12 @@
: Kind(RK_Macro), Macro(Macro), Rank(Rank), Hidden(false),
QualifierIsInformative(0), StartsNestedNameSpecifier(false),
Qualifier(0) { }
+
+ /// \brief Build a result that refers to a pattern.
+ Result(CodeCompletionString *Pattern, unsigned Rank)
+ : Kind(RK_Pattern), Pattern(Pattern), Rank(Rank), Hidden(false),
+ QualifierIsInformative(0), StartsNestedNameSpecifier(false),
+ Qualifier(0) { }
/// \brief Retrieve the declaration stored in this result.
NamedDecl *getDeclaration() const {
@@ -293,6 +313,8 @@
/// \brief Create a new code-completion string that describes how to insert
/// this result into a program.
CodeCompletionString *CreateCodeCompletionString(Sema &S);
+
+ void Destroy();
};
class OverloadCandidate {
Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=89277&r1=89276&r2=89277&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Wed Nov 18 18:01:57 2009
@@ -117,6 +117,33 @@
return Chunk(CK_CurrentParameter, CurrentParameter);
}
+CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
+ switch (Kind) {
+ case CK_TypedText:
+ case CK_Text:
+ case CK_Placeholder:
+ case CK_Informative:
+ case CK_CurrentParameter:
+ case CK_LeftParen:
+ case CK_RightParen:
+ case CK_LeftBracket:
+ case CK_RightBracket:
+ case CK_LeftBrace:
+ case CK_RightBrace:
+ case CK_LeftAngle:
+ case CK_RightAngle:
+ case CK_Comma:
+ return Chunk(Kind, Text);
+
+ case CK_Optional: {
+ std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
+ return CreateOptional(Opt);
+ }
+ }
+
+ // Silence GCC warning.
+ return Chunk();
+}
void
CodeCompletionString::Chunk::Destroy() {
@@ -168,6 +195,20 @@
return Result;
}
+const char *CodeCompletionString::getTypedText() const {
+ for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+ if (C->Kind == CK_TypedText)
+ return C->Text;
+
+ return 0;
+}
+
+CodeCompletionString *CodeCompletionString::Clone() const {
+ CodeCompletionString *Result = new CodeCompletionString;
+ for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+ Result->AddChunk(C->Clone());
+ return Result;
+}
namespace {
// Escape a string for XML-like formatting.
@@ -473,6 +514,13 @@
return Result;
}
+void CodeCompleteConsumer::Result::Destroy() {
+ if (Kind == RK_Pattern) {
+ delete Pattern;
+ Pattern = 0;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Code completion overload candidate implementation
//===----------------------------------------------------------------------===//
@@ -545,6 +593,12 @@
OS << '\n';
break;
}
+
+ case Result::RK_Pattern: {
+ OS << "Pattern : " << Results[I].Rank << " : "
+ << Results[I].Pattern->getAsString() << '\n';
+ break;
+ }
}
}
@@ -627,6 +681,13 @@
OS << '\n';
break;
}
+
+ case Result::RK_Pattern: {
+ OS << "Pattern:";
+ Results[I].Pattern->Serialize(OS);
+ OS << '\n';
+ break;
+ }
}
}
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=89277&r1=89276&r2=89277&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Nov 18 18:01:57 2009
@@ -1066,6 +1066,17 @@
else if (X.Rank > Y.Rank)
return false;
+ // We use a special ordering for keywords and patterns, based on the
+ // typed text.
+ if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
+ (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
+ const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
+ : X.Pattern->getTypedText();
+ const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
+ : Y.Pattern->getTypedText();
+ return strcmp(XStr, YStr) < 0;
+ }
+
// Result kinds are ordered by decreasing importance.
if (X.Kind < Y.Kind)
return true;
@@ -1087,12 +1098,14 @@
return isEarlierDeclarationName(X.Declaration->getDeclName(),
Y.Declaration->getDeclName());
- case Result::RK_Keyword:
- return strcmp(X.Keyword, Y.Keyword) < 0;
-
case Result::RK_Macro:
return llvm::LowercaseString(X.Macro->getName()) <
llvm::LowercaseString(Y.Macro->getName());
+
+ case Result::RK_Keyword:
+ case Result::RK_Pattern:
+ llvm::llvm_unreachable("Result kinds handled above");
+ break;
}
// Silence GCC warning.
@@ -1120,6 +1133,9 @@
if (CodeCompleter)
CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+
+ for (unsigned I = 0; I != NumResults; ++I)
+ Results[I].Destroy();
}
void Sema::CodeCompleteOrdinaryName(Scope *S) {
@@ -1635,10 +1651,20 @@
Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
if (!(Attributes & ObjCDeclSpec::DQ_PR_nonatomic))
Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_setter))
- Results.MaybeAddResult(CodeCompleteConsumer::Result("setter", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_getter))
- Results.MaybeAddResult(CodeCompleteConsumer::Result("getter", 0));
+ if (!(Attributes & ObjCDeclSpec::DQ_PR_setter)) {
+ CodeCompletionString *Setter = new CodeCompletionString;
+ Setter->AddTypedTextChunk("setter");
+ Setter->AddTextChunk(" = ");
+ Setter->AddPlaceholderChunk("method");
+ Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
+ }
+ if (!(Attributes & ObjCDeclSpec::DQ_PR_getter)) {
+ CodeCompletionString *Getter = new CodeCompletionString;
+ Getter->AddTypedTextChunk("getter");
+ Getter->AddTextChunk(" = ");
+ Getter->AddPlaceholderChunk("method");
+ Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
+ }
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
}
Removed: cfe/trunk/test/CodeCompletion/property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/property.m?rev=89276&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/property.m (original)
+++ cfe/trunk/test/CodeCompletion/property.m (removed)
@@ -1,29 +0,0 @@
-// Note: the run lines follow their respective tests, since line/column
-// matter in this test.
-
- at interface Foo {
- void *isa;
-}
- at property(copy) Foo *myprop;
- at property(retain, nonatomic) id xx;
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:7:11 %s -o - | FileCheck -check-prefix=CC1 %s
-// CC1: assign
-// CC1-NEXT: copy
-// CC1-NEXT: getter
-// CC1-NEXT: nonatomic
-// CC1-NEXT: readonly
-// CC1-NEXT: readwrite
-// CC1-NEXT: retain
-// CC1-NEXT: setter
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:8:18 %s -o - | FileCheck -check-prefix=CC2 %s
-// CC2: assign
-// CC2-NEXT: copy
-// CC2-NEXT: getter
-// CC2-NEXT: nonatomic
-// CC2-NEXT: readonly
-// CC2-NEXT: readwrite
-// CC2-NEXT: setter
- at end
-
-
-
Copied: cfe/trunk/test/Index/complete-property-flags.m (from r89264, cfe/trunk/test/CodeCompletion/property.m)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-property-flags.m?p2=cfe/trunk/test/Index/complete-property-flags.m&p1=cfe/trunk/test/CodeCompletion/property.m&r1=89264&r2=89277&rev=89277&view=diff
==============================================================================
--- cfe/trunk/test/CodeCompletion/property.m (original)
+++ cfe/trunk/test/Index/complete-property-flags.m Wed Nov 18 18:01:57 2009
@@ -6,23 +6,23 @@
}
@property(copy) Foo *myprop;
@property(retain, nonatomic) id xx;
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:7:11 %s -o - | FileCheck -check-prefix=CC1 %s
-// CC1: assign
-// CC1-NEXT: copy
-// CC1-NEXT: getter
-// CC1-NEXT: nonatomic
-// CC1-NEXT: readonly
-// CC1-NEXT: readwrite
-// CC1-NEXT: retain
-// CC1-NEXT: setter
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:8:18 %s -o - | FileCheck -check-prefix=CC2 %s
-// CC2: assign
-// CC2-NEXT: copy
-// CC2-NEXT: getter
-// CC2-NEXT: nonatomic
-// CC2-NEXT: readonly
-// CC2-NEXT: readwrite
-// CC2-NEXT: setter
+// RUN: c-index-test -code-completion-at=%s:7:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText assign}
+// CHECK-CC1-NEXT: {TypedText copy}
+// CHECK-CC1-NEXT: {TypedText getter}{Text = }{Placeholder method}
+// CHECK-CC1-NEXT: {TypedText nonatomic}
+// CHECK-CC1-NEXT: {TypedText readonly}
+// CHECK-CC1-NEXT: {TypedText readwrite}
+// CHECK-CC1-NEXT: {TypedText retain}
+// CHECK-CC1-NEXT: {TypedText setter}{Text = }{Placeholder method}
+// RUN: c-index-test -code-completion-at=%s:8:18 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText assign}
+// CHECK-CC2-NEXT: {TypedText copy}
+// CHECK-CC2-NEXT: {TypedText getter}{Text = }{Placeholder method}
+// CHECK-CC2-NEXT: {TypedText nonatomic}
+// CHECK-CC2-NEXT: {TypedText readonly}
+// CHECK-CC2-NEXT: {TypedText readwrite}
+// CHECK-CC2-NEXT: {TypedText setter}{Text = }{Placeholder method}
@end
More information about the cfe-commits
mailing list