llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp
Douglas Gregor 5bf52697b0 Tweak the code-completion results ranking and formation, so that
members found in base classes have the same ranking as members found
in derived classes. However, we will introduce an informative note for
members found in base classes, showing (as a nested-name-specifier)
the qualification to name the base class, to make it clear which
members are from bases.
 

llvm-svn: 82586
2009-09-22 23:15:58 +00:00

136 lines
4.1 KiB
C++

//===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the CodeCompleteConsumer class.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Parse/Scope.h"
#include "clang/Lex/Preprocessor.h"
#include "Sema.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
#include <functional>
using namespace clang;
//===----------------------------------------------------------------------===//
// Code completion string implementation
//===----------------------------------------------------------------------===//
CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
: Kind(Kind), Text(0)
{
assert((Kind == CK_Text || Kind == CK_Placeholder || Kind == CK_Informative)
&& "Invalid text chunk kind");
char *New = new char [std::strlen(Text) + 1];
std::strcpy(New, Text);
this->Text = New;
}
CodeCompletionString::Chunk
CodeCompletionString::Chunk::CreateText(const char *Text) {
return Chunk(CK_Text, Text);
}
CodeCompletionString::Chunk
CodeCompletionString::Chunk::CreateOptional(
std::auto_ptr<CodeCompletionString> Optional) {
Chunk Result;
Result.Kind = CK_Optional;
Result.Optional = Optional.release();
return Result;
}
CodeCompletionString::Chunk
CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
return Chunk(CK_Placeholder, Placeholder);
}
CodeCompletionString::Chunk
CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
return Chunk(CK_Informative, Informative);
}
void
CodeCompletionString::Chunk::Destroy() {
switch (Kind) {
case CK_Optional:
delete Optional;
break;
case CK_Text:
case CK_Placeholder:
case CK_Informative:
delete [] Text;
break;
}
}
CodeCompletionString::~CodeCompletionString() {
std::for_each(Chunks.begin(), Chunks.end(),
std::mem_fun_ref(&Chunk::Destroy));
}
std::string CodeCompletionString::getAsString() const {
std::string Result;
llvm::raw_string_ostream OS(Result);
for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
switch (C->Kind) {
case CK_Text: OS << C->Text; break;
case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
case CK_Informative: OS << "[#" << C->Text << "#]"; break;
}
}
return Result;
}
//===----------------------------------------------------------------------===//
// Code completion consumer implementation
//===----------------------------------------------------------------------===//
CodeCompleteConsumer::~CodeCompleteConsumer() { }
void
PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Result *Results,
unsigned NumResults) {
// Print the results.
for (unsigned I = 0; I != NumResults; ++I) {
switch (Results[I].Kind) {
case Result::RK_Declaration:
OS << Results[I].Declaration->getNameAsString() << " : "
<< Results[I].Rank;
if (Results[I].Hidden)
OS << " (Hidden)";
if (CodeCompletionString *CCS
= Results[I].CreateCodeCompletionString(SemaRef)) {
OS << " : " << CCS->getAsString();
delete CCS;
}
OS << '\n';
break;
case Result::RK_Keyword:
OS << Results[I].Keyword << " : " << Results[I].Rank << '\n';
break;
}
}
// Once we've printed the code-completion results, suppress remaining
// diagnostics.
// FIXME: Move this somewhere else!
SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
}