Skip to content

Commit

Permalink
[script] fix: diagnostics need to be on the script..
Browse files Browse the repository at this point in the history
not the context.. oops
  • Loading branch information
jd28 committed Nov 20, 2023
1 parent 71cd1a0 commit bbfe84d
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 41 deletions.
6 changes: 3 additions & 3 deletions docs/fake/rollnw/script/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,6 @@ class LspContext:
def __init__(self, command_script: str = "nwscript"):
pass

def diagnostics(self) -> List[Diagnostic]:
return []


class Nss:
"""Implementation of nwscript"""
Expand All @@ -147,6 +144,9 @@ def ast(self):
"""Gets the parsed script"""
pass

def diagnostics(self) -> List[Diagnostic]:
return []

def errors(self):
"""Gets number of errors encountered while parsing"""
pass
Expand Down
24 changes: 24 additions & 0 deletions lib/nw/script/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ bool Context::is_type_convertible(size_t lhs, size_t rhs)
void Context::lexical_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc)
{
if (script) {
Diagnostic result;
result.type = DiagnosticType::lexical;
result.level = is_warning ? DiagnosticLevel::warning : DiagnosticLevel::error;
result.script = script ? script->name() : "<source>";
result.message = std::string(msg);
result.location = loc;
script->add_diagnostic(std::move(result));

if (is_warning) {
script->increment_warnings();
} else {
Expand All @@ -196,6 +204,14 @@ void Context::lexical_diagnostic(Nss* script, std::string_view msg, bool is_warn
void Context::parse_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc)
{
if (script) {
Diagnostic result;
result.type = DiagnosticType::parse;
result.level = is_warning ? DiagnosticLevel::warning : DiagnosticLevel::error;
result.script = script ? script->name() : "<source>";
result.message = std::string(msg);
result.location = loc;
script->add_diagnostic(std::move(result));

if (is_warning) {
script->increment_warnings();
} else {
Expand All @@ -216,6 +232,14 @@ void Context::parse_diagnostic(Nss* script, std::string_view msg, bool is_warnin
void Context::semantic_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc)
{
if (script) {
Diagnostic result;
result.type = DiagnosticType::semantic;
result.level = is_warning ? DiagnosticLevel::warning : DiagnosticLevel::error;
result.script = script ? script->name() : "<source>";
result.message = std::string(msg);
result.location = loc;
script->add_diagnostic(std::move(result));

if (is_warning) {
script->increment_warnings();
} else {
Expand Down
28 changes: 28 additions & 0 deletions lib/nw/script/Diagnostic.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include "Token.hpp"

#include <string>

namespace nw::script {

enum struct DiagnosticType {
lexical,
parse,
semantic,
};

enum struct DiagnosticLevel {
warning,
error,
};

struct Diagnostic {
DiagnosticType type;
DiagnosticLevel level;
std::string script;
std::string message;
SourceLocation location;
};

} // namespace nw::script
37 changes: 29 additions & 8 deletions lib/nw/script/LspContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,70 @@

#include "Nss.hpp"

#include "../log.hpp"

namespace nw::script {

LspContext::LspContext(std::string command_script)
: Context(std::move(command_script))
{
}

const std::vector<Diagnostic>& LspContext::diagnostics() const
{
return diagnostics_;
}

void LspContext::lexical_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc)
{
CHECK_F(!!script, "");

Diagnostic result;
result.type = DiagnosticType::lexical;
result.level = is_warning ? DiagnosticLevel::warning : DiagnosticLevel::error;
result.script = script ? script->name() : "<source>";
result.message = std::string(msg);
result.location = loc;
diagnostics_.push_back(std::move(result));
script->add_diagnostic(std::move(result));

if (is_warning) {
script->increment_warnings();
} else {
script->increment_errors();
}
}

void LspContext::parse_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc)
{
CHECK_F(!!script, "");

Diagnostic result;
result.type = DiagnosticType::parse;
result.level = is_warning ? DiagnosticLevel::warning : DiagnosticLevel::error;
result.script = script ? script->name() : "<source>";
result.message = std::string(msg);
result.location = loc;
diagnostics_.push_back(std::move(result));
script->add_diagnostic(std::move(result));

if (is_warning) {
script->increment_warnings();
} else {
script->increment_errors();
}
}

void LspContext::semantic_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc)
{
CHECK_F(!!script, "");

Diagnostic result;
result.type = DiagnosticType::semantic;
result.level = is_warning ? DiagnosticLevel::warning : DiagnosticLevel::error;
result.script = script ? script->name() : "<source>";
result.message = std::string(msg);
result.location = loc;
diagnostics_.push_back(std::move(result));
script->add_diagnostic(std::move(result));

if (is_warning) {
script->increment_warnings();
} else {
script->increment_errors();
}
}

} // namespace nw::script
23 changes: 0 additions & 23 deletions lib/nw/script/LspContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,10 @@

namespace nw::script {

enum struct DiagnosticType {
lexical,
parse,
semantic,
};

enum struct DiagnosticLevel {
warning,
error,
};

struct Diagnostic {
DiagnosticType type;
DiagnosticLevel level;
std::string script;
std::string message;
SourceLocation location;
};

struct LspContext : public Context {
LspContext(std::string command_script = "nwscript");
virtual ~LspContext() = default;

std::vector<Diagnostic> diagnostics_;

const std::vector<Diagnostic>& diagnostics() const;

virtual void lexical_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc) override;
virtual void parse_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc) override;
virtual void semantic_diagnostic(Nss* script, std::string_view msg, bool is_warning, SourceLocation loc) override;
Expand Down
10 changes: 10 additions & 0 deletions lib/nw/script/Nss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ Nss::Nss(ResourceData data, Context* ctx)
CHECK_F(!!ctx_, "[script] invalid script context");
}

void Nss::add_diagnostic(Diagnostic diagnostic)
{
diagnostics_.push_back(std::move(diagnostic));
}

std::vector<std::string> Nss::complete(const std::string& needle)
{
std::vector<std::string> result;
Expand All @@ -59,6 +64,11 @@ std::set<std::string> Nss::dependencies() const
return result;
}

const std::vector<Diagnostic>& Nss::diagnostics() const noexcept
{
return diagnostics_;
}

Declaration* Nss::locate_export(const std::string& name, bool is_type)
{
auto sym = symbol_table_.find(name);
Expand Down
8 changes: 8 additions & 0 deletions lib/nw/script/Nss.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "../resources/ResourceData.hpp"
#include "Context.hpp"
#include "Diagnostic.hpp"

#include <absl/container/flat_hash_map.h>
#include <immer/map.hpp>
Expand All @@ -28,6 +29,9 @@ struct Nss {
explicit Nss(std::string_view script, Context* ctx);
explicit Nss(ResourceData data, Context* ctx);

/// Add diagnostic to script
void add_diagnostic(Diagnostic diagnostic);

/// Generates a list of potential completions from exports
/// @note This is just a baby step.
std::vector<std::string> complete(const std::string& needle);
Expand All @@ -38,6 +42,9 @@ struct Nss {
/// Returns all transitive dependencies
std::set<std::string> dependencies() const;

/// Gets script diagnostics
const std::vector<Diagnostic>& diagnostics() const noexcept;

/// Returns how many errors were found during parsing
size_t errors() const noexcept { return errors_; }

Expand Down Expand Up @@ -89,6 +96,7 @@ struct Nss {
NssParser parser_;
Ast ast_;
immer::map<std::string, Export> symbol_table_;
std::vector<Diagnostic> diagnostics_;
size_t errors_ = 0;
size_t warnings_ = 0;
bool resolved_ = false;
Expand Down
4 changes: 2 additions & 2 deletions rollnw-py/wrapper_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ void init_script(py::module& nw)

py::class_<nws::LspContext, nws::Context>(nw, "LspContext")
.def(py::init<>())
.def(py::init<std::string>())
.def("diagnostics", &nws::LspContext::diagnostics);
.def(py::init<std::string>());

py::enum_<nws::NssTokenType>(nw, "NssTokenType")
.value("INVALID", nws::NssTokenType::INVALID)
Expand Down Expand Up @@ -164,6 +163,7 @@ void init_script(py::module& nw)
},
py::return_value_policy::reference_internal)
.def("dependencies", &nws::Nss::dependencies)
.def("diagnostics", &nws::Nss::diagnostics)
.def("errors", &nws::Nss::errors)
.def("locate_export", &nws::Nss::locate_export, py::return_value_policy::reference_internal)
.def("parse", &nws::Nss::parse)
Expand Down
2 changes: 1 addition & 1 deletion rollnw-stubs/script.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class Diagnostic:

class LspContext(Context):
def __init__(self, command_script: str = "nwscript") -> None: ...
def diagnostics(self) -> List[Diagnostic]: ...


class AssignExpression(Expression):
Expand Down Expand Up @@ -215,6 +214,7 @@ class Nss:
def __init__(self, filename: Path, ctx: Context) -> None: ...
def ast(self) -> Ast: ...
def dependencies(self) -> Set[str]: ...
def diagnostics(self) -> List[Diagnostic]: ...
def errors(self) -> int: ...
def parse(self, *args, **kwargs) -> None: ...
def process_includes(self, parent: Nss) -> Any: ...
Expand Down
6 changes: 3 additions & 3 deletions tests/script_nss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,7 @@ TEST(Nss, LspContext)

EXPECT_NO_THROW(nss3.parse());
EXPECT_NO_THROW(nss3.resolve());
EXPECT_EQ(ctx->diagnostics().size(), 1);
EXPECT_EQ(ctx->diagnostics()[0].type, nw::script::DiagnosticType::semantic);
EXPECT_EQ(ctx->diagnostics()[0].level, nw::script::DiagnosticLevel::error);
EXPECT_EQ(nss3.diagnostics().size(), 1);
EXPECT_EQ(nss3.diagnostics()[0].type, nw::script::DiagnosticType::semantic);
EXPECT_EQ(nss3.diagnostics()[0].level, nw::script::DiagnosticLevel::error);
}
2 changes: 1 addition & 1 deletion tests/test_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_function_decl2():
except:
pass
nss.resolve()
assert len(ctx.diagnostics()) == 1
assert len(nss.diagnostics()) == 1


def test_var_decl():
Expand Down

0 comments on commit bbfe84d

Please sign in to comment.