From 07dcf3fe218d61e72073da72ba60ccbcd990bfb8 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Thu, 8 Jun 2023 09:45:10 -0400 Subject: [PATCH] Cleanup the CodeOracle by removing CodeTypeDispatch entirely (#1588) This fixes a source of significant confusion in the code-oracle support. * Every `CodeType` method takes a `CodeOracle` param - which is odd because the `CodeType` came from the oracle - it doesn't need the oracle to work. * There's a blanket implementation of `CodeType` made available for `Type` - so not only do we now have a `CodeType` that didn't come from an Oracle, so clearly can't know the language semantics the Oracle abstracts away, there's now *two* implementations of `CodeType` for each type, with each behaving differently. This cleans all that up: * CodeType is only supplied by Oracles - there's no blanket implementation for Type. * Therefore `CodeType` no longer takes Oracle's as args. * `CodeTypeDispatch` has been replaced by an `AsType` trait, which is implemented by Type itself and all the structs used by the codegen. --- uniffi_bindgen/src/backend/mod.rs | 3 +- uniffi_bindgen/src/backend/oracle.rs | 18 +- uniffi_bindgen/src/backend/types.rs | 168 +++--------------- .../kotlin/gen_kotlin/callback_interface.rs | 13 +- .../bindings/kotlin/gen_kotlin/compounds.rs | 52 +++--- .../src/bindings/kotlin/gen_kotlin/custom.rs | 9 +- .../src/bindings/kotlin/gen_kotlin/enum_.rs | 13 +- .../src/bindings/kotlin/gen_kotlin/error.rs | 9 +- .../bindings/kotlin/gen_kotlin/executor.rs | 9 +- .../bindings/kotlin/gen_kotlin/external.rs | 9 +- .../bindings/kotlin/gen_kotlin/miscellany.rs | 9 +- .../src/bindings/kotlin/gen_kotlin/mod.rs | 59 +++--- .../src/bindings/kotlin/gen_kotlin/object.rs | 9 +- .../bindings/kotlin/gen_kotlin/primitives.rs | 11 +- .../src/bindings/kotlin/gen_kotlin/record.rs | 9 +- .../kotlin/templates/ErrorTemplate.kt | 2 +- .../src/bindings/kotlin/templates/Helpers.kt | 2 +- .../python/gen_python/callback_interface.rs | 9 +- .../bindings/python/gen_python/compounds.rs | 49 ++--- .../src/bindings/python/gen_python/custom.rs | 7 +- .../src/bindings/python/gen_python/enum_.rs | 13 +- .../src/bindings/python/gen_python/error.rs | 9 +- .../bindings/python/gen_python/executor.rs | 7 +- .../bindings/python/gen_python/external.rs | 7 +- .../bindings/python/gen_python/miscellany.rs | 9 +- .../src/bindings/python/gen_python/mod.rs | 45 ++--- .../src/bindings/python/gen_python/object.rs | 9 +- .../bindings/python/gen_python/primitives.rs | 12 +- .../src/bindings/python/gen_python/record.rs | 9 +- .../src/bindings/python/templates/macros.py | 4 +- .../ruby/templates/RustBufferBuilder.rb | 4 +- .../ruby/templates/RustBufferStream.rb | 6 +- .../src/bindings/ruby/templates/macros.rb | 6 +- .../swift/gen_swift/callback_interface.rs | 9 +- .../src/bindings/swift/gen_swift/compounds.rs | 61 ++++--- .../src/bindings/swift/gen_swift/custom.rs | 7 +- .../src/bindings/swift/gen_swift/enum_.rs | 11 +- .../src/bindings/swift/gen_swift/error.rs | 7 +- .../src/bindings/swift/gen_swift/executor.rs | 9 +- .../src/bindings/swift/gen_swift/external.rs | 15 +- .../bindings/swift/gen_swift/miscellany.rs | 12 +- .../src/bindings/swift/gen_swift/mod.rs | 44 +++-- .../src/bindings/swift/gen_swift/object.rs | 7 +- .../bindings/swift/gen_swift/primitives.rs | 20 ++- .../src/bindings/swift/gen_swift/record.rs | 7 +- uniffi_bindgen/src/interface/callbacks.rs | 12 +- uniffi_bindgen/src/interface/enum_.rs | 26 +-- uniffi_bindgen/src/interface/error.rs | 14 +- uniffi_bindgen/src/interface/function.rs | 16 +- uniffi_bindgen/src/interface/mod.rs | 8 +- uniffi_bindgen/src/interface/object.rs | 18 +- uniffi_bindgen/src/interface/record.rs | 32 ++-- uniffi_bindgen/src/interface/types/finder.rs | 4 +- uniffi_bindgen/src/interface/types/mod.rs | 22 +++ .../templates/CallbackInterfaceTemplate.rs | 2 +- .../src/scaffolding/templates/EnumTemplate.rs | 2 +- .../scaffolding/templates/ErrorTemplate.rs | 2 +- .../scaffolding/templates/RecordTemplate.rs | 2 +- .../src/scaffolding/templates/macros.rs | 4 +- 59 files changed, 468 insertions(+), 514 deletions(-) diff --git a/uniffi_bindgen/src/backend/mod.rs b/uniffi_bindgen/src/backend/mod.rs index ed4c032508..a2524ffe53 100644 --- a/uniffi_bindgen/src/backend/mod.rs +++ b/uniffi_bindgen/src/backend/mod.rs @@ -12,5 +12,4 @@ pub use declarations::CodeDeclaration; pub use oracle::CodeOracle; pub use types::CodeType; -pub type TypeIdentifier = crate::interface::Type; -pub type Literal = crate::interface::Literal; +pub use crate::interface::{Literal, Type}; diff --git a/uniffi_bindgen/src/backend/oracle.rs b/uniffi_bindgen/src/backend/oracle.rs index c911dc7df7..5bbc775e61 100644 --- a/uniffi_bindgen/src/backend/oracle.rs +++ b/uniffi_bindgen/src/backend/oracle.rs @@ -2,19 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use super::{CodeType, TypeIdentifier}; -use crate::interface::FfiType; - -/// An object to look up a foreign language code specific renderer for a given type used. -/// Every `Type` referred to in the `ComponentInterface` should map to a corresponding -/// `CodeType`. -/// -/// The mapping may be opaque, but the oracle always knows the answer. -/// -/// In adddition, the oracle knows how to render identifiers (function names, -/// class names, variable names etc). +use super::CodeType; +use crate::interface::{FfiType, Type}; + +/// An object to supply a foreign language specific CodeType for a given type. It also +/// supplys the specific rendering of a given identifier when used in a specific context. pub trait CodeOracle { - fn find(&self, type_: &TypeIdentifier) -> Box; + fn find(&self, type_: &Type) -> Box; /// Get the idiomatic rendering of a class name (for enums, records, errors, etc). fn class_name(&self, nm: &str) -> String; diff --git a/uniffi_bindgen/src/backend/types.rs b/uniffi_bindgen/src/backend/types.rs index 66495e7edc..cb5ed6a987 100644 --- a/uniffi_bindgen/src/backend/types.rs +++ b/uniffi_bindgen/src/backend/types.rs @@ -11,50 +11,39 @@ //! (the FfiType), and foreign language expressions that call into the machinery. This helper code //! can be provided by a template file. //! -//! A `CodeDeclaration` is needed for each type that is declared in the UDL file. This has access to -//! the [crate::interface::ComponentInterface], which is the closest thing to an Intermediate Representation. -//! -//! `CodeDeclaration`s provide the target language's version of the UDL type, including forwarding method calls -//! into Rust. It is likely if you're implementing a `CodeDeclaration` for this purpose, it will also need to cross -//! the FFI, and you'll also need a `CodeType`. -//! -//! `CodeDeclaration`s can also be used to conditionally include code: e.g. only include the CallbackInterfaceRuntime -//! if the user has used at least one callback interface. -//! -//! Each backend has a wrapper template for each file it needs to generate. This should collect the `CodeDeclaration`s that -//! the backend and `ComponentInterface` between them specify and use them to stitch together a file in the target language. -//! //! The `CodeOracle` provides methods to map the `Type` values found in the `ComponentInterface` to the `CodeType`s specified //! by the backend. It also provides methods for transforming identifiers into the coding standard for the target language. //! +//! There's also a CodeTypeDispatch trait, implemented for every type, which allows a CodeType to be created +//! by the specified `CodeOracle`. This means backends are able to provide a custom CodeType for each type +//! via that backend's CodeOracle. +//! //! Each backend will have its own `filter` module, which is used by the askama templates used in all `CodeType`s and `CodeDeclaration`s. //! This filter provides methods to generate expressions and identifiers in the target language. These are all forwarded to the oracle. -use super::{CodeOracle, Literal}; +use std::fmt::Debug; + use crate::interface::*; -/// A Trait to emit foreign language code to handle referenced types. -/// A type which is specified in the UDL (i.e. a member of the component interface) -/// will have a `CodeDeclaration` as well, but for types used e.g. primitive types, Strings, etc -/// only a `CodeType` is needed. -pub trait CodeType { +/// A Trait to help render types in a language specific format. +pub trait CodeType: Debug { /// The language specific label used to reference this type. This will be used in /// method signatures and property declarations. - fn type_label(&self, oracle: &dyn CodeOracle) -> String; + fn type_label(&self) -> String; /// A representation of this type label that can be used as part of another /// identifier. e.g. `read_foo()`, or `FooInternals`. /// /// This is especially useful when creating specialized objects or methods to deal /// with this type only. - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { - self.type_label(oracle) + fn canonical_name(&self) -> String { + self.type_label() } /// A representation of the given literal for this type. /// N.B. `Literal` is aliased from `interface::Literal`, so may not be whole suited to this task. - fn literal(&self, oracle: &dyn CodeOracle, _literal: &Literal) -> String { - unimplemented!("Unimplemented for {}", self.type_label(oracle)) + fn literal(&self, _literal: &Literal) -> String { + unimplemented!("Unimplemented for {}", self.type_label()) } /// Name of the FfiConverter @@ -65,145 +54,38 @@ pub trait CodeType { /// This is the newer way of handling these methods and replaces the lower, write, lift, and /// read CodeType methods. Currently only used by Kotlin, but the plan is to move other /// backends to using this. - fn ffi_converter_name(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&format!("FfiConverter{}", self.canonical_name(oracle))) + fn ffi_converter_name(&self) -> String { + format!("FfiConverter{}", self.canonical_name()) } /// An expression for lowering a value into something we can pass over the FFI. - fn lower(&self, oracle: &dyn CodeOracle) -> String { - format!("{}.lower", self.ffi_converter_name(oracle)) + fn lower(&self) -> String { + format!("{}.lower", self.ffi_converter_name()) } /// An expression for writing a value into a byte buffer. - fn write(&self, oracle: &dyn CodeOracle) -> String { - format!("{}.write", self.ffi_converter_name(oracle)) + fn write(&self) -> String { + format!("{}.write", self.ffi_converter_name()) } /// An expression for lifting a value from something we received over the FFI. - fn lift(&self, oracle: &dyn CodeOracle) -> String { - format!("{}.lift", self.ffi_converter_name(oracle)) + fn lift(&self) -> String { + format!("{}.lift", self.ffi_converter_name()) } /// An expression for reading a value from a byte buffer. - fn read(&self, oracle: &dyn CodeOracle) -> String { - format!("{}.read", self.ffi_converter_name(oracle)) + fn read(&self) -> String { + format!("{}.read", self.ffi_converter_name()) } /// A list of imports that are needed if this type is in use. /// Classes are imported exactly once. - fn imports(&self, _oracle: &dyn CodeOracle) -> Option> { + fn imports(&self) -> Option> { None } /// Function to run at startup - fn initialization_fn(&self, _oracle: &dyn CodeOracle) -> Option { + fn initialization_fn(&self) -> Option { None } } - -/// This trait is used to implement `CodeType` for `Type` and type-like structs (`Record`, `Enum`, `Field`, -/// etc). We forward all method calls to a `Box`, which we get by calling -/// `CodeOracle.find()`. -pub trait CodeTypeDispatch { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box; -} - -impl CodeTypeDispatch for Type { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(self) - } -} - -impl CodeTypeDispatch for Record { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(&self.type_()) - } -} - -impl CodeTypeDispatch for Enum { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(&self.type_()) - } -} - -impl CodeTypeDispatch for Error { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(&self.type_()) - } -} - -impl CodeTypeDispatch for Object { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(&self.type_()) - } -} - -impl CodeTypeDispatch for CallbackInterface { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(&self.type_()) - } -} - -impl CodeTypeDispatch for Field { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(self.type_()) - } -} - -impl CodeTypeDispatch for Argument { - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - oracle.find(self.type_()) - } -} - -// Needed to handle &&Type and &&&Type values, which we sometimes end up with in the template code -impl CodeTypeDispatch for T -where - T: std::ops::Deref, - C: CodeTypeDispatch, -{ - fn code_type_impl(&self, oracle: &dyn CodeOracle) -> Box { - self.deref().code_type_impl(oracle) - } -} - -impl CodeType for T { - // The above code implements `CodeTypeDispatch` for `Type` and type-like structs (`Record`, - // `Enum`, `Field`, etc). Now we can leverage that to implement `CodeType` for all of them. - // This allows for simpler template code (`field|lower` instead of `field.type_()|lower`) - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - self.code_type_impl(oracle).type_label(oracle) - } - - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { - self.code_type_impl(oracle).canonical_name(oracle) - } - - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { - self.code_type_impl(oracle).literal(oracle, literal) - } - - fn lower(&self, oracle: &dyn CodeOracle) -> String { - self.code_type_impl(oracle).lower(oracle) - } - - fn write(&self, oracle: &dyn CodeOracle) -> String { - self.code_type_impl(oracle).write(oracle) - } - - fn lift(&self, oracle: &dyn CodeOracle) -> String { - self.code_type_impl(oracle).lift(oracle) - } - - fn read(&self, oracle: &dyn CodeOracle) -> String { - self.code_type_impl(oracle).read(oracle) - } - - fn imports(&self, oracle: &dyn CodeOracle) -> Option> { - self.code_type_impl(oracle).imports(oracle) - } - - fn initialization_fn(&self, oracle: &dyn CodeOracle) -> Option { - self.code_type_impl(oracle).initialization_fn(oracle) - } -} diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/callback_interface.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/callback_interface.rs index c0c7ab29b9..71abc66b15 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/callback_interface.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/callback_interface.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct CallbackInterfaceCodeType { id: String, } @@ -15,19 +16,19 @@ impl CallbackInterfaceCodeType { } impl CodeType for CallbackInterfaceCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::KotlinCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } - fn initialization_fn(&self, oracle: &dyn CodeOracle) -> Option { - Some(format!("{}.register", self.ffi_converter_name(oracle))) + fn initialization_fn(&self) -> Option { + Some(format!("{}.register", self.ffi_converter_name())) } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/compounds.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/compounds.rs index 7d5f77141f..cd3ea7f26c 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/compounds.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/compounds.rs @@ -2,47 +2,48 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal, TypeIdentifier}; +use crate::backend::{CodeOracle, CodeType, Literal, Type}; use paste::paste; -fn render_literal(oracle: &dyn CodeOracle, literal: &Literal, inner: &TypeIdentifier) -> String { +fn render_literal(literal: &Literal, inner: &Type) -> String { match literal { Literal::Null => "null".into(), Literal::EmptySequence => "listOf()".into(), Literal::EmptyMap => "mapOf()".into(), // For optionals - _ => oracle.find(inner).literal(oracle, literal), + _ => super::KotlinCodeOracle.find(inner).literal(literal), } } macro_rules! impl_code_type_for_compound { ($T:ty, $type_label_pattern:literal, $canonical_name_pattern: literal) => { paste! { + #[derive(Debug)] pub struct $T { - inner: TypeIdentifier, + inner: Type, } impl $T { - pub fn new(inner: TypeIdentifier) -> Self { + pub fn new(inner: Type) -> Self { Self { inner } } - fn inner(&self) -> &TypeIdentifier { + fn inner(&self) -> &Type { &self.inner } } impl CodeType for $T { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - format!($type_label_pattern, oracle.find(self.inner()).type_label(oracle)) + fn type_label(&self) -> String { + format!($type_label_pattern, super::KotlinCodeOracle.find(self.inner()).type_label()) } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { - format!($canonical_name_pattern, oracle.find(self.inner()).canonical_name(oracle)) + fn canonical_name(&self) -> String { + format!($canonical_name_pattern, super::KotlinCodeOracle.find(self.inner()).canonical_name()) } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { - render_literal(oracle, literal, self.inner()) + fn literal(&self, literal: &Literal) -> String { + render_literal(literal, self.inner()) } } } @@ -52,43 +53,44 @@ macro_rules! impl_code_type_for_compound { impl_code_type_for_compound!(OptionalCodeType, "{}?", "Optional{}"); impl_code_type_for_compound!(SequenceCodeType, "List<{}>", "Sequence{}"); +#[derive(Debug)] pub struct MapCodeType { - key: TypeIdentifier, - value: TypeIdentifier, + key: Type, + value: Type, } impl MapCodeType { - pub fn new(key: TypeIdentifier, value: TypeIdentifier) -> Self { + pub fn new(key: Type, value: Type) -> Self { Self { key, value } } - fn key(&self) -> &TypeIdentifier { + fn key(&self) -> &Type { &self.key } - fn value(&self) -> &TypeIdentifier { + fn value(&self) -> &Type { &self.value } } impl CodeType for MapCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { format!( "Map<{}, {}>", - self.key().type_label(oracle), - self.value().type_label(oracle), + super::KotlinCodeOracle.find(self.key()).type_label(), + super::KotlinCodeOracle.find(self.value()).type_label(), ) } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!( "Map{}{}", - self.key().type_label(oracle), - self.value().type_label(oracle), + super::KotlinCodeOracle.find(self.key()).canonical_name(), + super::KotlinCodeOracle.find(self.value()).canonical_name(), ) } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { - render_literal(oracle, literal, &self.value) + fn literal(&self, literal: &Literal) -> String { + render_literal(literal, &self.value) } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/custom.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/custom.rs index 4a5636a228..930fc5879e 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/custom.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/custom.rs @@ -2,8 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal}; +use crate::backend::{CodeType, Literal}; +#[derive(Debug)] pub struct CustomCodeType { name: String, } @@ -15,15 +16,15 @@ impl CustomCodeType { } impl CodeType for CustomCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { self.name.clone() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.name) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!("Can't have a literal of a custom type"); } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/enum_.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/enum_.rs index 941008e370..c932334f70 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/enum_.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/enum_.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct EnumCodeType { id: String, } @@ -15,20 +16,20 @@ impl EnumCodeType { } impl CodeType for EnumCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::KotlinCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { if let Literal::Enum(v, _) = literal { format!( "{}.{}", - self.type_label(oracle), - oracle.enum_variant_name(v) + self.type_label(), + super::KotlinCodeOracle.enum_variant_name(v) ) } else { unreachable!(); diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/error.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/error.rs index 3ab5f0ac9f..eeb5f59ba7 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/error.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/error.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct ErrorCodeType { id: String, } @@ -15,15 +16,15 @@ impl ErrorCodeType { } impl CodeType for ErrorCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.error_name(&self.id) + fn type_label(&self) -> String { + super::KotlinCodeOracle.error_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/executor.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/executor.rs index b6297899c0..e46058e7f1 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/executor.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/executor.rs @@ -2,21 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct ForeignExecutorCodeType; impl CodeType for ForeignExecutorCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { // Kotlin uses a CoroutineScope for ForeignExecutor "CoroutineScope".into() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { "ForeignExecutor".into() } - fn initialization_fn(&self, _oracle: &dyn CodeOracle) -> Option { + fn initialization_fn(&self) -> Option { Some("FfiConverterForeignExecutor.register".into()) } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/external.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/external.rs index 32d47cb3f1..a637c964a1 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/external.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/external.rs @@ -2,8 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal}; +use crate::backend::{CodeType, Literal}; +#[derive(Debug)] pub struct ExternalCodeType { name: String, } @@ -15,15 +16,15 @@ impl ExternalCodeType { } impl CodeType for ExternalCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { self.name.clone() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.name) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!("Can't have a literal of an external type"); } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/miscellany.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/miscellany.rs index 57b9a145e7..9a744ade72 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/miscellany.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/miscellany.rs @@ -2,24 +2,25 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal}; +use crate::backend::{CodeType, Literal}; use paste::paste; macro_rules! impl_code_type_for_miscellany { ($T:ty, $class_name:literal, $canonical_name:literal) => { paste! { + #[derive(Debug)] pub struct $T; impl CodeType for $T { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { $class_name.into() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { $canonical_name.into() } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!() } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs index c64925a45c..f04f3f7ad7 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/mod.rs @@ -11,7 +11,7 @@ use askama::Template; use heck::{ToLowerCamelCase, ToShoutySnakeCase, ToUpperCamelCase}; use serde::{Deserialize, Serialize}; -use crate::backend::{CodeOracle, CodeType, TemplateExpression, TypeIdentifier}; +use crate::backend::{CodeOracle, CodeType, TemplateExpression}; use crate::interface::*; use crate::BindingsConfig; @@ -212,7 +212,8 @@ impl<'a> KotlinWrapper<'a> { pub fn initialization_fns(&self) -> Vec { self.ci .iter_types() - .filter_map(|t| t.initialization_fn(&KotlinCodeOracle)) + .map(|t| KotlinCodeOracle.find(t)) + .filter_map(|ct| ct.initialization_fn()) .collect() } @@ -225,14 +226,14 @@ impl<'a> KotlinWrapper<'a> { pub struct KotlinCodeOracle; impl KotlinCodeOracle { - // Map `Type` instances to a `Box` for that type. + // Map `Type` instances to a `Box` for that type. // // There is a companion match in `templates/Types.kt` which performs a similar function for the // template code. // // - When adding additional types here, make sure to also add a match arm to the `Types.kt` template. // - To keep things manageable, let's try to limit ourselves to these 2 mega-matches - fn create_code_type(&self, type_: TypeIdentifier) -> Box { + fn create_code_type(&self, type_: Type) -> Box { match type_ { Type::UInt8 => Box::new(primitives::UInt8CodeType), Type::Int8 => Box::new(primitives::Int8CodeType), @@ -269,7 +270,7 @@ impl KotlinCodeOracle { } impl CodeOracle for KotlinCodeOracle { - fn find(&self, type_: &TypeIdentifier) -> Box { + fn find(&self, type_: &Type) -> Box { self.create_code_type(type_.clone()) } @@ -342,39 +343,51 @@ pub mod filters { &KotlinCodeOracle } - pub fn type_name(codetype: &impl CodeType) -> Result { - Ok(codetype.type_label(oracle())) + pub fn type_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).type_label()) } - pub fn canonical_name(codetype: &impl CodeType) -> Result { - Ok(codetype.canonical_name(oracle())) + pub fn canonical_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).canonical_name()) } - pub fn ffi_converter_name(codetype: &impl CodeType) -> Result { - Ok(codetype.ffi_converter_name(oracle())) + pub fn ffi_converter_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).ffi_converter_name()) } - pub fn lower_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.lower", codetype.ffi_converter_name(oracle()))) + pub fn lower_fn(as_type: &impl AsType) -> Result { + Ok(format!( + "{}.lower", + oracle().find(&as_type.as_type()).ffi_converter_name() + )) } - pub fn allocation_size_fn(codetype: &impl CodeType) -> Result { + pub fn allocation_size_fn(as_type: &impl AsType) -> Result { Ok(format!( "{}.allocationSize", - codetype.ffi_converter_name(oracle()) + oracle().find(&as_type.as_type()).ffi_converter_name() )) } - pub fn write_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.write", codetype.ffi_converter_name(oracle()))) + pub fn write_fn(as_type: &impl AsType) -> Result { + Ok(format!( + "{}.write", + oracle().find(&as_type.as_type()).ffi_converter_name() + )) } - pub fn lift_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.lift", codetype.ffi_converter_name(oracle()))) + pub fn lift_fn(as_type: &impl AsType) -> Result { + Ok(format!( + "{}.lift", + oracle().find(&as_type.as_type()).ffi_converter_name() + )) } - pub fn read_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.read", codetype.ffi_converter_name(oracle()))) + pub fn read_fn(as_type: &impl AsType) -> Result { + Ok(format!( + "{}.read", + oracle().find(&as_type.as_type()).ffi_converter_name() + )) } pub fn error_handler(result_type: &ResultType) -> Result { @@ -408,9 +421,9 @@ pub mod filters { pub fn render_literal( literal: &Literal, - codetype: &impl CodeType, + as_type: &impl AsType, ) -> Result { - Ok(codetype.literal(oracle(), literal)) + Ok(oracle().find(&as_type.as_type()).literal(literal)) } /// Get the Kotlin syntax for representing a given low-level `FfiType`. diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/object.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/object.rs index 7a1cddbafd..a9c986952c 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/object.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/object.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct ObjectCodeType { id: String, } @@ -15,15 +16,15 @@ impl ObjectCodeType { } impl CodeType for ObjectCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::KotlinCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/primitives.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/primitives.rs index 3edc2cc5d0..f63b441c44 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/primitives.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/primitives.rs @@ -2,11 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal}; +use crate::backend::{CodeType, Literal}; use crate::interface::{types::Type, Radix}; use paste::paste; -fn render_literal(_oracle: &dyn CodeOracle, literal: &Literal) -> String { +fn render_literal(literal: &Literal) -> String { fn typed_number(type_: &Type, num_str: String) -> String { match type_ { // Bytes, Shorts and Ints can all be inferred from the type. @@ -50,15 +50,16 @@ fn render_literal(_oracle: &dyn CodeOracle, literal: &Literal) -> String { macro_rules! impl_code_type_for_primitive { ($T:ty, $class_name:literal) => { paste! { + #[derive(Debug)] pub struct $T; impl CodeType for $T { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { $class_name.into() } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { - render_literal(oracle, &literal) + fn literal(&self, literal: &Literal) -> String { + render_literal(&literal) } } } diff --git a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/record.rs b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/record.rs index f923f102c4..782add2f2a 100644 --- a/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/record.rs +++ b/uniffi_bindgen/src/bindings/kotlin/gen_kotlin/record.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct RecordCodeType { id: String, } @@ -15,15 +16,15 @@ impl RecordCodeType { } impl CodeType for RecordCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::KotlinCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } } diff --git a/uniffi_bindgen/src/bindings/kotlin/templates/ErrorTemplate.kt b/uniffi_bindgen/src/bindings/kotlin/templates/ErrorTemplate.kt index 9ddef9bb73..715cb19d75 100644 --- a/uniffi_bindgen/src/bindings/kotlin/templates/ErrorTemplate.kt +++ b/uniffi_bindgen/src/bindings/kotlin/templates/ErrorTemplate.kt @@ -55,7 +55,7 @@ public object {{ e|ffi_converter_name }} : FfiConverterRustBuffer<{{ type_name } {% if e.is_flat() %} return when(buf.getInt()) { {%- for variant in e.variants() %} - {{ loop.index }} -> {{ type_name }}.{{ variant.name()|exception_name }}({{ TypeIdentifier::String.borrow()|read_fn }}(buf)) + {{ loop.index }} -> {{ type_name }}.{{ variant.name()|exception_name }}({{ Type::String.borrow()|read_fn }}(buf)) {%- endfor %} else -> throw RuntimeException("invalid error enum value, something is very wrong!!") } diff --git a/uniffi_bindgen/src/bindings/kotlin/templates/Helpers.kt b/uniffi_bindgen/src/bindings/kotlin/templates/Helpers.kt index 77648ddcd3..8af881a46c 100644 --- a/uniffi_bindgen/src/bindings/kotlin/templates/Helpers.kt +++ b/uniffi_bindgen/src/bindings/kotlin/templates/Helpers.kt @@ -51,7 +51,7 @@ private fun checkCallStatus(errorHandler: CallStatusErrorHandler 0) { - throw InternalException({{ TypeIdentifier::String.borrow()|lift_fn }}(status.error_buf)) + throw InternalException({{ Type::String.borrow()|lift_fn }}(status.error_buf)) } else { throw InternalException("Rust panic") } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/callback_interface.rs b/uniffi_bindgen/src/bindings/python/gen_python/callback_interface.rs index 74a50553fd..bd04df8d2b 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/callback_interface.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/callback_interface.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct CallbackInterfaceCodeType { id: String, } @@ -15,15 +16,15 @@ impl CallbackInterfaceCodeType { } impl CodeType for CallbackInterfaceCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::PythonCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("CallbackInterface{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/compounds.rs b/uniffi_bindgen/src/bindings/python/gen_python/compounds.rs index 9df0fe558d..dcbbd56a9c 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/compounds.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/compounds.rs @@ -2,61 +2,63 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal, TypeIdentifier}; +use crate::backend::{CodeOracle, CodeType, Literal, Type}; +#[derive(Debug)] pub struct OptionalCodeType { - inner: TypeIdentifier, + inner: Type, } impl OptionalCodeType { - pub fn new(inner: TypeIdentifier) -> Self { + pub fn new(inner: Type) -> Self { Self { inner } } } impl CodeType for OptionalCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.find(&self.inner).type_label(oracle) + fn type_label(&self) -> String { + super::PythonCodeOracle.find(&self.inner).type_label() } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!( "Optional{}", - oracle.find(&self.inner).canonical_name(oracle), + super::PythonCodeOracle.find(&self.inner).canonical_name(), ) } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { match literal { Literal::Null => "None".into(), - _ => oracle.find(&self.inner).literal(oracle, literal), + _ => super::PythonCodeOracle.find(&self.inner).literal(literal), } } } +#[derive(Debug)] pub struct SequenceCodeType { - inner: TypeIdentifier, + inner: Type, } impl SequenceCodeType { - pub fn new(inner: TypeIdentifier) -> Self { + pub fn new(inner: Type) -> Self { Self { inner } } } impl CodeType for SequenceCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { "list".to_string() } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!( "Sequence{}", - oracle.find(&self.inner).canonical_name(oracle), + super::PythonCodeOracle.find(&self.inner).canonical_name(), ) } - fn literal(&self, _oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { match literal { Literal::EmptySequence => "[]".into(), _ => unimplemented!(), @@ -64,31 +66,32 @@ impl CodeType for SequenceCodeType { } } +#[derive(Debug)] pub struct MapCodeType { - key: TypeIdentifier, - value: TypeIdentifier, + key: Type, + value: Type, } impl MapCodeType { - pub fn new(key: TypeIdentifier, value: TypeIdentifier) -> Self { + pub fn new(key: Type, value: Type) -> Self { Self { key, value } } } impl CodeType for MapCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { "dict".to_string() } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!( "Map{}{}", - oracle.find(&self.key).canonical_name(oracle), - oracle.find(&self.value).canonical_name(oracle), + super::PythonCodeOracle.find(&self.key).canonical_name(), + super::PythonCodeOracle.find(&self.value).canonical_name(), ) } - fn literal(&self, _oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { match literal { Literal::EmptyMap => "{}".into(), _ => unimplemented!(), diff --git a/uniffi_bindgen/src/bindings/python/gen_python/custom.rs b/uniffi_bindgen/src/bindings/python/gen_python/custom.rs index 353ce625d2..95d0d4364a 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/custom.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/custom.rs @@ -2,8 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct CustomCodeType { name: String, } @@ -15,11 +16,11 @@ impl CustomCodeType { } impl CodeType for CustomCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { self.name.clone() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.name) } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/enum_.rs b/uniffi_bindgen/src/bindings/python/gen_python/enum_.rs index 941008e370..6bd98513d2 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/enum_.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/enum_.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct EnumCodeType { id: String, } @@ -15,20 +16,20 @@ impl EnumCodeType { } impl CodeType for EnumCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::PythonCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { if let Literal::Enum(v, _) = literal { format!( "{}.{}", - self.type_label(oracle), - oracle.enum_variant_name(v) + self.type_label(), + super::PythonCodeOracle.enum_variant_name(v) ) } else { unreachable!(); diff --git a/uniffi_bindgen/src/bindings/python/gen_python/error.rs b/uniffi_bindgen/src/bindings/python/gen_python/error.rs index 7b6e6db44e..d00104507e 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/error.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/error.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct ErrorCodeType { id: String, } @@ -15,15 +16,15 @@ impl ErrorCodeType { } impl CodeType for ErrorCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::PythonCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/executor.rs b/uniffi_bindgen/src/bindings/python/gen_python/executor.rs index 9616845e85..2834d9e2ac 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/executor.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/executor.rs @@ -2,16 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct ForeignExecutorCodeType; impl CodeType for ForeignExecutorCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { "asyncio.BaseEventLoop".into() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { "ForeignExecutor".into() } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/external.rs b/uniffi_bindgen/src/bindings/python/gen_python/external.rs index b2b599674e..5a07d269fe 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/external.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/external.rs @@ -2,8 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct ExternalCodeType { name: String, } @@ -15,11 +16,11 @@ impl ExternalCodeType { } impl CodeType for ExternalCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { self.name.clone() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.name) } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/miscellany.rs b/uniffi_bindgen/src/bindings/python/gen_python/miscellany.rs index 930927ba60..e43503520e 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/miscellany.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/miscellany.rs @@ -2,24 +2,25 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal}; +use crate::backend::{CodeType, Literal}; use paste::paste; macro_rules! impl_code_type_for_miscellany { ($T:ty, $canonical_name:literal) => { paste! { + #[derive(Debug)] pub struct $T; impl CodeType for $T { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { format!("{}", $canonical_name) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("{}", $canonical_name) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!() } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/mod.rs b/uniffi_bindgen/src/bindings/python/gen_python/mod.rs index 412fe97cb4..eb6445bc63 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/mod.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/mod.rs @@ -11,7 +11,7 @@ use std::borrow::Borrow; use std::cell::RefCell; use std::collections::{BTreeSet, HashMap, HashSet}; -use crate::backend::{CodeOracle, CodeType, TemplateExpression, TypeIdentifier}; +use crate::backend::{CodeOracle, CodeType, TemplateExpression}; use crate::interface::*; use crate::BindingsConfig; @@ -273,7 +273,7 @@ impl PythonCodeOracle { // // - When adding additional types here, make sure to also add a match arm to the `Types.py` template. // - To keep things manageable, let's try to limit ourselves to these 2 mega-matches - fn create_code_type(&self, type_: TypeIdentifier) -> Box { + fn create_code_type(&self, type_: Type) -> Box { match type_ { Type::UInt8 => Box::new(primitives::UInt8CodeType), Type::Int8 => Box::new(primitives::Int8CodeType), @@ -310,7 +310,7 @@ impl PythonCodeOracle { } impl CodeOracle for PythonCodeOracle { - fn find(&self, type_: &TypeIdentifier) -> Box { + fn find(&self, type_: &Type) -> Box { self.create_code_type(type_.clone()) } @@ -384,35 +384,32 @@ pub mod filters { &PythonCodeOracle } - pub fn type_name(codetype: &impl CodeType) -> Result { - let oracle = oracle(); - Ok(codetype.type_label(oracle)) + pub fn type_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).type_label()) } - pub fn ffi_converter_name(codetype: &impl CodeType) -> Result { - let oracle = oracle(); - Ok(codetype.ffi_converter_name(oracle)) + pub fn ffi_converter_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).ffi_converter_name()) } - pub fn canonical_name(codetype: &impl CodeType) -> Result { - let oracle = oracle(); - Ok(codetype.canonical_name(oracle)) + pub fn canonical_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).canonical_name()) } - pub fn lift_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.lift", ffi_converter_name(codetype)?)) + pub fn lift_fn(as_type: &impl AsType) -> Result { + Ok(format!("{}.lift", ffi_converter_name(as_type)?)) } - pub fn lower_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.lower", ffi_converter_name(codetype)?)) + pub fn lower_fn(as_type: &impl AsType) -> Result { + Ok(format!("{}.lower", ffi_converter_name(as_type)?)) } - pub fn read_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.read", ffi_converter_name(codetype)?)) + pub fn read_fn(as_type: &impl AsType) -> Result { + Ok(format!("{}.read", ffi_converter_name(as_type)?)) } - pub fn write_fn(codetype: &impl CodeType) -> Result { - Ok(format!("{}.write", ffi_converter_name(codetype)?)) + pub fn write_fn(as_type: &impl AsType) -> Result { + Ok(format!("{}.write", ffi_converter_name(as_type)?)) } // Name of the callback function we pass to Rust to complete an async call @@ -430,12 +427,8 @@ pub mod filters { )) } - pub fn literal_py( - literal: &Literal, - codetype: &impl CodeType, - ) -> Result { - let oracle = oracle(); - Ok(codetype.literal(oracle, literal)) + pub fn literal_py(literal: &Literal, as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).literal(literal)) } /// Get the Python syntax for representing a given low-level `FfiType`. diff --git a/uniffi_bindgen/src/bindings/python/gen_python/object.rs b/uniffi_bindgen/src/bindings/python/gen_python/object.rs index 7a1cddbafd..6888256181 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/object.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/object.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct ObjectCodeType { id: String, } @@ -15,15 +16,15 @@ impl ObjectCodeType { } impl CodeType for ObjectCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::PythonCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/primitives.rs b/uniffi_bindgen/src/bindings/python/gen_python/primitives.rs index b9dfe4becd..06780da4cf 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/primitives.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/primitives.rs @@ -2,11 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal}; +use crate::backend::{CodeType, Literal}; use crate::interface::Radix; use paste::paste; -fn render_literal(_oracle: &dyn CodeOracle, literal: &Literal) -> String { +fn render_literal(literal: &Literal) -> String { match literal { Literal::Boolean(v) => { if *v { @@ -36,15 +36,15 @@ fn render_literal(_oracle: &dyn CodeOracle, literal: &Literal) -> String { macro_rules! impl_code_type_for_primitive { ($T:ty, $class_name:literal) => { paste! { + #[derive(Debug)] pub struct $T; - impl CodeType for $T { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { $class_name.into() } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { - render_literal(oracle, &literal) + fn literal(&self, literal: &Literal) -> String { + render_literal(&literal) } } } diff --git a/uniffi_bindgen/src/bindings/python/gen_python/record.rs b/uniffi_bindgen/src/bindings/python/gen_python/record.rs index f923f102c4..cd5fe6343f 100644 --- a/uniffi_bindgen/src/bindings/python/gen_python/record.rs +++ b/uniffi_bindgen/src/bindings/python/gen_python/record.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct RecordCodeType { id: String, } @@ -15,15 +16,15 @@ impl RecordCodeType { } impl CodeType for RecordCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::PythonCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, _oracle: &dyn CodeOracle, _literal: &Literal) -> String { + fn literal(&self, _literal: &Literal) -> String { unreachable!(); } } diff --git a/uniffi_bindgen/src/bindings/python/templates/macros.py b/uniffi_bindgen/src/bindings/python/templates/macros.py index 6c826fbfa5..6c84624c58 100644 --- a/uniffi_bindgen/src/bindings/python/templates/macros.py +++ b/uniffi_bindgen/src/bindings/python/templates/macros.py @@ -74,7 +74,7 @@ {%- when None %} {%- when Some with(literal) %} if {{ arg.name()|var_name }} is DEFAULT: - {{ arg.name()|var_name }} = {{ literal|literal_py(arg.type_().borrow()) }} + {{ arg.name()|var_name }} = {{ literal|literal_py(arg.as_type().borrow()) }} {%- endmatch %} {% endfor -%} {%- endmacro -%} @@ -89,7 +89,7 @@ {%- when None %} {%- when Some with(literal) %} if {{ arg.name()|var_name }} is DEFAULT: - {{ arg.name()|var_name }} = {{ literal|literal_py(arg.type_().borrow()) }} + {{ arg.name()|var_name }} = {{ literal|literal_py(arg.as_type().borrow()) }} {%- endmatch %} {% endfor -%} {%- endmacro -%} diff --git a/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb b/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb index b31a206a0c..a9a0b28400 100644 --- a/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb +++ b/uniffi_bindgen/src/bindings/ruby/templates/RustBufferBuilder.rb @@ -171,7 +171,7 @@ def write_{{ canonical_type_name }}(v) if v.{{ variant.name()|var_name_rb }}? pack_into(4, 'l>', {{ loop.index }}) {%- for field in variant.fields() %} - self.write_{{ field.type_().canonical_name().borrow()|class_name_rb }}(v.{{ field.name() }}) + self.write_{{ field.as_type().canonical_name().borrow()|class_name_rb }}(v.{{ field.name() }}) {%- endfor %} end {%- endfor %} @@ -184,7 +184,7 @@ def write_{{ canonical_type_name }}(v) def write_{{ canonical_type_name }}(v) {%- for field in rec.fields() %} - self.write_{{ field.type_().canonical_name().borrow()|class_name_rb }}(v.{{ field.name()|var_name_rb }}) + self.write_{{ field.as_type().canonical_name().borrow()|class_name_rb }}(v.{{ field.name()|var_name_rb }}) {%- endfor %} end diff --git a/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb b/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb index 378036e29f..941a018f78 100644 --- a/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb +++ b/uniffi_bindgen/src/bindings/ruby/templates/RustBufferStream.rb @@ -178,7 +178,7 @@ def read{{ canonical_type_name }} {%- if variant.has_fields() %} return {{ enum_name|class_name_rb }}::{{ variant.name()|enum_name_rb }}.new( {%- for field in variant.fields() %} - self.read{{ field.type_().canonical_name().borrow()|class_name_rb }}(){% if loop.last %}{% else %},{% endif %} + self.read{{ field.as_type().canonical_name().borrow()|class_name_rb }}(){% if loop.last %}{% else %},{% endif %} {%- endfor %} ) {%- else %} @@ -213,7 +213,7 @@ def read{{ canonical_type_name }} {%- if variant.has_fields() %} return {{ error_name|class_name_rb }}::{{ variant.name()|class_name_rb }}.new( {%- for field in variant.fields() %} - read{{ field.type_().canonical_name().borrow()|class_name_rb }}(){% if loop.last %}{% else %},{% endif %} + read{{ field.as_type().canonical_name().borrow()|class_name_rb }}(){% if loop.last %}{% else %},{% endif %} {%- endfor %} ) {%- else %} @@ -233,7 +233,7 @@ def read{{ canonical_type_name }} def read{{ canonical_type_name }} {{ rec.name()|class_name_rb }}.new( {%- for field in rec.fields() %} - read{{ field.type_().canonical_name().borrow()|class_name_rb }}{% if loop.last %}{% else %},{% endif %} + read{{ field.as_type().canonical_name().borrow()|class_name_rb }}{% if loop.last %}{% else %},{% endif %} {%- endfor %} ) end diff --git a/uniffi_bindgen/src/bindings/ruby/templates/macros.rb b/uniffi_bindgen/src/bindings/ruby/templates/macros.rb index c2faf63104..63977f8e67 100644 --- a/uniffi_bindgen/src/bindings/ruby/templates/macros.rb +++ b/uniffi_bindgen/src/bindings/ruby/templates/macros.rb @@ -31,7 +31,7 @@ {%- macro _arg_list_ffi_call(func) %} {%- for arg in func.arguments() %} - {{- arg.name()|lower_rb(arg.type_().borrow()) }} + {{- arg.name()|lower_rb(arg.as_type().borrow()) }} {%- if !loop.last %},{% endif %} {%- endfor %} {%- endmacro -%} @@ -62,12 +62,12 @@ {%- macro coerce_args(func) %} {%- for arg in func.arguments() %} - {{ arg.name() }} = {{ arg.name()|coerce_rb(arg.type_().borrow()) -}} + {{ arg.name() }} = {{ arg.name()|coerce_rb(arg.as_type().borrow()) -}} {% endfor -%} {%- endmacro -%} {%- macro coerce_args_extra_indent(func) %} {%- for arg in func.arguments() %} - {{ arg.name() }} = {{ arg.name()|coerce_rb(arg.type_().borrow()) }} + {{ arg.name() }} = {{ arg.name()|coerce_rb(arg.as_type().borrow()) }} {%- endfor %} {%- endmacro -%} diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/callback_interface.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/callback_interface.rs index 828a8823ee..34eac98bdf 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/callback_interface.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/callback_interface.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType}; +#[derive(Debug)] pub struct CallbackInterfaceCodeType { id: String, } @@ -15,11 +16,11 @@ impl CallbackInterfaceCodeType { } impl CodeType for CallbackInterfaceCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::SwiftCodeOracle.class_name(&self.id) } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { - format!("CallbackInterface{}", self.type_label(oracle)) + fn canonical_name(&self) -> String { + format!("CallbackInterface{}", self.type_label()) } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/compounds.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/compounds.rs index f91be9ce54..13254f1b51 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/compounds.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/compounds.rs @@ -2,58 +2,66 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType, Literal, TypeIdentifier}; +use crate::backend::{CodeOracle, CodeType, Literal, Type}; +#[derive(Debug)] pub struct OptionalCodeType { - inner: TypeIdentifier, + inner: Type, } impl OptionalCodeType { - pub fn new(inner: TypeIdentifier) -> Self { + pub fn new(inner: Type) -> Self { Self { inner } } } impl CodeType for OptionalCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - format!("{}?", oracle.find(&self.inner).type_label(oracle)) + fn type_label(&self) -> String { + format!("{}?", super::SwiftCodeOracle.find(&self.inner).type_label()) } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { - format!("Option{}", oracle.find(&self.inner).canonical_name(oracle)) + fn canonical_name(&self) -> String { + format!( + "Option{}", + super::SwiftCodeOracle.find(&self.inner).canonical_name() + ) } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { match literal { Literal::Null => "nil".into(), - _ => oracle.find(&self.inner).literal(oracle, literal), + _ => super::SwiftCodeOracle.find(&self.inner).literal(literal), } } } +#[derive(Debug)] pub struct SequenceCodeType { - inner: TypeIdentifier, + inner: Type, } impl SequenceCodeType { - pub fn new(inner: TypeIdentifier) -> Self { + pub fn new(inner: Type) -> Self { Self { inner } } } impl CodeType for SequenceCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - format!("[{}]", oracle.find(&self.inner).type_label(oracle)) + fn type_label(&self) -> String { + format!( + "[{}]", + super::SwiftCodeOracle.find(&self.inner).type_label() + ) } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!( "Sequence{}", - oracle.find(&self.inner).canonical_name(oracle) + super::SwiftCodeOracle.find(&self.inner).canonical_name() ) } - fn literal(&self, _oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { match literal { Literal::EmptySequence => "[]".into(), _ => unreachable!(), @@ -61,35 +69,36 @@ impl CodeType for SequenceCodeType { } } +#[derive(Debug)] pub struct MapCodeType { - key: TypeIdentifier, - value: TypeIdentifier, + key: Type, + value: Type, } impl MapCodeType { - pub fn new(key: TypeIdentifier, value: TypeIdentifier) -> Self { + pub fn new(key: Type, value: Type) -> Self { Self { key, value } } } impl CodeType for MapCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { format!( "[{}: {}]", - oracle.find(&self.key).type_label(oracle), - oracle.find(&self.value).type_label(oracle) + super::SwiftCodeOracle.find(&self.key).type_label(), + super::SwiftCodeOracle.find(&self.value).type_label() ) } - fn canonical_name(&self, oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!( "Dictionary{}{}", - oracle.find(&self.key).canonical_name(oracle), - oracle.find(&self.value).canonical_name(oracle) + super::SwiftCodeOracle.find(&self.key).canonical_name(), + super::SwiftCodeOracle.find(&self.value).canonical_name() ) } - fn literal(&self, _oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { match literal { Literal::EmptyMap => "[:]".into(), _ => unreachable!(), diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/custom.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/custom.rs index bf1806e5e2..77569c5485 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/custom.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/custom.rs @@ -2,8 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct CustomCodeType { name: String, } @@ -15,11 +16,11 @@ impl CustomCodeType { } impl CodeType for CustomCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { self.name.clone() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.name) } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/enum_.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/enum_.rs index 04d8422f6a..87deafe6cf 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/enum_.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/enum_.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType, Literal}; +#[derive(Debug)] pub struct EnumCodeType { id: String, } @@ -15,17 +16,17 @@ impl EnumCodeType { } impl CodeType for EnumCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::SwiftCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { + fn literal(&self, literal: &Literal) -> String { if let Literal::Enum(v, _) = literal { - format!(".{}", oracle.enum_variant_name(v)) + format!(".{}", super::SwiftCodeOracle.enum_variant_name(v)) } else { unreachable!(); } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/error.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/error.rs index 4219f24c39..5d9b7cd1ff 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/error.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/error.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType}; +#[derive(Debug)] pub struct ErrorCodeType { id: String, } @@ -15,11 +16,11 @@ impl ErrorCodeType { } impl CodeType for ErrorCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::SwiftCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/executor.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/executor.rs index 3d66ac5e1d..73a373d8d9 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/executor.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/executor.rs @@ -2,21 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct ForeignExecutorCodeType; impl CodeType for ForeignExecutorCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { // On Swift, we define a struct to represent a ForeignExecutor "UniFfiForeignExecutor".into() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { "ForeignExecutor".into() } - fn initialization_fn(&self, _oracle: &dyn CodeOracle) -> Option { + fn initialization_fn(&self) -> Option { Some("uniffiInitForeignExecutor".into()) } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/external.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/external.rs index c9a925cdaa..4cc3ff2707 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/external.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/external.rs @@ -2,8 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct ExternalCodeType { name: String, } @@ -15,21 +16,21 @@ impl ExternalCodeType { } impl CodeType for ExternalCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { self.name.clone() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.name) } // lower and lift need to call public function which were generated for // the original types. - fn lower(&self, oracle: &dyn CodeOracle) -> String { - format!("{}_lower", self.ffi_converter_name(oracle)) + fn lower(&self) -> String { + format!("{}_lower", self.ffi_converter_name()) } - fn lift(&self, oracle: &dyn CodeOracle) -> String { - format!("{}_lift", self.ffi_converter_name(oracle)) + fn lift(&self) -> String { + format!("{}_lift", self.ffi_converter_name()) } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/miscellany.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/miscellany.rs index 4f57734934..9c92b2f162 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/miscellany.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/miscellany.rs @@ -2,28 +2,30 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::backend::{CodeOracle, CodeType}; +use crate::backend::CodeType; +#[derive(Debug)] pub struct TimestampCodeType; impl CodeType for TimestampCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { "Date".into() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { "Timestamp".into() } } +#[derive(Debug)] pub struct DurationCodeType; impl CodeType for DurationCodeType { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { "TimeInterval".into() } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { "Duration".into() } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/mod.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/mod.rs index f78f21ffbe..01441ea297 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/mod.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/mod.rs @@ -12,7 +12,7 @@ use heck::{ToLowerCamelCase, ToUpperCamelCase}; use serde::{Deserialize, Serialize}; use super::Bindings; -use crate::backend::{CodeOracle, CodeType, TemplateExpression, TypeIdentifier}; +use crate::backend::{CodeOracle, CodeType, TemplateExpression}; use crate::interface::*; use crate::BindingsConfig; @@ -267,7 +267,8 @@ impl<'a> SwiftWrapper<'a> { pub fn initialization_fns(&self) -> Vec { self.ci .iter_types() - .filter_map(|t| t.initialization_fn(&SwiftCodeOracle)) + .map(|t| SwiftCodeOracle.find(t)) + .filter_map(|ct| ct.initialization_fn()) .collect() } } @@ -283,7 +284,7 @@ impl SwiftCodeOracle { // // - When adding additional types here, make sure to also add a match arm to the `Types.swift` template. // - To keep things manageable, let's try to limit ourselves to these 2 mega-matches - fn create_code_type(&self, type_: TypeIdentifier) -> Box { + fn create_code_type(&self, type_: Type) -> Box { match type_ { Type::UInt8 => Box::new(primitives::UInt8CodeType), Type::Int8 => Box::new(primitives::Int8CodeType), @@ -320,7 +321,7 @@ impl SwiftCodeOracle { } impl CodeOracle for SwiftCodeOracle { - fn find(&self, type_: &TypeIdentifier) -> Box { + fn find(&self, type_: &Type) -> Box { self.create_code_type(type_.clone()) } @@ -383,42 +384,39 @@ pub mod filters { &SwiftCodeOracle } - pub fn type_name(codetype: &impl CodeType) -> Result { - let oracle = oracle(); - Ok(codetype.type_label(oracle)) + pub fn type_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).type_label()) } - pub fn canonical_name(codetype: &impl CodeType) -> Result { - let oracle = oracle(); - Ok(codetype.canonical_name(oracle)) + pub fn canonical_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).canonical_name()) } - pub fn ffi_converter_name(codetype: &impl CodeType) -> Result { - Ok(codetype.ffi_converter_name(oracle())) + pub fn ffi_converter_name(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).ffi_converter_name()) } - pub fn lower_fn(codetype: &impl CodeType) -> Result { - Ok(codetype.lower(oracle())) + pub fn lower_fn(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).lower()) } - pub fn write_fn(codetype: &impl CodeType) -> Result { - Ok(codetype.write(oracle())) + pub fn write_fn(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).write()) } - pub fn lift_fn(codetype: &impl CodeType) -> Result { - Ok(codetype.lift(oracle())) + pub fn lift_fn(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).lift()) } - pub fn read_fn(codetype: &impl CodeType) -> Result { - Ok(codetype.read(oracle())) + pub fn read_fn(as_type: &impl AsType) -> Result { + Ok(oracle().find(&as_type.as_type()).read()) } pub fn literal_swift( literal: &Literal, - codetype: &impl CodeType, + as_type: &impl AsType, ) -> Result { - let oracle = oracle(); - Ok(codetype.literal(oracle, literal)) + Ok(oracle().find(&as_type.as_type()).literal(literal)) } /// Get the Swift type for an FFIType diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/object.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/object.rs index d227f8e7cd..b08e5c8260 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/object.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/object.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType}; +#[derive(Debug)] pub struct ObjectCodeType { id: String, } @@ -15,11 +16,11 @@ impl ObjectCodeType { } impl CodeType for ObjectCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::SwiftCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/primitives.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/primitives.rs index 0b58a4fe68..239bc23b14 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/primitives.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/primitives.rs @@ -6,8 +6,8 @@ use crate::backend::{CodeOracle, CodeType, Literal}; use crate::interface::{types::Type, Radix}; use paste::paste; -fn render_literal(oracle: &dyn CodeOracle, literal: &Literal) -> String { - fn typed_number(oracle: &dyn CodeOracle, type_: &Type, num_str: String) -> String { +fn render_literal(literal: &Literal) -> String { + fn typed_number(type_: &Type, num_str: String) -> String { match type_ { // special case Int32. Type::Int32 => num_str, @@ -23,7 +23,10 @@ fn render_literal(oracle: &dyn CodeOracle, literal: &Literal) -> String { | Type::Float64 => // XXX we should pass in the codetype itself. { - format!("{}({num_str})", oracle.find(type_).type_label(oracle)) + format!( + "{}({num_str})", + super::SwiftCodeOracle.find(type_).type_label() + ) } _ => panic!("Unexpected literal: {num_str} is not a number"), } @@ -33,7 +36,6 @@ fn render_literal(oracle: &dyn CodeOracle, literal: &Literal) -> String { Literal::Boolean(v) => format!("{v}"), Literal::String(s) => format!("\"{s}\""), Literal::Int(i, radix, type_) => typed_number( - oracle, type_, match radix { Radix::Octal => format!("0o{i:o}"), @@ -42,7 +44,6 @@ fn render_literal(oracle: &dyn CodeOracle, literal: &Literal) -> String { }, ), Literal::UInt(i, radix, type_) => typed_number( - oracle, type_, match radix { Radix::Octal => format!("0o{i:o}"), @@ -50,7 +51,7 @@ fn render_literal(oracle: &dyn CodeOracle, literal: &Literal) -> String { Radix::Hexadecimal => format!("{i:#x}"), }, ), - Literal::Float(string, type_) => typed_number(oracle, type_, string.clone()), + Literal::Float(string, type_) => typed_number(type_, string.clone()), _ => unreachable!("Literal"), } } @@ -58,15 +59,16 @@ fn render_literal(oracle: &dyn CodeOracle, literal: &Literal) -> String { macro_rules! impl_code_type_for_primitive { ($T:ty, $class_name:literal) => { paste! { + #[derive(Debug)] pub struct $T; impl CodeType for $T { - fn type_label(&self, _oracle: &dyn CodeOracle) -> String { + fn type_label(&self) -> String { $class_name.into() } - fn literal(&self, oracle: &dyn CodeOracle, literal: &Literal) -> String { - render_literal(oracle, &literal) + fn literal(&self, literal: &Literal) -> String { + render_literal(&literal) } } } diff --git a/uniffi_bindgen/src/bindings/swift/gen_swift/record.rs b/uniffi_bindgen/src/bindings/swift/gen_swift/record.rs index 0943bcaada..44d686dee6 100644 --- a/uniffi_bindgen/src/bindings/swift/gen_swift/record.rs +++ b/uniffi_bindgen/src/bindings/swift/gen_swift/record.rs @@ -4,6 +4,7 @@ use crate::backend::{CodeOracle, CodeType}; +#[derive(Debug)] pub struct RecordCodeType { id: String, } @@ -15,11 +16,11 @@ impl RecordCodeType { } impl CodeType for RecordCodeType { - fn type_label(&self, oracle: &dyn CodeOracle) -> String { - oracle.class_name(&self.id) + fn type_label(&self) -> String { + super::SwiftCodeOracle.class_name(&self.id) } - fn canonical_name(&self, _oracle: &dyn CodeOracle) -> String { + fn canonical_name(&self) -> String { format!("Type{}", self.id) } } diff --git a/uniffi_bindgen/src/interface/callbacks.rs b/uniffi_bindgen/src/interface/callbacks.rs index 636065f604..8313f87256 100644 --- a/uniffi_bindgen/src/interface/callbacks.rs +++ b/uniffi_bindgen/src/interface/callbacks.rs @@ -39,7 +39,7 @@ use uniffi_meta::Checksum; use super::ffi::{FfiArgument, FfiFunction, FfiType}; use super::object::Method; use super::types::{ObjectImpl, Type, TypeIterator}; -use super::{APIConverter, ComponentInterface}; +use super::{APIConverter, AsType, ComponentInterface}; #[derive(Debug, Clone, Checksum)] pub struct CallbackInterface { @@ -68,10 +68,6 @@ impl CallbackInterface { &self.name } - pub fn type_(&self) -> Type { - Type::CallbackInterface(self.name.clone()) - } - pub fn methods(&self) -> Vec<&Method> { self.methods.iter().collect() } @@ -95,6 +91,12 @@ impl CallbackInterface { } } +impl AsType for CallbackInterface { + fn as_type(&self) -> Type { + Type::CallbackInterface(self.name.clone()) + } +} + impl APIConverter for weedle::CallbackInterfaceDefinition<'_> { fn convert(&self, ci: &mut ComponentInterface) -> Result { if self.attributes.is_some() { diff --git a/uniffi_bindgen/src/interface/enum_.rs b/uniffi_bindgen/src/interface/enum_.rs index 74998517d2..9c627c859e 100644 --- a/uniffi_bindgen/src/interface/enum_.rs +++ b/uniffi_bindgen/src/interface/enum_.rs @@ -81,7 +81,7 @@ use uniffi_meta::Checksum; use super::record::Field; use super::types::{Type, TypeIterator}; -use super::{APIConverter, ComponentInterface}; +use super::{APIConverter, AsType, ComponentInterface}; /// Represents an enum with named variants, each of which may have named /// and typed fields. @@ -117,12 +117,6 @@ impl Enum { &self.name } - pub fn type_(&self) -> Type { - // *sigh* at the clone here, the relationship between a ComponentInterface - // and its contained types could use a bit of a cleanup. - Type::Enum(self.name.clone()) - } - pub fn variants(&self) -> &[Variant] { &self.variants } @@ -136,6 +130,12 @@ impl Enum { } } +impl AsType for Enum { + fn as_type(&self) -> Type { + Type::Enum(self.name.clone()) + } +} + impl TryFrom for Enum { type Error = anyhow::Error; @@ -399,9 +399,9 @@ mod test { ed.variants()[1] .fields() .iter() - .map(|f| f.type_()) + .map(|f| f.as_type()) .collect::>(), - vec![&Type::UInt32] + vec![Type::UInt32] ); assert_eq!( ed.variants()[2] @@ -415,9 +415,9 @@ mod test { ed.variants()[2] .fields() .iter() - .map(|f| f.type_()) + .map(|f| f.as_type()) .collect::>(), - vec![&Type::UInt32, &Type::String] + vec![Type::UInt32, Type::String] ); // The enum declared via interface, but with no associated data. @@ -435,7 +435,7 @@ mod test { // (It might be nice to optimize these to pass as plain integers, but that's // difficult atop the current factoring of `ComponentInterface` and friends). let farg = ci.get_function_definition("takes_an_enum").unwrap(); - assert_eq!(*farg.arguments()[0].type_(), Type::Enum("TestEnum".into())); + assert_eq!(farg.arguments()[0].as_type(), Type::Enum("TestEnum".into())); assert_eq!( farg.ffi_func().arguments()[0].type_(), FfiType::RustBuffer(None) @@ -452,7 +452,7 @@ mod test { .get_function_definition("takes_an_enum_with_data") .unwrap(); assert_eq!( - *farg.arguments()[0].type_(), + farg.arguments()[0].as_type(), Type::Enum("TestEnumWithData".into()) ); assert_eq!( diff --git a/uniffi_bindgen/src/interface/error.rs b/uniffi_bindgen/src/interface/error.rs index 26c695a659..45e2540659 100644 --- a/uniffi_bindgen/src/interface/error.rs +++ b/uniffi_bindgen/src/interface/error.rs @@ -87,7 +87,7 @@ use uniffi_meta::Checksum; use super::enum_::{Enum, Variant}; use super::types::{Type, TypeIterator}; -use super::{APIConverter, ComponentInterface}; +use super::{APIConverter, AsType, ComponentInterface}; /// Represents an Error that might be thrown by functions/methods in the component interface. /// @@ -108,12 +108,6 @@ impl Error { } } - pub fn type_(&self) -> Type { - // *sigh* at the clone here, the relationship between a ComponentInterface - // and its contained types could use a bit of a cleanup. - Type::Error(self.name.clone()) - } - pub fn name(&self) -> &str { &self.name } @@ -135,6 +129,12 @@ impl Error { } } +impl AsType for Error { + fn as_type(&self) -> Type { + Type::Error(self.name.clone()) + } +} + impl TryFrom for Error { type Error = anyhow::Error; diff --git a/uniffi_bindgen/src/interface/function.rs b/uniffi_bindgen/src/interface/function.rs index f15c6353f0..c8f06609dd 100644 --- a/uniffi_bindgen/src/interface/function.rs +++ b/uniffi_bindgen/src/interface/function.rs @@ -40,7 +40,7 @@ use super::attributes::{ArgumentAttributes, Attribute, FunctionAttributes}; use super::ffi::{FfiArgument, FfiFunction, FfiType}; use super::literal::{convert_default_value, Literal}; use super::types::{ObjectImpl, Type, TypeIterator}; -use super::{convert_type, APIConverter, ComponentInterface}; +use super::{convert_type, APIConverter, AsType, ComponentInterface}; /// Represents a standalone function. /// @@ -224,10 +224,6 @@ impl Argument { &self.name } - pub fn type_(&self) -> &Type { - &self.type_ - } - pub fn by_ref(&self) -> bool { self.by_ref } @@ -245,6 +241,12 @@ impl Argument { } } +impl AsType for Argument { + fn as_type(&self) -> Type { + self.type_.clone() + } +} + impl From<&Argument> for FfiArgument { fn from(a: &Argument) -> FfiArgument { FfiArgument { @@ -376,10 +378,10 @@ mod test { assert!(matches!(func2.throws_type(), Some(Type::Error(s)) if s == "TestError")); assert_eq!(func2.arguments().len(), 2); assert_eq!(func2.arguments()[0].name(), "arg1"); - assert_eq!(func2.arguments()[0].type_().canonical_name(), "u32"); + assert_eq!(func2.arguments()[0].as_type().canonical_name(), "u32"); assert_eq!(func2.arguments()[1].name(), "arg2"); assert_eq!( - func2.arguments()[1].type_().canonical_name(), + func2.arguments()[1].as_type().canonical_name(), "TypeTestDict" ); Ok(()) diff --git a/uniffi_bindgen/src/interface/mod.rs b/uniffi_bindgen/src/interface/mod.rs index bbe1ee3fd8..b5085d6863 100644 --- a/uniffi_bindgen/src/interface/mod.rs +++ b/uniffi_bindgen/src/interface/mod.rs @@ -53,7 +53,7 @@ use std::{ use anyhow::{bail, ensure, Result}; pub mod types; -pub use types::{ExternalKind, ObjectImpl, Type}; +pub use types::{AsType, ExternalKind, ObjectImpl, Type}; use types::{TypeIterator, TypeUniverse}; mod attributes; @@ -246,7 +246,7 @@ impl ComponentInterface { .callback_interface_definitions() .iter() .flat_map(|cb| cb.methods()) - .any(|m| m.throws_type() == Some(error.type_())); + .any(|m| m.throws_type() == Some(error.as_type())); fielded || used_in_callback_interface } @@ -597,7 +597,7 @@ impl ComponentInterface { Entry::Vacant(v) => { for variant in defn.variants() { for field in variant.fields() { - self.types.add_known_type(field.type_())?; + self.types.add_known_type(&field.as_type())?; } } v.insert(defn); @@ -623,7 +623,7 @@ impl ComponentInterface { match self.records.entry(defn.name().to_owned()) { Entry::Vacant(v) => { for field in defn.fields() { - self.types.add_known_type(field.type_())?; + self.types.add_known_type(&field.as_type())?; } v.insert(defn); } diff --git a/uniffi_bindgen/src/interface/object.rs b/uniffi_bindgen/src/interface/object.rs index f7e4fdb339..c15f1a1b34 100644 --- a/uniffi_bindgen/src/interface/object.rs +++ b/uniffi_bindgen/src/interface/object.rs @@ -67,7 +67,7 @@ use super::attributes::{Attribute, ConstructorAttributes, InterfaceAttributes, M use super::ffi::{FfiArgument, FfiFunction, FfiType}; use super::function::{Argument, Callable}; use super::types::{ObjectImpl, Type, TypeIterator}; -use super::{convert_type, APIConverter, ComponentInterface}; +use super::{convert_type, APIConverter, AsType, ComponentInterface}; /// An "object" is an opaque type that is passed around by reference, can /// have methods called on it, and so on - basically your classic Object Oriented Programming @@ -131,13 +131,6 @@ impl Object { &self.imp } - pub fn type_(&self) -> Type { - Type::Object { - name: self.name.clone(), - imp: self.imp, - } - } - pub fn constructors(&self) -> Vec<&Constructor> { self.constructors.iter().collect() } @@ -348,6 +341,15 @@ impl APIConverter for weedle::InterfaceDefinition<'_> { } } +impl AsType for Object { + fn as_type(&self) -> Type { + Type::Object { + name: self.name.clone(), + imp: self.imp, + } + } +} + // Represents a constructor for an object type. // // In the FFI, this will be a function that returns a pointer to an instance diff --git a/uniffi_bindgen/src/interface/record.rs b/uniffi_bindgen/src/interface/record.rs index a3b75871ad..2d176bfa06 100644 --- a/uniffi_bindgen/src/interface/record.rs +++ b/uniffi_bindgen/src/interface/record.rs @@ -52,7 +52,7 @@ use super::{ convert_type, literal::{convert_default_value, Literal}, }; -use super::{APIConverter, ComponentInterface}; +use super::{APIConverter, AsType, ComponentInterface}; /// Represents a "data class" style object, for passing around complex values. /// @@ -70,12 +70,6 @@ impl Record { &self.name } - pub fn type_(&self) -> Type { - // *sigh* at the clone here, the relationship between a ComponentInterface - // and its contained types could use a bit of a cleanup. - Type::Record(self.name.clone()) - } - pub fn fields(&self) -> &[Field] { &self.fields } @@ -85,6 +79,12 @@ impl Record { } } +impl AsType for Record { + fn as_type(&self) -> Type { + Type::Record(self.name.clone()) + } +} + impl TryFrom for Record { type Error = anyhow::Error; @@ -128,10 +128,6 @@ impl Field { &self.name } - pub fn type_(&self) -> &Type { - &self.type_ - } - pub fn default_value(&self) -> Option<&Literal> { self.default.as_ref() } @@ -141,6 +137,12 @@ impl Field { } } +impl AsType for Field { + fn as_type(&self) -> Type { + self.type_.clone() + } +} + impl TryFrom for Field { type Error = anyhow::Error; @@ -207,7 +209,7 @@ mod test { assert_eq!(record.name(), "Simple"); assert_eq!(record.fields().len(), 1); assert_eq!(record.fields()[0].name(), "field"); - assert_eq!(record.fields()[0].type_().canonical_name(), "u32"); + assert_eq!(record.fields()[0].as_type().canonical_name(), "u32"); assert!(record.fields()[0].default_value().is_none()); let record = ci.get_record_definition("Complex").unwrap(); @@ -215,18 +217,18 @@ mod test { assert_eq!(record.fields().len(), 3); assert_eq!(record.fields()[0].name(), "key"); assert_eq!( - record.fields()[0].type_().canonical_name(), + record.fields()[0].as_type().canonical_name(), "Optionalstring" ); assert!(record.fields()[0].default_value().is_none()); assert_eq!(record.fields()[1].name(), "value"); - assert_eq!(record.fields()[1].type_().canonical_name(), "u32"); + assert_eq!(record.fields()[1].as_type().canonical_name(), "u32"); assert!(matches!( record.fields()[1].default_value(), Some(Literal::UInt(0, Radix::Decimal, Type::UInt32)) )); assert_eq!(record.fields()[2].name(), "spin"); - assert_eq!(record.fields()[2].type_().canonical_name(), "bool"); + assert_eq!(record.fields()[2].as_type().canonical_name(), "bool"); assert!(record.fields()[2].default_value().is_none()); } diff --git a/uniffi_bindgen/src/interface/types/finder.rs b/uniffi_bindgen/src/interface/types/finder.rs index 80efde7882..6ee94f0abf 100644 --- a/uniffi_bindgen/src/interface/types/finder.rs +++ b/uniffi_bindgen/src/interface/types/finder.rs @@ -22,7 +22,7 @@ use std::convert::TryFrom; use anyhow::{bail, Result}; use super::super::attributes::{EnumAttributes, InterfaceAttributes, TypedefAttributes}; -use super::{Type, TypeUniverse}; +use super::{AsType, Type, TypeUniverse}; /// Trait to help with an early "type discovery" phase when processing the UDL. /// @@ -66,7 +66,7 @@ impl TypeFinder for weedle::InterfaceDefinition<'_> { types.add_type_definition(self.identifier.0, Type::Error(name)) } else { let obj = crate::interface::Object::new(name, attrs.object_impl()); - types.add_type_definition(self.identifier.0, obj.type_()) + types.add_type_definition(self.identifier.0, obj.as_type()) } } } diff --git a/uniffi_bindgen/src/interface/types/mod.rs b/uniffi_bindgen/src/interface/types/mod.rs index 65d1c919ea..52f4cfd6d9 100644 --- a/uniffi_bindgen/src/interface/types/mod.rs +++ b/uniffi_bindgen/src/interface/types/mod.rs @@ -252,6 +252,28 @@ impl From<&&Type> for FfiType { } } +// A trait so various things can turn into a type. +pub trait AsType: core::fmt::Debug { + fn as_type(&self) -> Type; +} + +impl AsType for Type { + fn as_type(&self) -> Type { + self.clone() + } +} + +// Needed to handle &&Type and &&&Type values, which we sometimes end up with in the template code +impl AsType for T +where + T: std::ops::Deref + std::fmt::Debug, + C: AsType, +{ + fn as_type(&self) -> Type { + self.deref().as_type() + } +} + /// The set of all possible types used in a particular component interface. /// /// Every component API uses a finite number of types, including primitive types, API-defined diff --git a/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs b/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs index 1e193ce52d..ec5405c893 100644 --- a/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs +++ b/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs @@ -63,7 +63,7 @@ impl r#{{ trait_name }} for {{ trait_impl }} { let mut args_buf = Vec::new(); {% endif -%} {%- for arg in meth.arguments() %} - {{ arg.type_().borrow()|ffi_converter }}::write(r#{{ arg.name() }}, &mut args_buf); + {{ arg.as_type().borrow()|ffi_converter }}::write(r#{{ arg.name() }}, &mut args_buf); {%- endfor -%} let args_rbuf = uniffi::RustBuffer::from_vec(args_buf); diff --git a/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs b/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs index 223be542b8..2a0a80e556 100644 --- a/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs +++ b/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs @@ -12,7 +12,7 @@ enum r#{{ e.name() }} { {%- for variant in e.variants() %} r#{{ variant.name() }} { {%- for field in variant.fields() %} - r#{{ field.name() }}: {{ field.type_()|type_rs }}, + r#{{ field.name() }}: {{ field.as_type().borrow()|type_rs }}, {%- endfor %} }, {%- endfor %} diff --git a/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs b/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs index 1aac82d2a5..f0cf1e61b7 100644 --- a/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs +++ b/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs @@ -20,7 +20,7 @@ enum r#{{ e.name() }} { {%- for variant in e.variants() %} r#{{ variant.name() }} { {%- for field in variant.fields() %} - r#{{ field.name() }}: {{ field.type_()|type_rs }}, + r#{{ field.name() }}: {{ field.as_type().borrow()|type_rs }}, {%- endfor %} }, {%- endfor %} diff --git a/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs b/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs index d80ce41d0a..a85affa163 100644 --- a/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs +++ b/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs @@ -11,6 +11,6 @@ #[::uniffi::ffi_converter_record(tag = crate::UniFfiTag)] struct r#{{ rec.name() }} { {%- for field in rec.fields() %} - r#{{ field.name() }}: {{ field.type_()|type_rs }}, + r#{{ field.name() }}: {{ field.as_type().borrow()|type_rs }}, {%- endfor %} } diff --git a/uniffi_bindgen/src/scaffolding/templates/macros.rs b/uniffi_bindgen/src/scaffolding/templates/macros.rs index c97d82765c..67c19b0476 100644 --- a/uniffi_bindgen/src/scaffolding/templates/macros.rs +++ b/uniffi_bindgen/src/scaffolding/templates/macros.rs @@ -8,7 +8,7 @@ r#{{ func.name() }}({% call _arg_list_rs_call(func) -%}) {%- macro _arg_list_rs_call(func) %} {%- for arg in func.full_arguments() %} - match {{- arg.type_().borrow()|ffi_converter }}::try_lift(r#{{ arg.name() }}) { + match {{- arg.as_type().borrow()|ffi_converter }}::try_lift(r#{{ arg.name() }}) { {%- if arg.by_ref() %} {# args passed by reference get special treatment for traits and their Box<> #} {%- if arg.is_trait_ref() %} @@ -51,7 +51,7 @@ r#{{ func.name() }}({% call _arg_list_rs_call(func) -%}) {{- prefix -}} {%- if meth.arguments().len() > 0 %}, {# whitespace #} {%- for arg in meth.arguments() %} - r#{{- arg.name() }}: {{ arg.type_().borrow()|type_rs -}}{% if loop.last %}{% else %},{% endif %} + r#{{- arg.name() }}: {{ arg.as_type().borrow()|type_rs -}}{% if loop.last %}{% else %},{% endif %} {%- endfor %} {%- endif %} {%- endmacro -%}