mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
llr: Store a GlobalIndex in the EvaluationContext instead of a reference
So that the CompilationUnit is only borrowed once and can be made mutable
This commit is contained in:
parent
3e586edd1a
commit
1aeeba7d6b
6 changed files with 50 additions and 37 deletions
|
@ -794,11 +794,11 @@ pub fn generate(
|
|||
}),
|
||||
));
|
||||
|
||||
for glob in &llr.globals {
|
||||
for (idx, glob) in llr.globals.iter().enumerate() {
|
||||
let ty = if glob.is_builtin {
|
||||
format_smolstr!("slint::cbindgen_private::{}", glob.name)
|
||||
} else if glob.must_generate() {
|
||||
generate_global(&mut file, &conditional_includes, glob, &llr);
|
||||
generate_global(&mut file, &conditional_includes, idx, glob, &llr);
|
||||
file.definitions.extend(glob.aliases.iter().map(|name| {
|
||||
Declaration::TypeAlias(TypeAlias {
|
||||
old_name: ident(&glob.name),
|
||||
|
@ -2555,6 +2555,7 @@ fn generate_repeated_component(
|
|||
fn generate_global(
|
||||
file: &mut File,
|
||||
conditional_includes: &ConditionalIncludes,
|
||||
global_idx: llr::GlobalIndex,
|
||||
global: &llr::GlobalComponent,
|
||||
root: &llr::CompilationUnit,
|
||||
) {
|
||||
|
@ -2587,7 +2588,7 @@ fn generate_global(
|
|||
let mut init = vec!["(void)this->globals;".into()];
|
||||
let ctx = EvaluationContext::new_global(
|
||||
root,
|
||||
global,
|
||||
global_idx,
|
||||
CppGeneratorContext { global_access: "this->globals".into(), conditional_includes },
|
||||
);
|
||||
|
||||
|
@ -2918,7 +2919,7 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
);
|
||||
let property_name = ident(&sub_component.properties[*property_index].name);
|
||||
format!("self->{}{}", compo_path, property_name)
|
||||
} else if let Some(current_global) = ctx.current_global {
|
||||
} else if let Some(current_global) = ctx.current_global() {
|
||||
format!("this->{}", ident(¤t_global.properties[*property_index].name))
|
||||
} else {
|
||||
unreachable!()
|
||||
|
@ -2933,7 +2934,7 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
);
|
||||
let name = ident(&sub_component.functions[*function_index].name);
|
||||
format!("self->{compo_path}fn_{name}")
|
||||
} else if let Some(current_global) = ctx.current_global {
|
||||
} else if let Some(current_global) = ctx.current_global() {
|
||||
format!("this->fn_{}", ident(¤t_global.functions[*function_index].name))
|
||||
} else {
|
||||
unreachable!()
|
||||
|
|
|
@ -199,8 +199,9 @@ pub fn generate(
|
|||
let globals = llr
|
||||
.globals
|
||||
.iter()
|
||||
.filter(|glob| glob.must_generate())
|
||||
.map(|glob| generate_global(glob, &llr));
|
||||
.enumerate()
|
||||
.filter(|(_, glob)| glob.must_generate())
|
||||
.map(|(idx, glob)| generate_global(idx, glob, &llr));
|
||||
let shared_globals = generate_shared_globals(&llr, &compiler_config);
|
||||
let globals_ids = llr.globals.iter().filter(|glob| glob.exported).flat_map(|glob| {
|
||||
std::iter::once(ident(&glob.name)).chain(glob.aliases.iter().map(|x| ident(x)))
|
||||
|
@ -1327,7 +1328,11 @@ fn generate_functions(functions: &[llr::Function], ctx: &EvaluationContext) -> V
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn generate_global(global: &llr::GlobalComponent, root: &llr::CompilationUnit) -> TokenStream {
|
||||
fn generate_global(
|
||||
global_idx: llr::GlobalIndex,
|
||||
global: &llr::GlobalComponent,
|
||||
root: &llr::CompilationUnit,
|
||||
) -> TokenStream {
|
||||
let mut declared_property_vars = vec![];
|
||||
let mut declared_property_types = vec![];
|
||||
let mut declared_callbacks = vec![];
|
||||
|
@ -1361,7 +1366,7 @@ fn generate_global(global: &llr::GlobalComponent, root: &llr::CompilationUnit) -
|
|||
|
||||
let ctx = EvaluationContext::new_global(
|
||||
root,
|
||||
global,
|
||||
global_idx,
|
||||
RustGeneratorContext {
|
||||
global_access: quote!(_self.globals.get().unwrap().upgrade().unwrap()),
|
||||
},
|
||||
|
@ -1918,7 +1923,7 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
let property_name = ident(&sub_component.properties[*property_index].name);
|
||||
let property_field = access_component_field_offset(&component_id, &property_name);
|
||||
MemberAccess::Direct(quote!((#compo_path #property_field).apply_pin(_self)))
|
||||
} else if let Some(current_global) = ctx.current_global {
|
||||
} else if let Some(current_global) = ctx.current_global() {
|
||||
let global_name = global_inner_name(current_global);
|
||||
let property_name = ident(¤t_global.properties[*property_index].name);
|
||||
let property_field = quote!({ *&#global_name::FIELD_OFFSETS.#property_name });
|
||||
|
@ -2018,7 +2023,7 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
}
|
||||
let fn_id = ident(&format!("fn_{}", sub_component.functions[*function_index].name));
|
||||
MemberAccess::Direct(quote!(#compo_path.#fn_id))
|
||||
} else if let Some(current_global) = ctx.current_global {
|
||||
} else if let Some(current_global) = ctx.current_global() {
|
||||
let fn_id =
|
||||
ident(&format!("fn_{}", current_global.functions[*function_index].name));
|
||||
MemberAccess::Direct(quote!(_self.#fn_id))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
use super::{PropertyReference, SubComponentIndex};
|
||||
use super::{GlobalIndex, PropertyReference, SubComponentIndex};
|
||||
use crate::expression_tree::{BuiltinFunction, MinMaxOp, OperatorClass};
|
||||
use crate::langtype::Type;
|
||||
use crate::layout::Orientation;
|
||||
|
@ -482,7 +482,7 @@ impl<'a, T> ParentCtx<'a, T> {
|
|||
pub struct EvaluationContext<'a, T = ()> {
|
||||
pub compilation_unit: &'a super::CompilationUnit,
|
||||
pub current_sub_component: Option<SubComponentIndex>,
|
||||
pub current_global: Option<&'a super::GlobalComponent>,
|
||||
pub current_global: Option<GlobalIndex>,
|
||||
pub generator_state: T,
|
||||
/// The repeater parent
|
||||
pub parent: Option<ParentCtx<'a, T>>,
|
||||
|
@ -510,7 +510,7 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
|
||||
pub fn new_global(
|
||||
compilation_unit: &'a super::CompilationUnit,
|
||||
global: &'a super::GlobalComponent,
|
||||
global: GlobalIndex,
|
||||
generator_state: T,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -604,7 +604,7 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
|
||||
match prop {
|
||||
PropertyReference::Local { property_index, .. } => {
|
||||
if let Some(g) = self.current_global {
|
||||
if let Some(g) = self.current_global() {
|
||||
return PropertyInfoResult {
|
||||
analysis: Some(&g.prop_analysis[*property_index]),
|
||||
binding: g.init_values[*property_index]
|
||||
|
@ -674,6 +674,10 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
pub fn current_sub_component(&self) -> Option<&super::SubComponent> {
|
||||
self.current_sub_component.and_then(|i| self.compilation_unit.sub_components.get(i))
|
||||
}
|
||||
|
||||
pub fn current_global(&self) -> Option<&super::GlobalComponent> {
|
||||
self.current_global.and_then(|i| self.compilation_unit.globals.get(i))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> TypeResolutionContext for EvaluationContext<'a, T> {
|
||||
|
@ -686,7 +690,7 @@ impl<'a, T> TypeResolutionContext for EvaluationContext<'a, T> {
|
|||
[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
&sub_component.properties[*property_index].ty
|
||||
} else if let Some(current_global) = self.current_global {
|
||||
} else if let Some(current_global) = self.current_global() {
|
||||
¤t_global.properties[*property_index].ty
|
||||
} else {
|
||||
unreachable!()
|
||||
|
@ -723,7 +727,7 @@ impl<'a, T> TypeResolutionContext for EvaluationContext<'a, T> {
|
|||
[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
&sub_component.functions[*function_index].ret_ty
|
||||
} else if let Some(current_global) = self.current_global {
|
||||
} else if let Some(current_global) = self.current_global() {
|
||||
¤t_global.functions[*function_index].ret_ty
|
||||
} else {
|
||||
unreachable!()
|
||||
|
@ -755,7 +759,7 @@ pub(crate) struct PropertyInfoResult<'a> {
|
|||
pub(crate) enum ContextMap {
|
||||
Identity,
|
||||
InSubElement { path: Vec<usize>, parent: usize },
|
||||
InGlobal(usize),
|
||||
InGlobal(GlobalIndex),
|
||||
}
|
||||
|
||||
impl ContextMap {
|
||||
|
@ -861,11 +865,7 @@ impl ContextMap {
|
|||
EvaluationContext::new_sub_component(ctx.compilation_unit, e, (), None)
|
||||
}
|
||||
}
|
||||
ContextMap::InGlobal(g) => EvaluationContext::new_global(
|
||||
ctx.compilation_unit,
|
||||
&ctx.compilation_unit.globals[*g],
|
||||
(),
|
||||
),
|
||||
ContextMap::InGlobal(g) => EvaluationContext::new_global(ctx.compilation_unit, *g, ()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ use std::rc::Rc;
|
|||
pub type PropertyIndex = usize;
|
||||
// Index in CompilationUint::sub_components
|
||||
pub type SubComponentIndex = usize;
|
||||
// Index in CompilationUnit::globas
|
||||
pub type GlobalIndex = usize;
|
||||
|
||||
#[derive(Debug, Clone, derive_more::Deref)]
|
||||
pub struct MutExpression(RefCell<Expression>);
|
||||
|
@ -94,12 +96,12 @@ pub enum PropertyReference {
|
|||
/// The properties is a property relative to a parent ItemTree (`level` level deep)
|
||||
InParent { level: NonZeroUsize, parent_reference: Box<PropertyReference> },
|
||||
/// The property within a GlobalComponent
|
||||
Global { global_index: usize, property_index: usize },
|
||||
Global { global_index: GlobalIndex, property_index: usize },
|
||||
|
||||
/// A function in a sub component.
|
||||
Function { sub_component_path: Vec<usize>, function_index: usize },
|
||||
/// A function in a global.
|
||||
GlobalFunction { global_index: usize, function_index: usize },
|
||||
GlobalFunction { global_index: GlobalIndex, function_index: usize },
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -437,8 +439,8 @@ impl CompilationUnit {
|
|||
visitor(e, ctx);
|
||||
}
|
||||
});
|
||||
for g in &self.globals {
|
||||
let ctx = EvaluationContext::new_global(self, g, ());
|
||||
for (idx, g) in self.globals.iter().enumerate() {
|
||||
let ctx = EvaluationContext::new_global(self, idx, ());
|
||||
for e in g.init_values.iter().filter_map(|x| x.as_ref()) {
|
||||
visitor(&e.expression, &ctx)
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
visit_property(&p.prop, &root_ctx);
|
||||
}
|
||||
}
|
||||
for g in root.globals.iter().filter(|g| g.exported) {
|
||||
let ctx = EvaluationContext::new_global(root, g, ());
|
||||
for (idx, g) in root.globals.iter().enumerate().filter(|(_, g)| g.exported) {
|
||||
let ctx = EvaluationContext::new_global(root, idx, ());
|
||||
for p in g.public_properties.iter().filter(|p| {
|
||||
!matches!(
|
||||
p.prop,
|
||||
|
@ -136,8 +136,8 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
});
|
||||
|
||||
// TODO: only visit used function
|
||||
for g in root.globals.iter() {
|
||||
let ctx = EvaluationContext::new_global(root, g, ());
|
||||
for (idx, g) in root.globals.iter().enumerate() {
|
||||
let ctx = EvaluationContext::new_global(root, idx, ());
|
||||
for f in &g.functions {
|
||||
f.code.visit_property_references(&ctx, &mut visit_property);
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ struct PrettyPrinter<'a> {
|
|||
|
||||
impl<'a> PrettyPrinter<'a> {
|
||||
fn print_root(&mut self, root: &CompilationUnit) -> Result {
|
||||
for g in &root.globals {
|
||||
for (idx, g) in root.globals.iter().enumerate() {
|
||||
if !g.is_builtin {
|
||||
self.print_global(root, g)?;
|
||||
self.print_global(root, idx, g)?;
|
||||
}
|
||||
}
|
||||
for c in 0..root.sub_components.len() {
|
||||
|
@ -116,8 +116,13 @@ impl<'a> PrettyPrinter<'a> {
|
|||
writeln!(self.writer, "}}")
|
||||
}
|
||||
|
||||
fn print_global(&mut self, root: &CompilationUnit, global: &super::GlobalComponent) -> Result {
|
||||
let ctx = EvaluationContext::new_global(root, global, ());
|
||||
fn print_global(
|
||||
&mut self,
|
||||
root: &CompilationUnit,
|
||||
idx: super::GlobalIndex,
|
||||
global: &super::GlobalComponent,
|
||||
) -> Result {
|
||||
let ctx = EvaluationContext::new_global(root, idx, ());
|
||||
if global.exported {
|
||||
write!(self.writer, "export ")?;
|
||||
}
|
||||
|
@ -184,7 +189,7 @@ impl<T> Display for DisplayPropertyRef<'_, T> {
|
|||
let mut ctx = self.1;
|
||||
match &self.0 {
|
||||
PropertyReference::Local { sub_component_path, property_index } => {
|
||||
if let Some(g) = ctx.current_global {
|
||||
if let Some(g) = ctx.current_global() {
|
||||
write!(f, "{}.{}", g.name, g.properties[*property_index].name)
|
||||
} else {
|
||||
let mut sc = ctx.current_sub_component().unwrap();
|
||||
|
@ -215,7 +220,7 @@ impl<T> Display for DisplayPropertyRef<'_, T> {
|
|||
write!(f, "{}.{}", g.name, g.properties[*property_index].name)
|
||||
}
|
||||
PropertyReference::Function { sub_component_path, function_index } => {
|
||||
if let Some(g) = ctx.current_global {
|
||||
if let Some(g) = ctx.current_global() {
|
||||
write!(f, "{}.{}", g.name, g.functions[*function_index].name)
|
||||
} else {
|
||||
let mut sc = ctx.current_sub_component().unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue