Skip to content

Commit

Permalink
feat: Diagnostics suppression for files with no pgm_conf configuration (
Browse files Browse the repository at this point in the history
  • Loading branch information
michalbali256 authored Dec 17, 2020
1 parent af48148 commit c287ff1
Show file tree
Hide file tree
Showing 37 changed files with 1,303 additions and 319 deletions.
8 changes: 8 additions & 0 deletions clients/vscode-hlasmplugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## ****Unreleased****

#### Added
- Diagnostic suppression for files that have no processor group configuration.
- Support for light and contrast themes.

#### Fixed
- Parsing issues regarding conditional assembly expressions and attribute lookahead.
- Several issues causing the extension to crash.

## [0.11.1] - 2020-11-09

#### Fixed
Expand Down
19 changes: 19 additions & 0 deletions clients/vscode-hlasmplugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,25 @@ The following example of `pgm_conf.json` specifies that the processor group `GRO
}
```

### Suppression of Diagnostics

For files, that use macros extensively, but do not have the definitions available, it is very probable that diagnostics reported by HLASM Language support will not be helpful. For those cases, there is the setting `diagnosticsSuppressLimit`, which can be set either in editor settings, or in `pgm_conf.json`. For files with no processor group configuration in `pgm_conf.json`, all the diagnostics will be suppressed, if there is too many of them (more than the configured limit).

```
{
"pgms": [
{
"program": "source_code",
"pgroup": "GROUP1"
}
],
"diagnosticsSuppressLimit" : 15
}
```
With the `pgm_conf.json` above, the `source_code` file has configuration, so all discovered diagnostics will be always shown. However, if you open another file and do not assign a processor group to it, its diagnostcs will not be shown, if there are more than 15 of them.



## Questions, issues, feature requests, and contributions
- If you have a question about how to accomplish something with the extension, or come across a problem file an issue on [GitHub](https://github.com/eclipse/che-che4z-lsp-for-hlasm)
- Contributions are always welcome! Please see our [GitHub](https://github.com/eclipse/che-che4z-lsp-for-hlasm) repository for more information.
Expand Down
5 changes: 5 additions & 0 deletions clients/vscode-hlasmplugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,11 @@
"type": "boolean",
"default": false,
"description": "Disable in case you experience lags when typing. Note: Extension will be restarted upon changing this option."
},
"hlasm.diagnosticsSuppressLimit": {
"type": "integer",
"default": 10,
"description": "This option limits number of diagnostics shown for an open code when there is no configuration in pgm_conf.json."
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions clients/vscode-hlasmplugin/pgm_conf_schema
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
"type" : "string",
"description" : "Wildcard"
}
},
"diagnosticsSuppressLimit":
{
"description":"An integer that configures the limit of diagnostics shown when there is no configuration available for the opened file.\nFor files, that use macros extensively, but do not have the definitions available, it is very probable that diagnostics reported by HLASM Language support will not be helpful. That is why we provide the option to suppress the diagnostics if there are too many of them. Set to zero to disable all diagnostics for files without configuration.",
"type": "integer",
"minimum" : 0
}
},
"required" : ["pgms"]
Expand Down
7 changes: 7 additions & 0 deletions language_server/src/dap/dap_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ server::server(parser_library::workspace_manager& ws_mngr)
register_methods();
}

void server::request(const json&, const std::string&, const json&, method)
{
// Currently, there are no supported DAP requests from client to server
/*send_message_->reply(json {
{ "seq", request_seq }, { "type", "request" }, { "command", requested_command }, { "arguments", args } });*/
}

