Change std::string FuncDefDefinition::short_name to ShortName()

This commit is contained in:
Fangrui Song 2018-01-30 22:39:39 -08:00
parent 41f87887bb
commit 93269ecfd4
9 changed files with 39 additions and 27 deletions

View File

@ -317,7 +317,7 @@ bool CanBeCalledImplicitly(CXIdxEntityKind kind) {
// useful to check for implicit function calls. // useful to check for implicit function calls.
bool CursorSpellingContainsString(CXCursor cursor, bool CursorSpellingContainsString(CXCursor cursor,
CXTranslationUnit cx_tu, CXTranslationUnit cx_tu,
std::string scanning_for) { std::string_view needle) {
CXSourceRange range = clang_Cursor_getSpellingNameRange(cursor, 0, 0); CXSourceRange range = clang_Cursor_getSpellingNameRange(cursor, 0, 0);
CXToken* tokens; CXToken* tokens;
unsigned num_tokens; unsigned num_tokens;
@ -327,7 +327,7 @@ bool CursorSpellingContainsString(CXCursor cursor,
for (unsigned i = 0; i < num_tokens; ++i) { for (unsigned i = 0; i < num_tokens; ++i) {
CXString name = clang_getTokenSpelling(cx_tu, tokens[i]); CXString name = clang_getTokenSpelling(cx_tu, tokens[i]);
if (strcmp(clang_getCString(name), scanning_for.c_str()) == 0) { if (needle == clang_getCString(name)) {
result = true; result = true;
break; break;
} }
@ -1542,11 +1542,15 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// indexing the definition, then there will not be any (ie) outline // indexing the definition, then there will not be any (ie) outline
// information. // information.
if (!is_template_specialization) { if (!is_template_specialization) {
func->def.short_name = decl->entityInfo->name;
// Build detailed name. The type desc looks like void (void *). We // Build detailed name. The type desc looks like void (void *). We
// insert the qualified name before the first '('. // insert the qualified name before the first '('.
// FIXME GetFunctionSignature should set index
func->def.detailed_name = GetFunctionSignature(db, ns, decl); func->def.detailed_name = GetFunctionSignature(db, ns, decl);
auto idx = func->def.detailed_name.find(decl->entityInfo->name);
assert(idx != std::string::npos);
func->def.short_name_offset = idx;
func->def.short_name_size = strlen(decl->entityInfo->name);
// CXCursor_OverloadedDeclRef in templates are not processed by // CXCursor_OverloadedDeclRef in templates are not processed by
// OnIndexReference, thus we use TemplateVisitor to collect function // OnIndexReference, thus we use TemplateVisitor to collect function
@ -1896,6 +1900,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
IndexFuncId called_id = db->ToFuncId(HashUsr(ref->referencedEntity->USR)); IndexFuncId called_id = db->ToFuncId(HashUsr(ref->referencedEntity->USR));
IndexFunc* called = db->Resolve(called_id); IndexFunc* called = db->Resolve(called_id);
std::string_view short_name = called->def.ShortName();
// libclang doesn't provide a nice api to check if the given function // libclang doesn't provide a nice api to check if the given function
// call is implicit. ref->kind should probably work (it's either direct // call is implicit. ref->kind should probably work (it's either direct
// or implicit), but libclang only supports implicit for objective-c. // or implicit), but libclang only supports implicit for objective-c.
@ -1903,14 +1908,14 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
CanBeCalledImplicitly(ref->referencedEntity->kind) && CanBeCalledImplicitly(ref->referencedEntity->kind) &&
// Treats empty short_name as an implicit call like implicit move // Treats empty short_name as an implicit call like implicit move
// constructor in `vector<int> a = f();` // constructor in `vector<int> a = f();`
(called->def.short_name.empty() || (short_name.empty() ||
// For explicit destructor call, ref->cursor may be "~" while // For explicit destructor call, ref->cursor may be "~" while
// called->def.short_name is "~A" // called->def.short_name is "~A"
// "~A" is not a substring of ref->cursor, but we should take this // "~A" is not a substring of ref->cursor, but we should take this
// case as not `is_implicit`. // case as not `is_implicit`.
(called->def.short_name[0] != '~' && (short_name[0] != '~' &&
!CursorSpellingContainsString(ref->cursor, param->tu->cx_tu, !CursorSpellingContainsString(ref->cursor, param->tu->cx_tu,
called->def.short_name))); short_name)));
// Extents have larger ranges and thus less specific, and will be // Extents have larger ranges and thus less specific, and will be
// overriden by other functions if exist. // overriden by other functions if exist.

View File

@ -255,10 +255,7 @@ template <typename TypeId,
typename Range> typename Range>
struct FuncDefDefinitionData { struct FuncDefDefinitionData {
// General metadata. // General metadata.
std::string short_name;
std::string detailed_name; std::string detailed_name;
ClangSymbolKind kind = ClangSymbolKind::Unknown;
StorageClass storage = StorageClass::Invalid;
optional<std::string> hover; optional<std::string> hover;
optional<std::string> comments; optional<std::string> comments;
optional<Range> definition_spelling; optional<Range> definition_spelling;
@ -276,6 +273,11 @@ struct FuncDefDefinitionData {
// Functions that this function calls. // Functions that this function calls.
std::vector<FuncRef> callees; std::vector<FuncRef> callees;
int16_t short_name_offset;
int16_t short_name_size;
ClangSymbolKind kind = ClangSymbolKind::Unknown;
StorageClass storage = StorageClass::Invalid;
bool operator==( bool operator==(
const FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef, Range>& other) const FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef, Range>& other)
const { const {
@ -291,6 +293,11 @@ struct FuncDefDefinitionData {
const { const {
return !(*this == other); return !(*this == other);
} }
std::string_view ShortName() const {
return std::string_view(detailed_name.c_str() + short_name_offset,
short_name_size);
}
}; };
template <typename TVisitor, template <typename TVisitor,
@ -303,8 +310,9 @@ void Reflect(
TVisitor& visitor, TVisitor& visitor,
FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef, Range>& value) { FuncDefDefinitionData<TypeId, FuncId, VarId, FuncRef, Range>& value) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER(short_name);
REFLECT_MEMBER(detailed_name); REFLECT_MEMBER(detailed_name);
REFLECT_MEMBER(short_name_offset);
REFLECT_MEMBER(short_name_size);
REFLECT_MEMBER(kind); REFLECT_MEMBER(kind);
REFLECT_MEMBER(storage); REFLECT_MEMBER(storage);
REFLECT_MEMBER(hover); REFLECT_MEMBER(hover);

View File

@ -122,12 +122,12 @@ void EmitSemanticHighlighting(QueryDatabase* db,
continue; // applies to for loop continue; // applies to for loop
// Don't highlight overloadable operators or implicit lambda -> // Don't highlight overloadable operators or implicit lambda ->
// std::function constructor. // std::function constructor.
if (func->def->short_name.compare(0, 8, "operator") == 0 || std::string_view short_name = func->def->ShortName();
func->def->short_name.compare(0, 27, if (short_name.compare(0, 8, "operator") == 0 ||
"function<type-parameter-0-0") == 0) short_name.compare(0, 27, "function<type-parameter-0-0") == 0)
continue; // applies to for loop continue; // applies to for loop
kind = func->def->kind; kind = func->def->kind;
detailed_name = func->def->short_name; detailed_name = short_name;
break; break;
} }
case SymbolKind::Var: { case SymbolKind::Var: {

View File

@ -29,7 +29,7 @@ REGISTER_IPC_MESSAGE(Ipc_CqueryCallTreeExpand);
struct Out_CqueryCallTree : public lsOutMessage<Out_CqueryCallTree> { struct Out_CqueryCallTree : public lsOutMessage<Out_CqueryCallTree> {
enum class CallType { Direct = 0, Base = 1, Derived = 2 }; enum class CallType { Direct = 0, Base = 1, Derived = 2 };
struct CallEntry { struct CallEntry {
std::string name; std::string_view name;
std::string usr; std::string usr;
lsLocation location; lsLocation location;
bool hasCallers = true; bool hasCallers = true;
@ -61,7 +61,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(
return {}; return {};
Out_CqueryCallTree::CallEntry entry; Out_CqueryCallTree::CallEntry entry;
entry.name = root_func.def->short_name; entry.name = root_func.def->ShortName();
entry.usr = std::to_string(root_func.usr); entry.usr = std::to_string(root_func.usr);
entry.location = *def_loc; entry.location = *def_loc;
entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, root_func); entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, root_func);
@ -112,7 +112,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
return; return;
Out_CqueryCallTree::CallEntry call_entry; Out_CqueryCallTree::CallEntry call_entry;
call_entry.name = call_func.def->short_name; call_entry.name = call_func.def->ShortName();
call_entry.usr = std::to_string(call_func.usr); call_entry.usr = std::to_string(call_func.usr);
call_entry.location = *call_location; call_entry.location = *call_location;
call_entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, call_func); call_entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, call_func);

View File

@ -405,7 +405,7 @@ struct TextDocumentCodeActionHandler
// Get implementation file. // Get implementation file.
Out_TextDocumentCodeAction::Command command; Out_TextDocumentCodeAction::Command command;
command.title = "Auto-Implement " + func.def->short_name; command.title = "Auto-Implement " + std::string(func.def->ShortName());
command.command = "cquery._autoImplement"; command.command = "cquery._autoImplement";
command.arguments.textDocumentUri = *impl_uri; command.arguments.textDocumentUri = *impl_uri;
optional<lsTextEdit> edit = BuildAutoImplementForFunction( optional<lsTextEdit> edit = BuildAutoImplementForFunction(

View File

@ -57,8 +57,9 @@ optional<QueryFunc::Def> ToQuery(const IdMap& id_map,
return nullopt; return nullopt;
QueryFunc::Def result; QueryFunc::Def result;
result.short_name = func.short_name;
result.detailed_name = func.detailed_name; result.detailed_name = func.detailed_name;
result.short_name_offset = func.short_name_offset;
result.short_name_size = func.short_name_size;
result.kind = func.kind; result.kind = func.kind;
result.storage = func.storage; result.storage = func.storage;
result.hover = func.hover; result.hover = func.hover;
@ -907,7 +908,7 @@ void QueryDatabase::ImportOrUpdate(
existing.def = def.value; existing.def = def.value;
UpdateDetailedNames(&existing.detailed_name_idx, SymbolKind::Func, UpdateDetailedNames(&existing.detailed_name_idx, SymbolKind::Func,
it->second.id, def.value.short_name, it->second.id, std::string(def.value.ShortName()),
def.value.detailed_name); def.value.detailed_name);
} }
} }

View File

@ -461,7 +461,7 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
lsSymbolInformation info; lsSymbolInformation info;
info.name = info.name =
use_short_name ? func.def->short_name : func.def->detailed_name; use_short_name ? std::string(func.def->ShortName()) : func.def->detailed_name;
info.containerName = func.def->detailed_name; info.containerName = func.def->detailed_name;
info.kind = lsSymbolKind::Function; info.kind = lsSymbolKind::Function;

View File

@ -178,8 +178,9 @@ void Reflect(TVisitor& visitor, IndexFunc& value) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER2("id", value.id); REFLECT_MEMBER2("id", value.id);
REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("usr", value.usr);
REFLECT_MEMBER2("short_name", value.def.short_name);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
REFLECT_MEMBER2("short_name_offset", value.def.short_name_offset);
REFLECT_MEMBER2("short_name_size", value.def.short_name_size);
REFLECT_MEMBER2("kind", value.def.kind); REFLECT_MEMBER2("kind", value.def.kind);
REFLECT_MEMBER2("storage", value.def.storage); REFLECT_MEMBER2("storage", value.def.storage);
REFLECT_MEMBER2("hover", value.def.hover); REFLECT_MEMBER2("hover", value.def.hover);

View File

@ -182,8 +182,8 @@ void Reflect(Writer& visitor, bool& value);
void Reflect(Reader& visitor, std::string& value); void Reflect(Reader& visitor, std::string& value);
void Reflect(Writer& visitor, std::string& value); void Reflect(Writer& visitor, std::string& value);
void Reflect(Reader& visitor, std::string& view, const std::string& data); void Reflect(Reader& visitor, std::string_view& view);
void Reflect(Writer& visitor, std::string& view, const std::string& data); void Reflect(Writer& visitor, std::string_view& view);
// std::monostate is used to represent JSON null // std::monostate is used to represent JSON null
void Reflect(Reader& visitor, std::monostate&); void Reflect(Reader& visitor, std::monostate&);
@ -346,9 +346,6 @@ void ReflectMember(Writer& visitor, const char* name, T& value) {
void ReflectMember(Writer& visitor, const char* name, std::string& value); void ReflectMember(Writer& visitor, const char* name, std::string& value);
void ReflectMember(Reader& visitor, const char* name, std::string_view& view);
void ReflectMember(Writer& visitor, const char* name, std::string_view& view);
// API // API
std::string Serialize(SerializeFormat format, IndexFile& file); std::string Serialize(SerializeFormat format, IndexFile& file);