Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/analysis/class_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ fn analyze_property(
func_name: String::new(),
func_name_alias: None,
nullable,
is_array: prop.is_array,
get_out_ref_mode,
set_in_ref_mode,
set_bound: None,
Expand Down
30 changes: 28 additions & 2 deletions src/analysis/function_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
pub struct Parameter {
pub lib_par: library::Parameter,
pub try_from_glib: TryFromGlib,
pub nullable: Nullable,
}

impl Parameter {
Expand All @@ -29,6 +30,11 @@ impl Parameter {
Parameter {
lib_par: lib_par.clone(),
try_from_glib: TryFromGlib::from_parameter(env, lib_par.typ, configured_parameters),
nullable: configured_parameters
.iter()
.filter_map(|p| p.nullable)
.next()
.unwrap_or(lib_par.nullable),
}
}

Expand All @@ -40,6 +46,11 @@ impl Parameter {
Parameter {
lib_par: lib_par.clone(),
try_from_glib: TryFromGlib::from_return_value(env, lib_par.typ, configured_functions),
nullable: configured_functions
.iter()
.filter_map(|f| f.ret.nullable)
.next()
.unwrap_or(lib_par.nullable),
}
}
}
Expand Down Expand Up @@ -107,6 +118,7 @@ pub enum TransformationType {
array_name: String,
array_length_name: String,
array_length_type: String,
nullable: library::Nullable,
},
IntoRaw(String),
ToSome(String),
Expand Down Expand Up @@ -176,7 +188,13 @@ impl Parameters {
let transformation = Transformation {
ind_c,
ind_rust: None,
transformation_type: get_length_type(env, "", &c_par.name, c_par.typ),
transformation_type: get_length_type(
env,
"",
&c_par.name,
c_par.typ,
library::Nullable(false),
),
};
self.transformations.push(transformation);
}
Expand Down Expand Up @@ -301,7 +319,13 @@ pub fn analyze(
let transformation = Transformation {
ind_c,
ind_rust: None,
transformation_type: get_length_type(env, &array_name, &par.name, typ),
transformation_type: get_length_type(
env,
&array_name,
&par.name,
typ,
array_par.nullable,
),
};
parameters.transformations.push(transformation);
}
Expand Down Expand Up @@ -448,12 +472,14 @@ fn get_length_type(
array_name: &str,
length_name: &str,
length_typ: TypeId,
nullable: library::Nullable,
) -> TransformationType {
let array_length_type = RustType::try_new(env, length_typ).into_string();
TransformationType::Length {
array_name: array_name.to_string(),
array_length_name: length_name.to_string(),
array_length_type,
nullable,
}
}

Expand Down
14 changes: 4 additions & 10 deletions src/analysis/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub struct Property {
pub func_name: String,
pub func_name_alias: Option<String>,
pub nullable: library::Nullable,
pub is_array: bool,
pub get_out_ref_mode: RefMode,
pub set_in_ref_mode: RefMode,
pub bounds: Bounds,
Expand Down Expand Up @@ -265,6 +266,7 @@ fn analyze_property(
func_name: get_func_name,
func_name_alias: get_prop_name,
nullable,
is_array: prop.is_array,
get_out_ref_mode,
set_in_ref_mode,
set_bound: None,
Expand Down Expand Up @@ -318,6 +320,7 @@ fn analyze_property(
func_name: set_func_name,
func_name_alias: set_prop_name,
nullable,
is_array: prop.is_array,
get_out_ref_mode,
set_in_ref_mode,
set_bound,
Expand Down Expand Up @@ -348,17 +351,8 @@ fn analyze_property(
.find_type(library::INTERNAL_NAMESPACE, "none")
.unwrap(),
c_type: "none".into(),
instance_parameter: false,
direction: library::ParameterDirection::Return,
transfer: library::Transfer::None,
caller_allocates: false,
nullable: library::Nullable(false),
array_length: None,
is_error: false,
doc: None,
scope: library::ParameterScope::None,
closure: None,
destroy: None,
..Default::default()
},
is_action: false,
is_detailed: false, /* well, technically this *is* an instance of a detailed
Expand Down
35 changes: 24 additions & 11 deletions src/analysis/return_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,32 @@ pub fn analyze(

let parameter = parameter.as_ref().map(|lib_par| {
let par = analysis::Parameter::from_return_value(env, lib_par, configured_functions);
if let Ok(rust_type) = RustType::builder(env, typ)
.direction(par.lib_par.direction)
.try_from_glib(&par.try_from_glib)
.try_build()
if par.lib_par.is_array
&& !par.lib_par.zero_terminated.unwrap_or(true)
&& par.lib_par.array_length.is_none()
{
used_types.extend(rust_type.into_used_types());
}
// The array length for the return value of this function can not be inferred
// from any argument. How the length should be inferred is usually specified
// in the doc of the function, so there's nothing we can do automatically.
// Currently the functions matching this condition are explicitly marked
// `manual = true` in the matching Gir.toml.
// FIXME: `FixedArray`s could be handled automatically
commented = true;
} else {
if let Ok(rust_type) = RustType::builder(env, typ)
.direction(par.lib_par.direction)
.try_from_glib(&par.try_from_glib)
.try_build()
{
used_types.extend(rust_type.into_used_types());
}

commented = RustType::builder(env, typ)
.direction(func.ret.direction)
.try_from_glib(&par.try_from_glib)
.try_build_param()
.is_err();
commented = RustType::builder(env, typ)
.direction(func.ret.direction)
.try_from_glib(&par.try_from_glib)
.try_build_param()
.is_err();
}

par
});
Expand Down
5 changes: 1 addition & 4 deletions src/analysis/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ impl<'env> RustTypeBuilder<'env> {
let ok = |s: &str| Ok(RustType::from(s));
let ok_and_use = |s: &str| Ok(RustType::new_and_use(&s));
let err = |s: &str| Err(TypeError::Unimplemented(s.into()));
let mut skip_option = false;
let type_ = self.env.library.type_(self.type_id);
let mut rust_type = match *type_ {
Basic(fund) => {
Expand Down Expand Up @@ -355,7 +354,6 @@ impl<'env> RustTypeBuilder<'env> {
List(inner_tid) | SList(inner_tid) | CArray(inner_tid) | PtrArray(inner_tid)
if ConversionType::of(self.env, inner_tid) == ConversionType::Pointer =>
{
skip_option = true;
let inner_ref_mode = match self.env.type_(inner_tid) {
Class(..) | Interface(..) => RefMode::None,
Record(record) => match RecordType::of(record) {
Expand Down Expand Up @@ -409,7 +407,6 @@ impl<'env> RustTypeBuilder<'env> {
};

if let Some(s) = array_type {
skip_option = true;
if self.ref_mode.is_ref() {
Ok(format!("[{s}]").into())
} else {
Expand Down Expand Up @@ -604,7 +601,7 @@ impl<'env> RustTypeBuilder<'env> {
}
}

if *self.nullable && !skip_option {
if *self.nullable {
match ConversionType::of(self.env, self.type_id) {
ConversionType::Pointer | ConversionType::Scalar => {
rust_type = rust_type.map_any(|rust_type| {
Expand Down
5 changes: 4 additions & 1 deletion src/chunk/conversion_from_glib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use super::parameter_ffi_call_out;
use crate::{
analysis::{self, try_from_glib::TryFromGlib},
library,
library::{self, Nullable},
};

#[derive(Clone, Debug)]
pub struct Mode {
pub typ: library::TypeId,
pub transfer: library::Transfer,
pub try_from_glib: TryFromGlib,
pub nullable: Nullable,
}

impl From<&parameter_ffi_call_out::Parameter> for Mode {
Expand All @@ -17,6 +18,7 @@ impl From<&parameter_ffi_call_out::Parameter> for Mode {
typ: orig.typ,
transfer: orig.transfer,
try_from_glib: orig.try_from_glib.clone(),
nullable: orig.nullable,
}
}
}
Expand All @@ -27,6 +29,7 @@ impl From<&analysis::Parameter> for Mode {
typ: orig.lib_par.typ,
transfer: orig.lib_par.transfer,
try_from_glib: orig.try_from_glib.clone(),
nullable: orig.nullable,
}
}
}
5 changes: 4 additions & 1 deletion src/chunk/parameter_ffi_call_out.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
analysis::{self, try_from_glib::TryFromGlib},
library,
library::{self, Nullable},
};

#[derive(Clone, Debug)]
Expand All @@ -12,6 +12,7 @@ pub struct Parameter {
pub is_error: bool,
pub is_uninitialized: bool,
pub try_from_glib: TryFromGlib,
pub nullable: Nullable,
}

impl Parameter {
Expand All @@ -24,6 +25,7 @@ impl Parameter {
is_error: orig.is_error,
is_uninitialized,
try_from_glib: orig.try_from_glib.clone(),
nullable: orig.nullable,
}
}
}
Expand All @@ -38,6 +40,7 @@ impl From<&analysis::Parameter> for Parameter {
is_error: orig.lib_par.is_error,
is_uninitialized: false,
try_from_glib: orig.try_from_glib.clone(),
nullable: orig.nullable,
}
}
}
10 changes: 9 additions & 1 deletion src/codegen/function_body_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,11 +962,19 @@ impl Builder {
if let TransformationType::Length {
ref array_name,
ref array_length_name,
nullable,
..
} = trans.transformation_type
{
if let In = self.parameters[trans.ind_c] {
let value = Chunk::Custom(format!("{array_name}.len() as _"));
let value = if !*nullable {
Chunk::Custom(format!("{}.len() as _", array_name))
} else {
Chunk::Custom(format!(
"{}.map(|arr| arr.len()).unwrap_or(0) as _",
array_name
))
};
chunks.push(Chunk::Let {
name: array_length_name.clone(),
is_mut: false,
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ fn declaration(env: &Env, prop: &Property) -> String {
let dir = library::ParameterDirection::Return;
let ret_type = RustType::builder(env, prop.typ)
.direction(dir)
.nullable(prop.nullable)
.nullable(prop.nullable & !prop.is_array)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which APIs is this relevant with?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Examples in gtk-rs-core (prop getters):

  • gio::[D]tlsConnection: advertised-protocols
  • gio::SimpleProxyResolver: ignore-hosts

.ref_mode(prop.get_out_ref_mode)
.try_build_param()
.into_string();
Expand Down
15 changes: 13 additions & 2 deletions src/codegen/translate_from_glib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,21 @@ impl TranslateFromGlib for Mode {
| library::Type::SList(..)
| library::Type::PtrArray(..)
| library::Type::CArray(..) => {
let (pre1, pre2) = if *self.nullable {
("Maybe", "maybe_")
} else {
("", "")
};
if array_length.is_some() {
(format!("FromGlibContainer::{}", trans.0), trans.1)
(
format!("{pre1}FromGlibContainer::{pre2}{}", trans.0),
trans.1,
)
} else {
(format!("FromGlibPtrContainer::{}", trans.0), trans.1)
(
format!("{pre1}FromGlibPtrContainer::{pre2}{}", trans.0),
trans.1,
)
}
}
_ => trans,
Expand Down
Loading
Loading