Fix named exports in native code (#3602)

This commit is contained in:
J-P Nurmi 2023-10-05 16:41:10 +02:00 committed by GitHub
parent a982bdebe2
commit 8dd51f76f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 13 deletions

View file

@ -777,6 +777,8 @@ pub fn generate(doc: &Document) -> impl std::fmt::Display {
generate_public_component(&mut file, &conditional_includes, &llr);
generate_type_aliases(&mut file, doc);
file.after_includes = format!(
"static_assert({x} == SLINT_VERSION_MAJOR && {y} == SLINT_VERSION_MINOR && {z} == SLINT_VERSION_PATCH, \
\"This file was generated with Slint compiler version {x}.{y}.{z}, but the Slint library used is \" \
@ -3250,3 +3252,31 @@ fn return_compile_expression(
}
}
}
fn generate_type_aliases(file: &mut File, doc: &Document) {
let type_aliases = doc
.exports
.iter()
.filter_map(|export| match &export.1 {
Either::Left(component) if !component.is_global() => {
Some((&export.0.name, &component.id))
}
Either::Right(ty) => match &ty {
Type::Struct { name: Some(name), node: Some(_), .. } => {
Some((&export.0.name, name))
}
Type::Enumeration(en) => Some((&export.0.name, &en.name)),
_ => None,
},
_ => None,
})
.filter(|(export_name, type_name)| export_name != type_name)
.map(|(export_name, type_name)| {
Declaration::TypeAlias(TypeAlias {
old_name: ident(&type_name),
new_name: ident(&export_name),
})
});
file.declarations.extend(type_aliases);
}

View file

@ -186,6 +186,7 @@ pub fn generate(doc: &Document) -> TokenStream {
});
let resource_symbols = generate_resources(doc);
let named_exports = generate_named_exports(doc);
quote! {
#[allow(non_snake_case)]
@ -210,7 +211,7 @@ pub fn generate(doc: &Document) -> TokenStream {
#(#resource_symbols)*
const _THE_SAME_VERSION_MUST_BE_USED_FOR_THE_COMPILER_AND_THE_RUNTIME : slint::#version_check = slint::#version_check;
}
pub use #compo_module::{#compo_id #(,#structs_and_enums_ids)* #(,#globals_ids)* };
pub use #compo_module::{#compo_id #(,#structs_and_enums_ids)* #(,#globals_ids)* #(,#named_exports)*};
pub use slint::{ComponentHandle as _, Global as _, ModelExt as _};
}
}
@ -2715,3 +2716,28 @@ fn generate_resources(doc: &Document) -> Vec<TokenStream> {
})
.collect()
}
fn generate_named_exports(doc: &Document) -> Vec<TokenStream> {
doc.exports
.iter()
.filter_map(|export| match &export.1 {
Either::Left(component) if !component.is_global() => {
Some((&export.0.name, &component.id))
}
Either::Right(ty) => match &ty {
Type::Struct { name: Some(name), node: Some(_), .. } => {
Some((&export.0.name, name))
}
Type::Enumeration(en) => Some((&export.0.name, &en.name)),
_ => None,
},
_ => None,
})
.filter(|(export_name, type_name)| export_name != type_name)
.map(|(export_name, type_name)| {
let type_id = ident(&type_name);
let export_id = ident(&export_name);
quote!(#type_id as #export_id)
})
.collect::<Vec<_>>()
}

View file

@ -13,9 +13,9 @@ use std::rc::Rc;
pub fn collect_structs_and_enums(doc: &Document) {
let mut hash = BTreeMap::new();
for (name, exp) in doc.exports.iter() {
for (_, exp) in doc.exports.iter() {
if let Some(ty) = exp.as_ref().right() {
hash.insert(String::clone(name), ty.clone());
maybe_collect_object(ty, &mut hash);
}
}
@ -35,25 +35,25 @@ pub fn collect_structs_and_enums(doc: &Document) {
}
}
fn collect_types_in_component(root_component: &Rc<Component>, hash: &mut BTreeMap<String, Type>) {
let mut maybe_collect_object = |ty: &Type| {
visit_declared_type(ty, &mut |name, sub_ty| {
hash.entry(name.clone()).or_insert_with(|| sub_ty.clone());
});
};
fn maybe_collect_object(ty: &Type, hash: &mut BTreeMap<String, Type>) {
visit_declared_type(ty, &mut |name, sub_ty| {
hash.entry(name.clone()).or_insert_with(|| sub_ty.clone());
});
}
fn collect_types_in_component(root_component: &Rc<Component>, hash: &mut BTreeMap<String, Type>) {
recurse_elem_including_sub_components_no_borrow(root_component, &(), &mut |elem, _| {
for x in elem.borrow().property_declarations.values() {
maybe_collect_object(&x.property_type);
maybe_collect_object(&x.property_type, hash);
}
});
visit_all_expressions(root_component, |expr, _| {
expr.visit_recursive(&mut |expr| match expr {
Expression::Struct { ty, .. } => maybe_collect_object(ty),
Expression::Array { element_ty, .. } => maybe_collect_object(element_ty),
Expression::Struct { ty, .. } => maybe_collect_object(ty, hash),
Expression::Array { element_ty, .. } => maybe_collect_object(element_ty, hash),
Expression::EnumerationValue(ev) => {
maybe_collect_object(&Type::Enumeration(ev.enumeration.clone()))
maybe_collect_object(&Type::Enumeration(ev.enumeration.clone()), hash)
}
_ => (),
})

View file

@ -0,0 +1,26 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
//include_path: ../../helper_components
import { ExportedStruct, ExportEnum } from "export_structs.slint";
export { ExportedStruct as NamedStruct, ExportEnum as NamedEnum }
component TestCase inherits Rectangle {
in-out property<ExportedStruct> st;
in-out property<ExportEnum> en: ExportEnum.Bonjour;
}
export { TestCase as NamedTestCase }
/*
```cpp
auto handle = NamedTestCase::create();
const TestCase &instance = *handle;
assert(instance.get_en() == NamedEnum::Bonjour);
```
```rust
let instance = NamedTestCase::new().unwrap();
assert_eq!(instance.get_en(), NamedEnum::Bonjour);
```
*/