Add a diagnostics getter to ComponentCompiler

This commit is contained in:
Simon Hausmann 2021-03-19 18:34:30 +01:00
parent 5b726cacbe
commit e1f9347aaa
4 changed files with 71 additions and 0 deletions

View file

@ -473,6 +473,9 @@ public:
}
};
using Diagnostic = sixtyfps::cbindgen_private::CDiagnostic;
using DiagnosticLevel = sixtyfps::cbindgen_private::CDiagnosticLevel;
class ComponentCompiler
{
cbindgen_private::ComponentCompilerOpaque inner;
@ -513,6 +516,13 @@ public:
return paths;
}
sixtyfps::SharedVector<Diagnostic> diagnostics() const
{
sixtyfps::SharedVector<Diagnostic> result;
cbindgen_private::sixtyfps_interpreter_component_compiler_get_diagnostics(&inner, &result);
return result;
}
std::optional<ComponentDefinition> build_from_source(std::string_view source_code,
std::string_view path)
{

View file

@ -88,6 +88,22 @@ struct SharedString
/// \return true if the string contains no characters; false otherwise.
bool empty() const { return std::string_view(*this).empty(); }
/// \return true if the string starts with the specified prefix string; false otherwise
bool starts_with(std::string_view prefix) const
{
return std::string_view(*this).substr(0, prefix.size()) == prefix;
}
/// \return true if the string ends with the specified prefix string; false otherwise
bool ends_with(std::string_view prefix) const
{
std::string_view self_view(*this);
return self_view.size() >= prefix.size()
&& self_view.compare(self_view.size() - prefix.size(), std::string_view::npos,
prefix)
== 0;
}
/// Creates a new SharedString from the given number \a n. The string representation of the
/// number uses a minimal formatting scheme: If \a n has no fractional part, the number will be
/// formatted as an integer.

View file

@ -282,6 +282,10 @@ SCENARIO("Component Compiler")
{
auto result = compiler.build_from_path(SOURCE_DIR "/file-not-there.60");
REQUIRE_FALSE(result.has_value());
auto diags = compiler.diagnostics();
REQUIRE(diags.size() == 1);
REQUIRE(diags[0].message.starts_with("Could not load"));
}
SECTION("Compile from path")

View file

@ -1295,6 +1295,24 @@ pub(crate) mod ffi {
notify.as_model_notify().row_removed(row, count);
}
// FIXME: Figure out how to re-export the one from compilerlib
#[derive(Clone)]
#[repr(C)]
pub enum CDiagnosticLevel {
Error,
Warning,
}
#[derive(Clone)]
#[repr(C)]
pub struct CDiagnostic {
message: SharedString,
source_file: SharedString,
line: usize,
column: usize,
level: CDiagnosticLevel,
}
#[repr(C)]
pub struct ComponentCompilerOpaque([usize; 12]);
/// Asserts that ComponentCompilerOpaque is as large as ComponentCompiler and has the same alignment, to make transmute safe.
@ -1373,6 +1391,29 @@ pub(crate) mod ffi {
);
}
#[no_mangle]
pub unsafe extern "C" fn sixtyfps_interpreter_component_compiler_get_diagnostics(
compiler: &ComponentCompilerOpaque,
out_diags: &mut SharedVector<CDiagnostic>,
) {
out_diags.extend(compiler.as_component_compiler().diagnostics.iter().map(|diagnostic| {
let (line, column) = diagnostic.line_column();
CDiagnostic {
message: diagnostic.message().into(),
source_file: diagnostic
.source_file()
.and_then(|path| path.to_str())
.map_or_else(|| Default::default(), |str| str.into()),
line,
column,
level: match diagnostic.level() {
DiagnosticLevel::Error => CDiagnosticLevel::Error,
DiagnosticLevel::Warning => CDiagnosticLevel::Warning,
},
}
}));
}
#[no_mangle]
pub unsafe extern "C" fn sixtyfps_interpreter_component_compiler_build_from_source(
compiler: &mut ComponentCompilerOpaque,