From aadb755fd7a8dfa47ec1de0e618d150a223517c8 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 5 Jan 2022 15:43:50 +0100 Subject: [PATCH] Join separated documentation for some interpreter C++ API types The docs were living in the public header file while the enums/structs were defined in Rust. With the infrastructure of the parent commits we can join them together. --- api/sixtyfps-cpp/cbindgen.rs | 47 +++++++++++- .../include/sixtyfps_interpreter.h | 76 +------------------ sixtyfps_runtime/interpreter/api.rs | 2 - sixtyfps_runtime/interpreter/ffi.rs | 35 ++++++--- 4 files changed, 72 insertions(+), 88 deletions(-) diff --git a/api/sixtyfps-cpp/cbindgen.rs b/api/sixtyfps-cpp/cbindgen.rs index ac7e8469d..767e31fce 100644 --- a/api/sixtyfps-cpp/cbindgen.rs +++ b/api/sixtyfps-cpp/cbindgen.rs @@ -471,17 +471,60 @@ fn gen_interpreter( ) -> anyhow::Result<()> { let mut config = default_config(); // Avoid Value, just export ValueOpaque. - config.export.exclude.push("Value".into()); + config.export.exclude = std::array::IntoIter::new([ + "Value", + "ValueType", + "PropertyDescriptor", + "Diagnostic", + "PropertyDescriptor", + ]) + .map(String::from) + .collect(); let mut crate_dir = root_dir.to_owned(); crate_dir.extend(["sixtyfps_runtime", "interpreter"].iter()); ensure_cargo_rerun_for_crate(&crate_dir, dependencies)?; + // Generate a header file with some public API (enums, etc.) + let mut public_config = config.clone(); + public_config.namespaces = Some(vec!["sixtyfps".into(), "interpreter".into()]); + public_config.export.item_types = vec![cbindgen::ItemType::Enums, cbindgen::ItemType::Structs]; + + public_config.export.exclude = std::array::IntoIter::new([ + "ComponentCompilerOpaque", + "ComponentDefinitionOpaque", + "ModelAdaptorVTable", + "StructIteratorOpaque", + "ComponentInstance", + "StructIteratorResult", + "ValueOpaque", + "StructOpaque", + "ModelNotifyOpaque", + ]) + .map(String::from) + .collect(); + + cbindgen::Builder::new() + .with_config(public_config) + .with_crate(crate_dir.clone()) + .generate() + .context("Unable to generate bindings for sixtyfps_interpreter_generated_public.h")? + .write_to_file(include_dir.join("sixtyfps_interpreter_generated_public.h")); + cbindgen::Builder::new() .with_config(config) .with_crate(crate_dir) .with_include("sixtyfps_internal.h") - .with_after_include("namespace sixtyfps::cbindgen_private { struct Value; }") + .with_include("sixtyfps_interpreter_generated_public.h") + .with_after_include( + r" + namespace sixtyfps::cbindgen_private { + struct Value; + using sixtyfps::interpreter::ValueType; + using sixtyfps::interpreter::PropertyDescriptor; + using sixtyfps::interpreter::Diagnostic; + }", + ) .generate() .context("Unable to generate bindings for sixtyfps_interpreter_internal.h")? .write_to_file(include_dir.join("sixtyfps_interpreter_internal.h")); diff --git a/api/sixtyfps-cpp/include/sixtyfps_interpreter.h b/api/sixtyfps-cpp/include/sixtyfps_interpreter.h index 09c8a5494..f3fa7ed3d 100644 --- a/api/sixtyfps-cpp/include/sixtyfps_interpreter.h +++ b/api/sixtyfps-cpp/include/sixtyfps_interpreter.h @@ -285,36 +285,8 @@ public: /// Destroys the value. ~Value() { cbindgen_private::sixtyfps_interpreter_value_destructor(&inner); } -#if !defined(DOXYGEN) - using Type = cbindgen_private::ValueType; -#else - /// This enum describes the different types the Value class can represent. - enum Type { - /// The variant that expresses the non-type. This is the default. - Void, - /// An `int` or a `float` (this is also used for unit based type such as `length` or - /// `angle`) - Number, - /// Correspond to the `string` type in .60 - String, - /// Correspond to the `bool` type in .60 - Bool, - /// An Array in the .60 language. - Array, - /// A more complex model which is not created by the interpreter itself (Type::Array can - /// also be used for models) - Model, - /// An object - Struct, - /// Correspond to `brush` or `color` type in .60. For color, this is then a - /// sixtyfps::Brush with just a color. - Brush, - /// Correspond to `image` type in .60. - Image, - /// The type is not a public type but something internal. - Other = -1, - }; -#endif // else !defined(DOXYGEN) + /// A convenience alias for the value type enum. + using Type = ValueType; // optional to_int() const; // optional to_float() const; @@ -788,21 +760,6 @@ public: } }; -#if !defined(DOXYGEN) -using PropertyDescriptor = sixtyfps::cbindgen_private::PropertyDescriptor; -#else -/// PropertyDescriptor is a simple structure that's used to describe a property declared in .60 -/// code. It is returned from in a vector from -/// sixtyfps::interpreter::ComponentDefinition::properties(). -struct PropertyDescriptor -{ - /// The name of the declared property. - SharedString property_name; - /// The type of the property. - Value::Type property_type; -}; -#endif // else !defined(DOXYGEN) - /// ComponentDefinition is a representation of a compiled component from .60 markup. /// /// It can be constructed from a .60 file using the ComponentCompiler::build_from_path() or @@ -920,35 +877,6 @@ public: } }; -#if !defined(DOXYGEN) -using DiagnosticLevel = sixtyfps::cbindgen_private::CDiagnosticLevel; -using Diagnostic = sixtyfps::cbindgen_private::CDiagnostic; -#else -/// DiagnosticLevel describes the severity of a diagnostic. -enum DiagnosticLevel { - /// The diagnostic belongs to an error. - Error, - /// The diagnostic belongs to a warning. - Warning, -}; -/// Diagnostic describes the aspects of either a warning or an error, along -/// with its location and a description. Diagnostics are typically returned by -/// sixtyfps::interpreter::ComponentCompiler::diagnostics() in a vector. -struct Diagnostic -{ - /// The message describing the warning or error. - SharedString message; - /// The path to the source file where the warning or error is located. - SharedString source_file; - /// The line within the source file. Line numbers start at 1. - uintptr_t line; - /// The column within the source file. Column numbers start at 1. - uintptr_t column; - /// The level of the diagnostic, such as a warning or an error. - DiagnosticLevel level; -}; -#endif // else !defined(DOXYGEN) - /// ComponentCompiler is the entry point to the SixtyFPS interpreter that can be used /// to load .60 files or compile them on-the-fly from a string /// (using build_from_source()) or from a path (using build_from_source()) diff --git a/sixtyfps_runtime/interpreter/api.rs b/sixtyfps_runtime/interpreter/api.rs index 8d2568526..6a1b0b18d 100644 --- a/sixtyfps_runtime/interpreter/api.rs +++ b/sixtyfps_runtime/interpreter/api.rs @@ -18,8 +18,6 @@ pub use sixtyfps_corelib::window::api::Window; /// This enum represents the different public variants of the [`Value`] enum, without /// the contained values. -// NOTE: The docs for ValueType are duplicated in sixtyfps_interpreter.h, for extraction by -// Doxygen. Keep in sync! #[derive(Debug, Copy, Clone, PartialEq)] #[repr(i8)] pub enum ValueType { diff --git a/sixtyfps_runtime/interpreter/ffi.rs b/sixtyfps_runtime/interpreter/ffi.rs index 94cd44d23..50d31af52 100644 --- a/sixtyfps_runtime/interpreter/ffi.rs +++ b/sixtyfps_runtime/interpreter/ffi.rs @@ -655,23 +655,32 @@ pub unsafe extern "C" fn sixtyfps_interpreter_model_notify_row_removed( } // FIXME: Figure out how to re-export the one from compilerlib -// Note: Documented in sixtyfps.h - keep in sync! +/// DiagnosticLevel describes the severity of a diagnostic. #[derive(Clone)] #[repr(C)] -pub enum CDiagnosticLevel { +pub enum DiagnosticLevel { + /// The diagnostic belongs to an error. Error, + /// The diagnostic belongs to a warning. Warning, } -// Note: Documented in sixtyfps.h - keep in sync! +/// Diagnostic describes the aspects of either a warning or an error, along +/// with its location and a description. Diagnostics are typically returned by +/// sixtyfps::interpreter::ComponentCompiler::diagnostics() in a vector. #[derive(Clone)] #[repr(C)] -pub struct CDiagnostic { +pub struct Diagnostic { + /// The message describing the warning or error. message: SharedString, + /// The path to the source file where the warning or error is located. source_file: SharedString, + /// The line within the source file. Line numbers start at 1. line: usize, + /// The column within the source file. Column numbers start at 1. column: usize, - level: CDiagnosticLevel, + /// The level of the diagnostic, such as a warning or an error. + level: DiagnosticLevel, } #[repr(C)] @@ -751,11 +760,11 @@ pub unsafe extern "C" fn sixtyfps_interpreter_component_compiler_get_include_pat #[no_mangle] pub unsafe extern "C" fn sixtyfps_interpreter_component_compiler_get_diagnostics( compiler: &ComponentCompilerOpaque, - out_diags: &mut SharedVector, + out_diags: &mut SharedVector, ) { out_diags.extend(compiler.as_component_compiler().diagnostics.iter().map(|diagnostic| { let (line, column) = diagnostic.line_column(); - CDiagnostic { + Diagnostic { message: diagnostic.message().into(), source_file: diagnostic .source_file() @@ -764,8 +773,10 @@ pub unsafe extern "C" fn sixtyfps_interpreter_component_compiler_get_diagnostics line, column, level: match diagnostic.level() { - DiagnosticLevel::Error => CDiagnosticLevel::Error, - DiagnosticLevel::Warning => CDiagnosticLevel::Warning, + sixtyfps_compilerlib::diagnostics::DiagnosticLevel::Error => DiagnosticLevel::Error, + sixtyfps_compilerlib::diagnostics::DiagnosticLevel::Warning => { + DiagnosticLevel::Warning + } }, } })); @@ -810,11 +821,15 @@ pub unsafe extern "C" fn sixtyfps_interpreter_component_compiler_build_from_path } } -// NOTE: The C++ documentation for this exists in sixtyfps_interpreter.h. Keep in sync! +/// PropertyDescriptor is a simple structure that's used to describe a property declared in .60 +/// code. It is returned from in a vector from +/// sixtyfps::interpreter::ComponentDefinition::properties(). #[derive(Clone)] #[repr(C)] pub struct PropertyDescriptor { + /// The name of the declared property. property_name: SharedString, + /// The type of the property. property_type: ValueType, }