Skip to content

Commit

Permalink
Resolve lifetime issues related to macro dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera authored Feb 2, 2023
1 parent a49d70f commit bdbb68d
Show file tree
Hide file tree
Showing 33 changed files with 499 additions and 537 deletions.
2 changes: 1 addition & 1 deletion parser_library/include/workspace_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class PARSER_LIBRARY_EXPORT workspace_manager
virtual completion_list completion(
const char* document_uri, position pos, char trigger_char, completion_trigger_kind trigger_kind);

virtual sequence<token_info> semantic_tokens(const char* document_uri);
virtual continuous_sequence<token_info> semantic_tokens(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, const char* whole_settings);
Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ std::unique_ptr<processing::preprocessor> analyzer_options::get_preprocessor(pro
return std::make_unique<combined_preprocessor>(std::move(tmp));
}

analyzer::analyzer(const std::string& text, analyzer_options opts)
analyzer::analyzer(std::string_view text, analyzer_options opts)
: diagnosable_ctx(opts.get_hlasm_context())
, ctx_(std::move(opts.get_context()))
, src_proc_(opts.collect_hl_info == collect_highlighting_info::yes)
Expand Down
4 changes: 2 additions & 2 deletions parser_library/src/analyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <atomic>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>
Expand Down Expand Up @@ -146,7 +146,7 @@ class analyzer : public diagnosable_ctx
processing::processing_manager mngr_;

public:
analyzer(const std::string& text, analyzer_options opts = {});
analyzer(std::string_view text, analyzer_options opts = {});

