Skip to content
This repository has been archived by the owner on Jul 30, 2020. It is now read-only.

Add Just My Code support for global symbol search #823

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,19 @@ struct Config {
};
Index index;

// List of folders opened in current workspace.
std::vector<std::string> workspaceFolders;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably shouldn't be in config, can you store it as a variable in the base message handler class?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm..
Don't know how to achieve this. Okay, let me put forth my understanding of LSP.

  • There are only two ways to receive config options from clients.
    1. Through initialization options - stored in struct Config.
    2. Through --init command line option - can be stored in strut MessageHandler or in one of its fields.
  • Clients don't (can't) send extra options through queries.

Please, correct me if I'm wrong regarding these assumptions.

Coming to the change you suggested, did you mean struct MessageHandler or struct BaseMessageHandler.
In either case please elaborate on how to achieve this. Thanks.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In MessageHandler, ie, where db, project and the like are defined (src/message_handler.h line 85ish). You can declare a std::unique_ptr<std::vector<std::string>> workspaceFolders there and append to it inside of init, ie, so that every derived MessageHandler type will use the same std::vector instance.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you don't feel like doing that, a TODO is good enough.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, for clarification. I've made the changes you suggested. Check if that is what you intended.
Please feel free to suggest further changes.


struct WorkspaceSymbol {
// Maximum workspace search results.
int maxNum = 1000;
// If true, workspace search results will be dynamically rescored/reordered
// as the search progresses. Some clients do their own ordering and assume
// that the results stay sorted in the same order as the search progresses.
bool sort = true;
// If Just My Code is enabled, workspace search results will only contain
// symbols from workspace folders.
bool justMyCode = true;
};
WorkspaceSymbol workspaceSymbol;

Expand Down Expand Up @@ -278,7 +284,7 @@ MAKE_REFLECT_STRUCT(Config::Index,
enabled,
logSkippedPaths,
threads);
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, maxNum, sort);
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, maxNum, sort, justMyCode);
MAKE_REFLECT_STRUCT(Config::Xref, maxNum);
MAKE_REFLECT_STRUCT(Config,
compilationDatabaseCommand,
Expand All @@ -302,6 +308,7 @@ MAKE_REFLECT_STRUCT(Config,
diagnostics,
highlight,
index,
workspaceFolders,
workspaceSymbol,
xref,

Expand Down
1 change: 1 addition & 0 deletions src/message_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct MessageHandler {
CodeCompleteCache* global_code_complete_cache = nullptr;
CodeCompleteCache* non_global_code_complete_cache = nullptr;
CodeCompleteCache* signature_cache = nullptr;
std::unique_ptr<std::vector<std::string>> workspaceFolders;

virtual MethodType GetMethodType() const = 0;
virtual void Run(std::unique_ptr<InMessage> message) = 0;
Expand Down
44 changes: 44 additions & 0 deletions src/messages/initialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,50 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
g_config->cacheDirectory = *cacheDir;
EnsureEndsInSlash(g_config->cacheDirectory);
}

// Should Just My Code be enabled?
if (g_config->workspaceSymbol.justMyCode) {
if (g_config->workspaceFolders.empty()) {
g_config->workspaceSymbol.justMyCode = false;
} else {
std::vector<std::string> workspaceFolders;

for (const auto& folder : g_config->workspaceFolders) {
const auto folderPath = NormalizePath(folder);

// Bogus workspaceFolder received. Disable Just My Code.
if (!folderPath) {
g_config->workspaceSymbol.justMyCode = false;
break;
}

workspaceFolders.emplace_back(std::move(folderPath.value()));
}

for (MessageHandler* handler : *MessageHandler::message_handlers) {
handler->workspaceFolders =
std::make_unique<std::vector<std::string>>(workspaceFolders);
}
}

if (!g_config->workspaceSymbol.justMyCode) {
std::string workspaceFoldersString = "";

for (const auto& folder : g_config->workspaceFolders) {
workspaceFoldersString += folder + ", ";
}

LOG_S(WARNING) << "[querydb] Cannot enable Just My Code with "
"invalid workspaceFolders settings ("
<< workspaceFoldersString
<< "). Disabling Just My Code";
} else {
LOG_S(INFO) << "Just My Code Enabled";
}
} else {
g_config->workspaceSymbol.justMyCode = false;
LOG_S(INFO) << "Just My Code Disabled";
}
}

// Should snippets be enabled?
Expand Down
31 changes: 25 additions & 6 deletions src/messages/workspace_symbol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,23 @@
namespace {
MethodType kMethodType = "workspace/symbol";

// Returns true iff symbol source file is from one of the workspace folders
static bool SymbolInWorkspace(std::vector<std::string>* workspaceFolders,
std::string_view symbolSourceFilePath) {
for (const auto& workspaceFolder : *workspaceFolders) {
if (symbolSourceFilePath.find(workspaceFolder) != std::string::npos) {
return true;
}
}

return false;
}

// Lookup |symbol| in |db| and insert the value into |result|.
bool InsertSymbolIntoResult(QueryDatabase* db,
WorkingFiles* working_files,
SymbolIdx symbol,
std::vector<std::string>* workspaceFolders,
std::vector<lsSymbolInformation>* result) {
optional<lsSymbolInformation> info =
GetSymbolInfo(db, working_files, symbol, false /*use_short_name*/);
Expand All @@ -36,11 +49,16 @@ bool InsertSymbolIntoResult(QueryDatabase* db,
}

optional<lsLocation> ls_location = GetLsLocation(db, working_files, loc);
if (!ls_location)
return false;
info->location = *ls_location;
result->push_back(*info);
return true;

if (ls_location &&
(!g_config->workspaceSymbol.justMyCode ||
SymbolInWorkspace(workspaceFolders, ls_location->uri.raw_uri_))) {
info->location = *ls_location;
result->push_back(*info);
return true;
}

return false;
}

struct In_WorkspaceSymbol : public RequestInMessage {
Expand Down Expand Up @@ -91,7 +109,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler<In_WorkspaceSymbol> {
continue;

if (InsertSymbolIntoResult(db, working_files, db->symbols[i],
&unsorted_results)) {
workspaceFolders.get(), &unsorted_results)) {
result_indices.push_back(i);
if (unsorted_results.size() >= g_config->workspaceSymbol.maxNum)
break;
Expand All @@ -116,6 +134,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler<In_WorkspaceSymbol> {
continue;

if (InsertSymbolIntoResult(db, working_files, db->symbols[i],
workspaceFolders.get(),
&unsorted_results)) {
result_indices.push_back(i);
if (unsorted_results.size() >= g_config->workspaceSymbol.maxNum)
Expand Down