void server::respond(const json& request_seq, const std::string& requested_command, const json& args)
{
send_message_->reply(json { { "seq", ++last_seq_ },
Expand Down
11 changes: 6 additions & 5 deletions language_server/src/dap/dap_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,19 @@ class server : public hlasm_plugin::language_server::server
public:
explicit server(parser_library::workspace_manager& ws_mngr);

// Inherited via server
virtual void respond(const json& id, const std::string& requested_method, const json& args) override;
void request(const json& id, const std::string& requested_method, const json& args, method handler) override;

virtual void notify(const std::string& method, const json& args) override;
void respond(const json& id, const std::string& requested_method, const json& args) override;

virtual void respond_error(const json& id,
void notify(const std::string& method, const json& args) override;

void respond_error(const json& id,
const std::string& requested_method,
int err_code,
const std::string& err_message,
const json& error) override;

virtual void message_received(const json& message) override;
void message_received(const json& message) override;



Expand Down
1 change: 1 addition & 0 deletions language_server/src/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace hlasm_plugin::language_server {
class response_provider
{
public:
virtual void request(const json& id, const std::string& requested_method, const json& args, method handler) = 0;
virtual void respond(const json& id, const std::string& requested_method, const json& args) = 0;
virtual void notify(const std::string& method, const json& args) = 0;
virtual void respond_error(const json& id,
Expand Down
37 changes: 35 additions & 2 deletions language_server/src/lsp/feature_workspace_folders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
#include "network/uri/uri.hpp"

#include "../logger.h"
#include "lib_config.h"


namespace hlasm_plugin::language_server::lsp {

feature_workspace_folders::feature_workspace_folders(parser_library::workspace_manager& ws_mngr)
: feature(ws_mngr)
feature_workspace_folders::feature_workspace_folders(
parser_library::workspace_manager& ws_mngr, response_provider& response_provider)
: feature(ws_mngr, response_provider)
{}

void feature_workspace_folders::register_methods(std::map<std::string, method>& methods)
Expand All @@ -36,6 +39,9 @@ void feature_workspace_folders::register_methods(std::map<std::string, method>&
methods.emplace("workspace/didChangeWatchedFiles",
std::bind(
&feature_workspace_folders::did_change_watched_files, this, std::placeholders::_1, std::placeholders::_2));
methods.emplace("workspace/didChangeConfiguration",
std::bind(
&feature_workspace_folders::did_change_configuration, this, std::placeholders::_1, std::placeholders::_2));
}

json feature_workspace_folders::register_capabilities()
Expand All @@ -46,6 +52,9 @@ json feature_workspace_folders::register_capabilities()

void feature_workspace_folders::initialize_feature(const json& initialize_params)
{
// Get config at initialization
send_configuration_request();

bool ws_folders_support = false;
auto capabs = initialize_params["capabilities"];
auto ws = capabs.find("workspace");
Expand Down Expand Up @@ -134,4 +143,28 @@ void feature_workspace_folders::did_change_watched_files(const json&, const json
paths.begin(), paths.end(), std::back_inserter(c_uris), [](const std::string& s) { return s.c_str(); });
ws_mngr_.did_change_watched_files(c_uris.data(), c_uris.size());
}

void feature_workspace_folders::send_configuration_request()
{
static const json config_request_args { { "items", { { { "section", "hlasm" } } } } };
response_->request("config_request_" + std::to_string(config_request_number_),
"workspace/configuration",
config_request_args,
std::bind(&feature_workspace_folders::configuration, this, std::placeholders::_1, std::placeholders::_2));
++config_request_number_;
}

void feature_workspace_folders::configuration(const json&, const json& params) const
{
if (params.size() == 0)
{
LOG_WARNING("Empty configuration response received.");
return;
}

ws_mngr_.configuration_changed(parser_library::lib_config::load_from_json(params[0]));
}

void feature_workspace_folders::did_change_configuration(const json&, const json&) { send_configuration_request(); }

} // namespace hlasm_plugin::language_server::lsp
13 changes: 11 additions & 2 deletions language_server/src/lsp/feature_workspace_folders.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ namespace hlasm_plugin::language_server::lsp {
class feature_workspace_folders : public feature
{
public:
explicit feature_workspace_folders(parser_library::workspace_manager& ws_mngr);
explicit feature_workspace_folders(
parser_library::workspace_manager& ws_mngr, response_provider& response_provider);

// Adds workspace/didChangeWorkspaceFolders method to the map.
// Adds workspace/* methods to the map.
void register_methods(std::map<std::string, method>&) override;
// Returns workspaces capability.
json virtual register_capabilities() override;
Expand All @@ -41,6 +42,11 @@ class feature_workspace_folders : public feature
// Handles workspace/didChangeWorkspaceFolders notification.
void on_did_change_workspace_folders(const json& id, const json& params);
void did_change_watched_files(const json&, const json& params);

void configuration(const json&, const json& params) const;
void did_change_configuration(const json&, const json& params);


// Adds all workspaces specified in the json to the workspace manager.
void add_workspaces(const json& added);

Expand All @@ -49,6 +55,9 @@ class feature_workspace_folders : public feature

// Adds one workspace to the workspace manager.
void add_workspace(const std::string& name, const std::string& uri);

uint64_t config_request_number_ = 0;
void send_configuration_request();
};

} // namespace hlasm_plugin::language_server::lsp
Expand Down
64 changes: 60 additions & 4 deletions language_server/src/lsp/lsp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,64 @@
#include "feature_language_features.h"
#include "feature_text_synchronization.h"
#include "feature_workspace_folders.h"
#include "lib_config.h"

namespace hlasm_plugin::language_server::lsp {

server::server(parser_library::workspace_manager& ws_mngr)
: language_server::server(ws_mngr)
{
features_.push_back(std::make_unique<feature_workspace_folders>(ws_mngr_));
features_.push_back(std::make_unique<feature_workspace_folders>(ws_mngr_, *this));
features_.push_back(std::make_unique<feature_text_synchronization>(ws_mngr_, *this));
features_.push_back(std::make_unique<feature_language_features>(ws_mngr_, *this));
register_feature_methods();
register_methods();

ws_mngr_.register_diagnostics_consumer(this);
ws_mngr_.set_message_consumer(this);
}

void server::message_received(const json& message)
{
// we do not support any requests sent from this server
// thus we do not accept any responses
auto id_found = message.find("id");


auto result_found = message.find("result");
auto error_result_found = message.find("error");

if (result_found != message.end())
{
// we received a response to our request that was successful
if (id_found == message.end())
{
LOG_WARNING("A response with no id field received.");
return;
}

auto handler_found = request_handlers_.find(*id_found);
if (handler_found == request_handlers_.end())
{
LOG_WARNING("A response with no registered handler received.");
return;
}

method handler = handler_found->second;
request_handlers_.erase(handler_found);
handler(id_found.value(), result_found.value());
return;
}
else if (error_result_found != message.end())
{
auto message_found = error_result_found->find("message");
std::string warn_message;
if (message_found != error_result_found->end())
warn_message = message_found->dump();
else
warn_message = "Request with id " + id_found->dump() + " returned with unspecified error.";
LOG_WARNING(warn_message);
return;
}

auto params_found = message.find("params");
auto method_found = message.find("method");

Expand Down Expand Up @@ -71,6 +109,13 @@ void server::message_received(const json& message)
}
}

void server::request(const json& id, const std::string& requested_method, const json& args, method handler)
{
json reply { { "jsonrpc", "2.0" }, { "id", id }, { "method", requested_method }, { "params", args } };
request_handlers_.emplace(id, handler);
send_message_->reply(reply);
}

void server::respond(const json& id, const std::string&, const json& args)
{
json reply { { "jsonrpc", "2.0" }, { "id", id }, { "result", args } };
Expand Down Expand Up @@ -100,6 +145,11 @@ void server::register_methods()
methods_.emplace("exit", std::bind(&server::on_exit, this, std::placeholders::_1, std::placeholders::_2));
}

void empty_handler(json, const json&)
{
// Does nothing
}

void server::on_initialize(json id, const json& param)
{
// send server capabilities back
Expand All @@ -124,6 +174,12 @@ void server::on_initialize(json id, const json& param)

respond(id, "", capabilities);

json register_configuration_changed_args {
{ { "registrations", { { { "id", "configureRegister" }, { "method", "workspace/didChangeConfiguration" } } } } }
};

request("register1", "client/registerCapability", register_configuration_changed_args, &empty_handler);


for (auto& f : features_)
{
Expand All @@ -142,7 +198,7 @@ void server::on_shutdown(json id, const json&)

void server::on_exit(json, const json&) { exit_notification_received_ = true; }

void server::show_message(const std::string& message, message_type type)
void server::show_message(const std::string& message, parser_library::message_type type)
{
json m { { "type", (int)type }, { "message", message } };
notify("window/showMessage", m);
Expand Down
16 changes: 6 additions & 10 deletions language_server/src/lsp/lsp_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,12 @@

namespace hlasm_plugin::language_server::lsp {

enum class message_type
{
MT_ERROR = 1,
MT_WARNING = 2,
MT_INFO = 3,
MT_LOG = 4
};

// Implements LSP server (session-controlling methods like initialize and shutdown).
// Integrates 3 features: language features, text synchronization and workspace folders.
// Consumes diagnostics that come from the parser library and sends them to LSP client.
class server final : public hlasm_plugin::language_server::server, public parser_library::diagnostics_consumer
class server final : public hlasm_plugin::language_server::server,
public parser_library::diagnostics_consumer,
public parser_library::message_consumer
{
public:
// Creates the server with workspace_manager as entry point to parser library.
Expand All @@ -49,6 +43,8 @@ class server final : public hlasm_plugin::language_server::server, public parser
void message_received(const json& message) override;

protected:
// Sends request to LSP client using send_message_provider.
void request(const json& id, const std::string& requested_method, const json& args, method handler) override;
// Sends respond to request to LSP client using send_message_provider.
void respond(const json& id, const std::string& requested_method, const json& args) override;
// Sends notification to LSP client using send_message_provider.
Expand Down Expand Up @@ -78,7 +74,7 @@ class server final : public hlasm_plugin::language_server::server, public parser
// client notifications

// Implements the LSP showMessage request.
void show_message(const std::string& message, message_type type);
void show_message(const std::string& message, parser_library::message_type type) override;

// Remembers name of files for which were sent diagnostics the last time
// diagnostics were sent to client. Used to clear diagnostics in client
Expand Down
1 change: 1 addition & 0 deletions language_server/src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class server : public response_provider
std::vector<std::unique_ptr<feature>> features_;

std::map<std::string, method> methods_;
std::unordered_map<json, method> request_handlers_;

bool shutdown_request_received_ = false;
bool exit_notification_received_ = false;
Expand Down
1 change: 1 addition & 0 deletions language_server/test/dap/feature_launch_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct notif_mock

struct response_provider_mock : public response_provider
{
void request(const json&, const std::string&, const json&, method) override {};
void respond(const json& id, const std::string& requested_method, const json& args) override
{
responses.push_back({ id, requested_method, args });
Expand Down
1 change: 1 addition & 0 deletions language_server/test/dispatcher_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class server_mock : public server

std::vector<json> messages;

virtual void request(const json&, const std::string&, const json&, method) override {}
virtual void respond(const json&, const std::string&, const json&) override {}
virtual void notify(const std::string&, const json&) override {}
virtual void respond_error(const json&, const std::string&, int, const std::string&, const json&) override {}
Expand Down
Loading

0 comments on commit c287ff1

Please sign in to comment.