analyzing_context context() const;
context::hlasm_context& hlasm_ctx();
Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/lsp/text_data_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace hlasm_plugin::parser_library::lsp {

class text_data_view
{
std::string text; // FIXME: no longer view due to lifetime issues
std::string_view text;
std::vector<size_t> line_indices;

public:
Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/processing/processing_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ processing_manager::processing_manager(std::unique_ptr<opencode_provider> base_p
analyzing_context ctx,
workspaces::library_data data,
utils::resource::resource_location file_loc,
const std::string& file_text,
std::string_view file_text,
workspaces::parse_lib_provider& lib_provider,
statement_fields_parser& parser,
std::shared_ptr<std::vector<fade_message_s>> fade_msgs)
Expand Down
3 changes: 2 additions & 1 deletion parser_library/src/processing/processing_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <memory>
#include <set>
#include <stack>
#include <string_view>
#include <vector>

#include "analyzing_context.h"
Expand All @@ -42,7 +43,7 @@ class processing_manager final : public processing_state_listener, public branch
analyzing_context ctx,
workspaces::library_data data,
utils::resource::resource_location file_loc,
const std::string& file_text,
std::string_view file_text,
workspaces::parse_lib_provider& lib_provider,
statement_fields_parser& parser,
std::shared_ptr<std::vector<fade_message_s>> fade_msgs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ constexpr std::array<std::pair<context::id_index, context::SET_t_enum>, 3> SET_i

} // namespace

lsp_analyzer::lsp_analyzer(context::hlasm_context& hlasm_ctx, lsp::lsp_context& lsp_ctx, const std::string& file_text)
lsp_analyzer::lsp_analyzer(context::hlasm_context& hlasm_ctx, lsp::lsp_context& lsp_ctx, std::string_view file_text)
: hlasm_ctx_(hlasm_ctx)
, lsp_ctx_(lsp_ctx)
, file_text_(file_text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#define PROCESSING_LSP_ANALYZER_H

#include <array>
#include <string>
#include <string_view>

#include "context/common_types.h"
#include "context/copy_member.h"
Expand Down Expand Up @@ -69,7 +69,7 @@ class lsp_analyzer : public statement_analyzer
context::hlasm_context& hlasm_ctx_;
lsp::lsp_context& lsp_ctx_;
// text of the file this analyzer is assigned to
const std::string& file_text_;
std::string_view file_text_;

bool in_macro_ = false;
size_t macro_nest_ = 1;
Expand All @@ -81,7 +81,7 @@ class lsp_analyzer : public statement_analyzer
lsp::occurence_storage stmt_occurences_;

public:
lsp_analyzer(context::hlasm_context& hlasm_ctx, lsp::lsp_context& lsp_ctx, const std::string& file_text);
lsp_analyzer(context::hlasm_context& hlasm_ctx, lsp::lsp_context& lsp_ctx, std::string_view file_text);

void analyze(const context::hlasm_statement& statement,
statement_provider_kind prov_kind,
Expand Down
4 changes: 2 additions & 2 deletions parser_library/src/workspace_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ completion_list workspace_manager::completion(
return impl_->completion(document_uri, pos, trigger_char, trigger_kind);
}

sequence<token_info> workspace_manager::semantic_tokens(const char* document_uri)
continuous_sequence<token_info> workspace_manager::semantic_tokens(const char* document_uri)
{
return sequence<token_info>(impl_->semantic_tokens(document_uri));
return impl_->semantic_tokens(document_uri);
}

document_symbol_list workspace_manager::document_symbol(const char* document_uri, long long limit)
Expand Down
105 changes: 49 additions & 56 deletions parser_library/src/workspace_manager_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class workspace_manager::impl final : public diagnosable_impl
public:
impl(std::atomic<bool>* cancel = nullptr)
: cancel_(cancel)
, file_manager_(cancel)
, implicit_workspace_(file_manager_, global_config_, m_global_settings, cancel)
, quiet_implicit_workspace_(file_manager_, supress_all, m_global_settings, cancel)
{}
Expand All @@ -51,6 +50,39 @@ class workspace_manager::impl final : public diagnosable_impl
impl(impl&&) = delete;
impl& operator=(impl&&) = delete;

static auto& ws_path_match(auto& self, std::string_view document_uri)
{
if (auto hlasm_id = extract_hlasm_id(document_uri); hlasm_id.has_value())
{
if (auto related_ws = self.file_manager_.get_virtual_file_workspace(hlasm_id.value()); !related_ws.empty())
for (auto& [_, ws] : self.workspaces_)
if (ws.uri() == related_ws.get_uri())
return ws;
}

size_t max = 0;
decltype(&self.workspaces_.begin()->second) max_ws = nullptr;
for (auto& [name, ws] : self.workspaces_)
{
size_t match = prefix_match(document_uri, ws.uri());
if (match > max && match >= name.size())
{
max = match;
max_ws = &ws;
}
}
if (max_ws != nullptr)
return *max_ws;
else if (document_uri.starts_with("file:") || document_uri.starts_with("untitled:"))
return self.implicit_workspace_;
else
return self.quiet_implicit_workspace_;
}

// returns implicit workspace, if the file does not belong to any workspace
auto& ws_path_match(std::string_view document_uri) { return ws_path_match(*this, document_uri); }
auto& ws_path_match(std::string_view document_uri) const { return ws_path_match(*this, document_uri); }

size_t get_workspaces(ws_id* workspaces, size_t max_size)
{
size_t size = 0;
Expand Down Expand Up @@ -246,19 +278,10 @@ class workspace_manager::impl final : public diagnosable_impl
notify_diagnostics_consumers();
}

std::vector<token_info> empty_tokens;
const std::vector<token_info>& semantic_tokens(const char* document_uri)
continuous_sequence<token_info> semantic_tokens(const char* document_uri)
{
if (cancel_ && *cancel_)
return empty_tokens;

utils::resource::resource_location doc(document_uri);

auto file = file_manager_.find(doc);
if (dynamic_cast<workspaces::processor_file*>(file.get()) != nullptr)
return file_manager_.find_processor_file(doc)->get_hl_info();

return empty_tokens;
return make_continuous_sequence(
ws_path_match(document_uri).semantic_tokens(utils::resource::resource_location(document_uri)));
}

continuous_sequence<char> get_virtual_file_content(unsigned long long id) const
Expand All @@ -284,8 +307,8 @@ class workspace_manager::impl final : public diagnosable_impl
private:
void collect_diags() const override
{
collect_diags_from_child(file_manager_);

collect_diags_from_child(implicit_workspace_);
collect_diags_from_child(quiet_implicit_workspace_);
for (auto& it : workspaces_)
collect_diags_from_child(it.second);
}
Expand All @@ -310,43 +333,16 @@ class workspace_manager::impl final : public diagnosable_impl
return result;
}

// returns implicit workspace, if the file does not belong to any workspace
workspaces::workspace& ws_path_match(std::string_view document_uri)
{
if (auto hlasm_id = extract_hlasm_id(document_uri); hlasm_id.has_value())
{
if (auto related_ws = file_manager_.get_virtual_file_workspace(hlasm_id.value()); !related_ws.empty())
for (auto& [_, ws] : workspaces_)
if (ws.uri() == related_ws.get_uri())
return ws;
}

size_t max = 0;
workspaces::workspace* max_ws = nullptr;
for (auto& [name, ws] : workspaces_)
{
size_t match = prefix_match(document_uri, ws.uri());
if (match > max && match >= name.size())
{
max = match;
max_ws = &ws;
}
}
if (max_ws != nullptr)
return *max_ws;
else if (document_uri.starts_with("file:") || document_uri.starts_with("untitled:"))
return implicit_workspace_;
else
return quiet_implicit_workspace_;
}

void notify_diagnostics_consumers()
{
diags().clear();
collect_diags();

fade_messages_.clear();
file_manager_.retrieve_fade_messages(fade_messages_);
implicit_workspace_.retrieve_fade_messages(fade_messages_);
quiet_implicit_workspace_.retrieve_fade_messages(fade_messages_);
for (const auto& [_, ws] : workspaces_)
ws.retrieve_fade_messages(fade_messages_);

for (auto consumer : diag_consumers_)
consumer->consume_diagnostics(diagnostic_list(diags().data(), diags().size()),
Expand All @@ -356,16 +352,13 @@ class workspace_manager::impl final : public diagnosable_impl
void notify_performance_consumers(
const utils::resource::resource_location& document_uri, workspace_file_info ws_file_info) const
{
auto file = file_manager_.find(document_uri);
auto proc_file = dynamic_cast<workspaces::processor_file*>(file.get());
if (proc_file)
{
const auto& metrics = proc_file->get_metrics();
for (auto consumer : parsing_metadata_consumers_)
{
consumer->consume_parsing_metadata({ metrics, ws_file_info });
}
}
auto proc_file = ws_path_match(document_uri.get_uri()).find_processor_file(document_uri);
if (!proc_file)
return;

parsing_metadata data { proc_file->get_metrics(), std::move(ws_file_info) };
for (auto consumer : parsing_metadata_consumers_)
consumer->consume_parsing_metadata(data);
}

static size_t prefix_match(std::string_view first, std::string_view second)
Expand Down
4 changes: 1 addition & 3 deletions parser_library/src/workspaces/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ enum class update_file_result

// Interface that represents both file opened in LSP
// as well as a file opened by parser library from the disk.
class file : public virtual diagnosable
class file
{
public:
virtual const file_location& get_location() = 0;
Expand All @@ -57,8 +57,6 @@ class file : public virtual diagnosable
virtual void did_change(range range, std::string new_text) = 0;
virtual void did_close() = 0;

virtual void retrieve_fade_messages(std::vector<fade_message_s>& fms) const = 0;

protected:
~file() = default;
};
Expand Down
6 changes: 3 additions & 3 deletions parser_library/src/workspaces/file_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ file_impl::file_impl(file_location location)
, text_()
{}

void file_impl::collect_diags() const {}

const file_location& file_impl::get_location() { return file_location_; }

const std::string& file_impl::get_text()
Expand Down Expand Up @@ -108,7 +106,9 @@ size_t find_newlines(std::string_view text, std::vector<size_t>& lines)
open_file_result file_impl::did_open(std::string new_text, version_t version)
{
bool identical = text_ == new_text;
text_ = std::move(new_text);
if (!identical)
text_ = std::move(new_text);

version_ = version;

lines_ind_.clear();
Expand Down
7 changes: 2 additions & 5 deletions parser_library/src/workspaces/file_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace hlasm_plugin::parser_library::workspaces {

// Implementation of the file interface. Implements LSP incremental changing
// of contents of file as well as loading the file from disk.
class file_impl : public virtual file, public virtual diagnosable_impl
class file_impl : public virtual file
{
public:
explicit file_impl(file_location location);
Expand All @@ -39,8 +39,6 @@ class file_impl : public virtual file, public virtual diagnosable_impl
file_impl(file_impl&&) = default;
file_impl& operator=(file_impl&&) = default;

void collect_diags() const override;

const file_location& get_location() override;
const std::string& get_text() override;
version_t get_version() override;
Expand All @@ -61,8 +59,7 @@ class file_impl : public virtual file, public virtual diagnosable_impl
virtual ~file_impl() = default;

bool is_bad() const { return bad_; }

void retrieve_fade_messages(std::vector<fade_message_s>&) const override {};
bool is_text_loaded() const { return up_to_date_; }

protected:
const std::string& get_text_ref();
Expand Down
22 changes: 4 additions & 18 deletions parser_library/src/workspaces/file_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@

namespace hlasm_plugin::parser_library::workspaces {

using file_ptr = std::shared_ptr<file>;
using processor_file_ptr = std::shared_ptr<processor_file>;
using list_directory_result =
std::pair<std::vector<std::pair<std::string, utils::resource::resource_location>>, utils::path::list_directory_rc>;
enum class open_file_result
Expand All @@ -46,27 +44,17 @@ enum class open_file_result

// Wraps an associative array of file names and files.
// Implements LSP text synchronization methods.
class file_manager : public virtual diagnosable
class file_manager
{
public:
// Adds a file with specified file name and returns it.
// If such processor file already exists, it is returned.
virtual file_ptr add_file(const file_location&) = 0;

// Adds processor file with specified file name and returns it.
// If such processor file already exists, it is returned.
// If such file already exists, it is changed into processor file.
virtual processor_file_ptr add_processor_file(const file_location&) = 0;
virtual processor_file_ptr get_processor_file(const file_location&) = 0;
virtual std::shared_ptr<file> add_file(const file_location&) = 0;

virtual void remove_file(const file_location&) = 0;

// Finds file with specified file name, return nullptr if not found.
virtual file_ptr find(const file_location& key) const = 0;
// Finds processor file with specified file name.
// If there is a file with the file name, it is changed to processor_file.
// Returns nullptr if there is no such file.
virtual processor_file_ptr find_processor_file(const file_location& key) = 0;
virtual std::shared_ptr<file> find(const file_location& key) const = 0;

// Returns list of all files in a directory. Returns associative array with pairs file name - file location.
virtual list_directory_result list_directory_files(const utils::resource::resource_location& directory) const = 0;
Expand Down Expand Up @@ -94,9 +82,7 @@ class file_manager : public virtual diagnosable

virtual open_file_result update_file(const file_location& document_loc) = 0;

virtual std::optional<std::string> get_file_content(const utils::resource::resource_location&) = 0;

virtual void retrieve_fade_messages(std::vector<fade_message_s>& fms) const = 0;
virtual std::optional<std::string> get_file_content(const utils::resource::resource_location&) const = 0;

protected:
~file_manager() = default;
Expand Down
Loading

0 comments on commit bdbb68d

Please sign in to comment.