From 3a7a0d2bac2fd21652382761d521c6a5274f825f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 28 Oct 2018 18:28:01 +0100 Subject: [PATCH] Fix property Into generation --- src/codegen/properties.rs | 90 ++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/src/codegen/properties.rs b/src/codegen/properties.rs index 37d6c8f41..94ca52d40 100644 --- a/src/codegen/properties.rs +++ b/src/codegen/properties.rs @@ -1,5 +1,6 @@ use std::io::{Result, Write}; +use analysis; use analysis::bounds::{Bound, Bounds}; use analysis::properties::Property; use analysis::rust_type::{parameter_rust_type, rust_type}; @@ -88,34 +89,58 @@ fn declaration(env: &Env, prop: &Property) -> String { .. }) = prop.bound { - if bound_type.is_into() { - let mut bounds = Bounds::default(); - bounds.add_parameter(&prop.var_name, - ¶meter_rust_type(env, prop.typ, dir, prop.nullable, prop.set_in_ref_mode).into_string(), - bound_type.clone(), - false); - bound = codegen::function::bounds(&bounds, &[], false); - format!("{}", bounds.iter().next().unwrap().alias) - } else { - let value_bound = if !prop.is_get { + use library::Type::*; + use analysis::bounds::BoundType; + + let type_ = env.library.type_(prop.typ); + let bound_type = match *type_ { + Fundamental(_) => Some(bound_type.clone()), + _ => match bound_type { + BoundType::Into(_, Some(ref x)) => Some(*x.clone()), + _ => None, + } + }; + match bound_type { + Some(ref bound_type) if bound_type.is_into() => { + let type_name = parameter_rust_type(env, + prop.typ, + dir, + library::Nullable(false), + analysis::ref_mode::RefMode::ByRefFake) + .into_string(); + let mut bounds = Bounds::default(); + bounds.add_parameter(&prop.var_name, + &type_name, + bound_type.clone(), + false); + bound = codegen::function::bounds(&bounds, &[], false); + format!("{}", bounds.iter().next().unwrap().alias) + } + Some(_) => { + let value_bound = if !prop.is_get { + if *prop.nullable { + " + glib::value::SetValueOptional" + } else { + " + glib::value::SetValue" + } + } else { + "" + }; + bound = format!( + "<{}: IsA<{}> + IsA{}>", + alias, + type_str, + value_bound + ); if *prop.nullable { - " + glib::value::SetValueOptional" + format!("Option<&{}>", alias) } else { - " + glib::value::SetValue" + format!("&{}", alias) } - } else { - "" - }; - bound = format!( - "<{}: IsA<{}> + IsA{}>", - alias, - type_str, - value_bound - ); - if *prop.nullable { - format!("Option<&{}>", alias) - } else { - format!("&{}", alias) + } + _ => { + parameter_rust_type(env, prop.typ, dir, prop.nullable, prop.set_in_ref_mode) + .into_string() } } } else { @@ -149,6 +174,21 @@ fn body(env: &Env, prop: &Property) -> Chunk { .var_name(&prop.var_name) .is_get(prop.is_get) .is_ref(prop.set_in_ref_mode.is_ref()) + .is_into({ + use library::Type::*; + + let type_ = env.library.type_(prop.typ); + match *type_ { + Fundamental(_) => { + if let Some(Bound { ref bound_type, .. }) = prop.bound { + bound_type.is_into() + } else { + false + } + } + _ => false, + } + }) .is_nullable(*prop.nullable); if let Ok(type_) = rust_type(env, prop.typ) {