From 72e654ffed171d2c7bd309a4abab2ecea444fc7b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 12 Feb 2018 23:20:08 -0800 Subject: [PATCH] Fix default -resource-dir when clang -print-resource-dir contains .. Also makes textDocument/definition in comments takes scope resolution into account, and use detailed names (for Func, without parameters) for workspace/symbol --- src/lex_utils.cc | 11 ++++++----- src/messages/text_document_definition.cc | 18 ++++++------------ src/messages/workspace_symbol.cc | 16 ++++++---------- src/query.cc | 8 ++++++-- src/utils.cc | 2 +- wscript | 10 +++------- 6 files changed, 28 insertions(+), 37 deletions(-) diff --git a/src/lex_utils.cc b/src/lex_utils.cc index f345016f..60a76c37 100644 --- a/src/lex_utils.cc +++ b/src/lex_utils.cc @@ -201,19 +201,20 @@ std::string LexWordAroundPos(lsPosition position, const std::string& content) { int index = GetOffsetForPosition(position, content); int start = index; - int end = index; + int end = index + 1; + // We search for : before the cursor but not after to get the qualifier. while (start > 0) { char c = content[start - 1]; - if (isalnum(c) || c == '_') { + if (isalnum(c) || c == '_' || c == ':') { --start; } else { break; } } - while ((end + 1) < content.size()) { - char c = content[end + 1]; + while (end < (int)content.size()) { + char c = content[end]; if (isalnum(c) || c == '_') { ++end; } else { @@ -221,7 +222,7 @@ std::string LexWordAroundPos(lsPosition position, const std::string& content) { } } - return content.substr(start, end - start + 1); + return content.substr(start, end - start); } bool SubsequenceMatch(std::string_view search, std::string_view content) { diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index aa000b92..678a95f3 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -131,24 +131,18 @@ struct TextDocumentDefinitionHandler // Find the best match of the identifier at point. if (!has_symbol && db->symbols.size()) { const std::string& buffer = working_file->buffer_content; - int start = GetOffsetForPosition(request->params.position, buffer); - int end = start; - while (start > 0 && isalnum(buffer[start - 1])) - start--; - while (isalnum(buffer[end])) - end++; - auto query = std::string_view(buffer).substr(start, end - start); + std::string query = LexWordAroundPos(request->params.position, buffer); int best_score = kMinScore; int best_i = 0; std::vector score, dp; for (int i = 0; i < (int)db->symbols.size(); ++i) { - std::string_view short_name = db->GetSymbolShortName(i); - if (short_name.size() > score.size()) { - score.resize(short_name.size()); - dp.resize(short_name.size()); + std::string_view detailed_name = db->GetSymbolDetailedName(i); + if (detailed_name.size() > score.size()) { + score.resize(detailed_name.size()); + dp.resize(detailed_name.size()); } - int t = FuzzyEvaluate(query, short_name, score, dp); + int t = FuzzyEvaluate(query, detailed_name, score, dp); if (t > best_score) { best_score = t; best_i = i; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 5aa41e01..a78ca994 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -79,12 +79,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { inserted_results.reserve(config->maxWorkspaceSearchResults); result_indices.reserve(config->maxWorkspaceSearchResults); - // We use detailed_names for exact matches and short_names for fuzzy matches - // because otherwise the fuzzy match is likely to match on parameter names - // and the like. - // TODO: make detailed_names not include function parameter information (or - // introduce additional metadata) so that we can do fuzzy search with - // detailed_names. + // We use detailed_names without parameters for matching. // Find exact substring matches. for (int i = 0; i < db->symbols.size(); ++i) { @@ -112,9 +107,10 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { query_without_space += c; for (int i = 0; i < db->symbols.size(); ++i) { - if (SubsequenceMatch(query_without_space, db->GetSymbolShortName(i))) { + std::string_view detailed_name = db->GetSymbolDetailedName(i); + if (SubsequenceMatch(query_without_space, detailed_name)) { // Do not show the same entry twice. - if (!inserted_results.insert(std::string(db->GetSymbolDetailedName(i))).second) + if (!inserted_results.insert(std::string(detailed_name)).second) continue; if (InsertSymbolIntoResult(db, working_files, db->symbols[i], @@ -131,7 +127,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { // Sort results with a fuzzy matching algorithm. int longest = 0; for (int i : result_indices) - longest = std::max(longest, int(db->GetSymbolShortName(i).size())); + longest = std::max(longest, int(db->GetSymbolDetailedName(i).size())); std::vector score(longest); // score for each position std::vector dp( @@ -139,7 +135,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { std::vector> permutation(result_indices.size()); for (int i = 0; i < int(result_indices.size()); i++) { permutation[i] = { - FuzzyEvaluate(query, db->GetSymbolShortName(result_indices[i]), score, dp), + FuzzyEvaluate(query, db->GetSymbolDetailedName(result_indices[i]), score, dp), i}; } std::sort(permutation.begin(), permutation.end(), diff --git a/src/query.cc b/src/query.cc index 04fe1d61..c4e0533f 100644 --- a/src/query.cc +++ b/src/query.cc @@ -916,6 +916,7 @@ void QueryDatabase::UpdateSymbols(Maybe>* symbol_idx, } } +// For Func, the returned name does not include parameters. std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const { RawId idx = symbols[symbol_idx].id.id; switch (symbols[symbol_idx].kind) { @@ -926,8 +927,11 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const { return files[idx].def->path; break; case SymbolKind::Func: - if (funcs[idx].def) - return funcs[idx].def->detailed_name; + if (funcs[idx].def) { + auto& def = funcs[idx].def; + return std::string_view(def->detailed_name) + .substr(0, def->short_name_offset + def->short_name_size); + } break; case SymbolKind::Type: if (types[idx].def) diff --git a/src/utils.cc b/src/utils.cc index 726eba11..2d53957a 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -565,7 +565,7 @@ std::string GetDefaultResourceDirectory() { resource_directory = resource_directory.substr(1, resource_directory.size() - 2); } - if (resource_directory.find("..") != std::string::npos) { + if (resource_directory.compare(0, 2, "..") == 0) { std::string executable_path = GetExecutablePath(); size_t pos = executable_path.find_last_of('/'); result = executable_path.substr(0, pos + 1); diff --git a/wscript b/wscript index 8e6fc7a1..00de509e 100644 --- a/wscript +++ b/wscript @@ -216,13 +216,9 @@ def configure(ctx): # Ask llvm-config for cflags and ldflags ctx.find_program(ctx.options.llvm_config, msg='checking for llvm-config', var='LLVM_CONFIG', mandatory=False) - if len(ctx.options.llvm_config): - ctx.env.rpath = [str(subprocess.check_output( - [ctx.options.llvm_config, '--libdir'], - stderr=subprocess.STDOUT).decode()).strip()] - else: - # If `--llvm-config=` (empty) - ctx.env.rpath = [] + ctx.env.rpath = [str(subprocess.check_output( + [ctx.options.llvm_config, '--libdir'], + stderr=subprocess.STDOUT).decode()).strip()] if ctx.options.clang_prefix: ctx.start_msg('Checking for clang prefix')