diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/CodeCompleteConsumer.cpp | 61 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 40 |
2 files changed, 94 insertions, 7 deletions
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 88ac4e49cf9..a9d83010576 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -117,6 +117,33 @@ CodeCompletionString::Chunk::CreateCurrentParameter( 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 @@ std::string CodeCompletionString::getAsString() const { 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 @@ CodeCompletionString *CodeCompletionString::Deserialize(llvm::StringRef &Str) { return Result; } +void CodeCompleteConsumer::Result::Destroy() { + if (Kind == RK_Pattern) { + delete Pattern; + Pattern = 0; + } +} + //===----------------------------------------------------------------------===// // Code completion overload candidate implementation //===----------------------------------------------------------------------===// @@ -545,6 +593,12 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, OS << '\n'; break; } + + case Result::RK_Pattern: { + OS << "Pattern : " << Results[I].Rank << " : " + << Results[I].Pattern->getAsString() << '\n'; + break; + } } } @@ -627,6 +681,13 @@ CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, OS << '\n'; break; } + + case Result::RK_Pattern: { + OS << "Pattern:"; + Results[I].Pattern->Serialize(OS); + OS << '\n'; + break; + } } } diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 22d2884ede1..f3f7d3f4055 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1066,6 +1066,17 @@ namespace { 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 @@ namespace { 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 @@ static void HandleCodeCompleteResults(Sema *S, 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 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { 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()); } |