Skip to content

Commit

Permalink
Introduce a limit to outline tree size (#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera authored Oct 19, 2021
1 parent 03d62ad commit 5724f79
Show file tree
Hide file tree
Showing 19 changed files with 503 additions and 371 deletions.
3 changes: 2 additions & 1 deletion language_server/src/lsp/feature_language_features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,8 @@ void feature_language_features::document_symbol(const json& id, const json& para
{
auto document_uri = params["textDocument"]["uri"].get<std::string>();

auto symbol_list = ws_mngr_.document_symbol(uri_to_path(document_uri).c_str());
const auto limit = 5000LL;
auto symbol_list = ws_mngr_.document_symbol(uri_to_path(document_uri).c_str(), limit);

response_->respond(id, "", document_symbol_list_json(symbol_list));
}
Expand Down
2 changes: 1 addition & 1 deletion parser_library/include/workspace_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class PARSER_LIBRARY_EXPORT workspace_manager
const char* document_uri, position pos, char trigger_char, completion_trigger_kind trigger_kind);

virtual const std::vector<token_info>& semantic_tokens(const char* document_uri);
virtual document_symbol_list document_symbol(const char* document_uri);
virtual document_symbol_list document_symbol(const char* document_uri, long long limit);

virtual void configuration_changed(const lib_config& new_config);

Expand Down
52 changes: 7 additions & 45 deletions parser_library/src/lsp/document_symbol_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include "document_symbol_item.h"

#include "utils/similar.h"

namespace hlasm_plugin::parser_library::lsp {

document_symbol_item_s::document_symbol_item_s(std::string name, document_symbol_kind kind, range symbol_range)
Expand All @@ -31,55 +33,15 @@ document_symbol_item_s::document_symbol_item_s(
, children(children)
{}

bool is_permutation_with_permutations(const document_symbol_list_s& lhs, const document_symbol_list_s& rhs)
{
if (lhs.size() != rhs.size())
{
return false;
}
for (auto& item : lhs)
{
auto i = std::find(rhs.begin(), rhs.end(), item);
if (i == rhs.end())
{
return false;
}
if (!is_permutation_with_permutations(item.children, i->children))
{
return false;
}
}
return true;
}

document_symbol_list_s::iterator document_symbol_no_children_find(
document_symbol_list_s::iterator begin, document_symbol_list_s::iterator end, const document_symbol_item_s& item)
{
while (begin != end)
{
if (item.name == begin->name && item.kind == begin->kind && item.symbol_range == begin->symbol_range
&& item.symbol_selection_range == begin->symbol_selection_range)
{
return begin;
}
begin++;
}
return end;
}

bool operator==(const document_symbol_item_s& lhs, const document_symbol_item_s& rhs)
bool is_similar(const document_symbol_list_s& l, const document_symbol_list_s& r)
{
return lhs.name == rhs.name && lhs.kind == rhs.kind && lhs.symbol_range == rhs.symbol_range
&& lhs.symbol_selection_range == rhs.symbol_selection_range
&& is_permutation_with_permutations(lhs.children, rhs.children);
return l.size() == r.size() && std::is_permutation(l.begin(), l.end(), r.begin(), utils::is_similar);
}

void operator+=(document_symbol_list_s& lhs, const document_symbol_list_s& rhs)
bool is_similar(const document_symbol_item_s& l, const document_symbol_item_s& r)
{
for (const auto& item : rhs)
{
lhs.push_back(item);
}
return l.name == r.name && l.kind == r.kind && l.symbol_range == r.symbol_range
&& l.symbol_selection_range == r.symbol_selection_range && is_similar(l.children, r.children);
}

} // namespace hlasm_plugin::parser_library::lsp
8 changes: 2 additions & 6 deletions parser_library/src/lsp/document_symbol_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,8 @@ struct document_symbol_item_s

std::vector<range> scope;
};

bool operator==(const document_symbol_item_s& lhs, const document_symbol_item_s& rhs);
bool is_permutation_with_permutations(const document_symbol_list_s& lhs, const document_symbol_list_s& rhs);
document_symbol_list_s::iterator document_symbol_no_children_find(
document_symbol_list_s::iterator begin, document_symbol_list_s::iterator end, const document_symbol_item_s& item);
void operator+=(document_symbol_list_s& lhs, const document_symbol_list_s& rhs);
bool is_similar(const document_symbol_list_s& l, const document_symbol_list_s& r);
bool is_similar(const document_symbol_item_s& l, const document_symbol_item_s& r);

} // namespace hlasm_plugin::parser_library::lsp

Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/lsp/feature_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct feature_provider
position pos,
char trigger_char,
completion_trigger_kind trigger_kind) const = 0;
virtual document_symbol_list_s document_symbol(const std::string& document_uri) const = 0;
virtual document_symbol_list_s document_symbol(const std::string& document_uri, long long limit) const = 0;

protected:
~feature_provider() = default;
Expand Down
27 changes: 24 additions & 3 deletions parser_library/src/lsp/file_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,20 @@ occurence_scope_t file_info::find_occurence_with_scope(position pos) const
{
const symbol_occurence* found = nullptr;

auto l = std::lower_bound(occurences.begin(), occurences.end(), pos, [](const auto& occ, const auto& p) {
return occ.occurence_range.end.line < p.line;
});
auto it_limit = occurences_start_limit.begin() + std::distance(occurences.begin(), l);
// find in occurences
for (const auto& occ : occurences)
for (auto it = l; it != occurences.end() && *it_limit <= pos.line; ++it, ++it_limit)
{
const auto& occ = *it;
if (is_in_range(pos, occ.occurence_range))
{
found = &occ;
break;
}
}

// if not found, return
if (!found)
Expand Down Expand Up @@ -93,8 +100,7 @@ std::vector<position> file_info::find_references(

void file_info::update_occurences(const occurence_storage& occurences_upd)
{
for (const auto& occ : occurences_upd)
occurences.emplace_back(occ);
occurences.insert(occurences.end(), occurences_upd.begin(), occurences_upd.end());
}

void file_info::update_slices(const std::vector<file_slice_t>& slices_upd)
Expand Down Expand Up @@ -145,4 +151,19 @@ std::vector<file_slice_t> file_slice_t::transform_slices(

const std::vector<symbol_occurence>& file_info::get_occurences() const { return occurences; }

void file_info::process_occurrences()
{
std::sort(occurences.begin(), occurences.end(), [](const auto& l, const auto& r) {
return std::tie(l.occurence_range.end.line, l.occurence_range.start.line)
< std::tie(r.occurence_range.end.line, r.occurence_range.start.line);
});

occurences_start_limit.resize(occurences.size());

std::transform(occurences.rbegin(),
occurences.rend(),
occurences_start_limit.rbegin(),
[min = (size_t)-1](const auto& occ) mutable { return min = std::min(min, occ.occurence_range.start.line); });
}

} // namespace hlasm_plugin::parser_library::lsp
2 changes: 2 additions & 0 deletions parser_library/src/lsp/file_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ class file_info
void update_occurences(const occurence_storage& occurences_upd);
void update_slices(const std::vector<file_slice_t>& slices);
const std::vector<symbol_occurence>& get_occurences() const;
void process_occurrences();

private:
std::map<line_range, file_slice_t> slices;
std::vector<symbol_occurence> occurences;
std::vector<size_t> occurences_start_limit;
};

} // namespace hlasm_plugin::parser_library::lsp
Expand Down
Loading

0 comments on commit 5724f79

Please sign in to comment.