From 82ab6d7aaad72182a22ed5a9788751c202485d6a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 14:42:38 -0800 Subject: [PATCH 01/16] Use namespaced types in cpp2 --- tool/src/cpp2/formatter.rs | 21 +++++++++++++++++---- tool/src/cpp2/ty.rs | 17 +++++++++++++++++ tool/templates/cpp2/enum_decl.h.jinja | 13 +++++++++---- tool/templates/cpp2/enum_impl.h.jinja | 2 +- tool/templates/cpp2/opaque_decl.h.jinja | 20 +++++++++++++------- tool/templates/cpp2/struct_decl.h.jinja | 9 +++++++-- 6 files changed, 64 insertions(+), 18 deletions(-) diff --git a/tool/src/cpp2/formatter.rs b/tool/src/cpp2/formatter.rs index ab60f639a..74665dd65 100644 --- a/tool/src/cpp2/formatter.rs +++ b/tool/src/cpp2/formatter.rs @@ -24,8 +24,8 @@ impl<'tcx> Cpp2Formatter<'tcx> { } } - /// Resolve and format a named type for use in code - pub fn fmt_type_name(&self, id: TypeId) -> Cow<'tcx, str> { + /// Resolve and format a named type for use in code (without the namespace) + pub fn fmt_type_name_unnamespaced(&self, id: TypeId) -> Cow<'tcx, str> { let resolved = self.c.tcx().resolve_type(id); resolved @@ -33,6 +33,19 @@ impl<'tcx> Cpp2Formatter<'tcx> { .rename .apply(resolved.name().as_str().into()) } + /// Resolve and format a named type for use in code + pub fn fmt_type_name(&self, id: TypeId) -> Cow<'tcx, str> { + let resolved = self.c.tcx().resolve_type(id); + let name = resolved + .attrs() + .rename + .apply(resolved.name().as_str().into()); + if let Some(ref ns) = resolved.attrs().namespace { + format!("{ns}::{name}").into() + } else { + name + } + } /// Resolve and format a named type for use in diagnostics /// (don't apply rename rules and such) @@ -42,12 +55,12 @@ impl<'tcx> Cpp2Formatter<'tcx> { /// Resolve and format the name of a type for use in header names pub fn fmt_decl_header_path(&self, id: TypeId) -> String { - let type_name = self.fmt_type_name(id); + let type_name = self.fmt_type_name_unnamespaced(id); format!("{type_name}.d.hpp") } /// Resolve and format the name of a type for use in header names pub fn fmt_impl_header_path(&self, id: TypeId) -> String { - let type_name = self.fmt_type_name(id); + let type_name = self.fmt_type_name_unnamespaced(id); format!("{type_name}.hpp") } diff --git a/tool/src/cpp2/ty.rs b/tool/src/cpp2/ty.rs index 6492efb3a..a81613ea4 100644 --- a/tool/src/cpp2/ty.rs +++ b/tool/src/cpp2/ty.rs @@ -118,6 +118,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { /// cannot be added to it. pub fn gen_enum_def(&mut self, ty: &'tcx hir::EnumDef, id: TypeId) { let type_name = self.cx.formatter.fmt_type_name(id); + let type_name_unnamespaced = self.cx.formatter.fmt_type_name_unnamespaced(id); let ctype = self.cx.formatter.fmt_c_type_name(id); let methods = ty @@ -134,6 +135,8 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &'a str, ctype: &'a str, methods: &'a [MethodInfo<'a>], + namespace: Option<&'a str>, + type_name_unnamespaced: &'a str, } DeclTemplate { @@ -142,6 +145,8 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &type_name, ctype: &ctype, methods: methods.as_slice(), + namespace: ty.attrs.namespace.as_ref().map(|x| &**x), + type_name_unnamespaced: &type_name_unnamespaced, } .render_into(self.decl_header) .unwrap(); @@ -154,6 +159,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &'a str, ctype: &'a str, methods: &'a [MethodInfo<'a>], + type_name_unnamespaced: &'a str, } ImplTemplate { @@ -162,6 +168,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &type_name, ctype: &ctype, methods: methods.as_slice(), + type_name_unnamespaced: &type_name_unnamespaced, } .render_into(self.impl_header) .unwrap(); @@ -173,6 +180,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { pub fn gen_opaque_def(&mut self, ty: &'tcx hir::OpaqueDef, id: TypeId) { let type_name = self.cx.formatter.fmt_type_name(id); + let type_name_unnamespaced = self.cx.formatter.fmt_type_name_unnamespaced(id); let ctype = self.cx.formatter.fmt_c_type_name(id); let dtor_name = self.cx.formatter.fmt_c_dtor_name(id); @@ -190,6 +198,8 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &'a str, ctype: &'a str, methods: &'a [MethodInfo<'a>], + namespace: Option<&'a str>, + type_name_unnamespaced: &'a str, } DeclTemplate { @@ -198,6 +208,8 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &type_name, ctype: &ctype, methods: methods.as_slice(), + namespace: ty.attrs.namespace.as_ref().map(|x| &**x), + type_name_unnamespaced: &type_name_unnamespaced, } .render_into(self.decl_header) .unwrap(); @@ -231,6 +243,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { pub fn gen_struct_def(&mut self, def: &'tcx hir::StructDef

, id: TypeId) { let type_name = self.cx.formatter.fmt_type_name(id); + let type_name_unnamespaced = self.cx.formatter.fmt_type_name_unnamespaced(id); let ctype = self.cx.formatter.fmt_c_type_name(id); let field_decls = def @@ -266,6 +279,8 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { ctype: &'a str, fields: &'a [NamedType<'a>], methods: &'a [MethodInfo<'a>], + namespace: Option<&'a str>, + type_name_unnamespaced: &'a str, } DeclTemplate { @@ -275,6 +290,8 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { ctype: &ctype, fields: field_decls.as_slice(), methods: methods.as_slice(), + namespace: def.attrs.namespace.as_ref().map(|x| &**x), + type_name_unnamespaced: &type_name_unnamespaced, } .render_into(self.decl_header) .unwrap(); diff --git a/tool/templates/cpp2/enum_decl.h.jinja b/tool/templates/cpp2/enum_decl.h.jinja index 3bb1be249..64a818d75 100644 --- a/tool/templates/cpp2/enum_decl.h.jinja +++ b/tool/templates/cpp2/enum_decl.h.jinja @@ -1,4 +1,7 @@ -class {{type_name}} { +{%- if let Some(ns) = namespace -%} +namespace {{ns}} { +{%endif-%} +class {{type_name_unnamespaced}} { {{ctype}} value; public: @@ -13,11 +16,13 @@ public: {% include "method_decl.h.jinja" %} {%- endfor %} - inline {{type_name}}({{type_name}}::Value cpp_value); - inline {{type_name}}({{ctype}} c_enum) : value(c_enum) {}; + inline {{type_name_unnamespaced}}({{type_name}}::Value cpp_value); + inline {{type_name_unnamespaced}}({{ctype}} c_enum) : value(c_enum) {}; inline {{ctype}} AsFFI() const; inline static {{type_name}} FromFFI({{ctype}} c_enum); }; - +{% if namespace.is_some() -%} +} +{%-endif%} diff --git a/tool/templates/cpp2/enum_impl.h.jinja b/tool/templates/cpp2/enum_impl.h.jinja index 99e68247a..0bab18cb9 100644 --- a/tool/templates/cpp2/enum_impl.h.jinja +++ b/tool/templates/cpp2/enum_impl.h.jinja @@ -1,4 +1,4 @@ -inline {{type_name}}::{{type_name}}({{type_name}}::Value cpp_value) { +inline {{type_name}}::{{type_name_unnamespaced}}({{type_name}}::Value cpp_value) { switch (cpp_value) { {%- for enum_variant in ty.variants %} case {{fmt.fmt_enum_variant(enum_variant)}}: diff --git a/tool/templates/cpp2/opaque_decl.h.jinja b/tool/templates/cpp2/opaque_decl.h.jinja index fbf7fc7f0..d6c154916 100644 --- a/tool/templates/cpp2/opaque_decl.h.jinja +++ b/tool/templates/cpp2/opaque_decl.h.jinja @@ -5,7 +5,11 @@ {% let const_ref = fmt.fmt_borrowed(type_name, Mutability::Immutable) -%} {% let move_ref = fmt.fmt_move_ref(type_name) -%} -class {{type_name}} { +{%- if let Some(ns) = namespace -%} +namespace {{ns}} { +{%endif-%} + +class {{type_name_unnamespaced}} { public: {% for m in methods %} {% include "method_decl.h.jinja" %} @@ -16,12 +20,14 @@ public: inline static {{mut_ptr}} FromFFI({{mut_cptr}} ptr); inline static void operator delete(void* ptr); private: - {{type_name}}() = delete; - {{type_name}}({{const_ref}}) = delete; - {{type_name}}({{move_ref}}) noexcept = delete; - {{type_name}} operator=({{const_ref}}) = delete; - {{type_name}} operator=({{move_ref}}) noexcept = delete; + {{type_name_unnamespaced}}() = delete; + {{type_name_unnamespaced}}({{const_ref}}) = delete; + {{type_name_unnamespaced}}({{move_ref}}) noexcept = delete; + {{type_name_unnamespaced}} operator=({{const_ref}}) = delete; + {{type_name_unnamespaced}} operator=({{move_ref}}) noexcept = delete; static void operator delete[](void*, size_t) = delete; }; - +{% if namespace.is_some() -%} +} +{%-endif%} diff --git a/tool/templates/cpp2/struct_decl.h.jinja b/tool/templates/cpp2/struct_decl.h.jinja index 326cbd161..1c2391019 100644 --- a/tool/templates/cpp2/struct_decl.h.jinja +++ b/tool/templates/cpp2/struct_decl.h.jinja @@ -1,4 +1,7 @@ -struct {{type_name}} { +{%- if let Some(ns) = namespace -%} +namespace {{ns}} { +{%endif-%} +struct {{type_name_unnamespaced}} { {%- for field in fields %} {{field.type_name}} {{field.var_name}}; {%- endfor %} @@ -9,4 +12,6 @@ struct {{type_name}} { inline static {{type_name}} FromFFI({{ctype}} c_struct); }; - +{% if namespace.is_some() -%} +} +{%-endif%} From e3bc9c7a9fc74639549f06c69440e7a00a5d2601 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 14:44:26 -0800 Subject: [PATCH 02/16] test --- feature_tests/src/attrs.rs | 1 + tool/src/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/feature_tests/src/attrs.rs b/feature_tests/src/attrs.rs index 22ff068a0..91f3cb94e 100644 --- a/feature_tests/src/attrs.rs +++ b/feature_tests/src/attrs.rs @@ -1,6 +1,7 @@ #[diplomat::bridge] #[diplomat::abi_rename = "namespace_{0}"] #[diplomat::attr(cpp2, rename = "CPPRenamed{0}")] +#[diplomat::attr(cpp2, namespace = "ns")] pub mod ffi { #[diplomat::opaque] #[diplomat::attr(cpp2, rename = "AttrOpaque1Renamed")] diff --git a/tool/src/lib.rs b/tool/src/lib.rs index d9e50f6d5..5952495f3 100644 --- a/tool/src/lib.rs +++ b/tool/src/lib.rs @@ -124,6 +124,8 @@ pub fn gen( // C backends cannot rename types using backend attributes // In the future we may add a c_rename attribute attr_validator.support.renaming = true; + + attr_validator.support.namespacing = true; } attr_validator.support.disabling = true; From 6b23683919c3a87918d4644d12426d7d3ad33a44 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 15:02:40 -0800 Subject: [PATCH 03/16] regen --- .../cpp2/include/AttrOpaque1Renamed.d.hpp | 17 +++++++------- .../cpp2/include/AttrOpaque1Renamed.hpp | 22 +++++++++---------- .../cpp2/include/CPPRenamedAttrEnum.d.hpp | 7 +++--- .../cpp2/include/CPPRenamedAttrEnum.hpp | 8 +++---- feature_tests/cpp2/tests/attrs.cpp | 4 ++-- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp index 0c34387af..e9082bed2 100644 --- a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp +++ b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp @@ -11,10 +11,11 @@ #include "AttrOpaque1.d.h" +namespace ns { class AttrOpaque1Renamed { public: - inline static std::unique_ptr totally_not_new(); + inline static std::unique_ptr totally_not_new(); inline uint8_t method_renamed() const; @@ -22,17 +23,17 @@ class AttrOpaque1Renamed { inline const capi::AttrOpaque1* AsFFI() const; inline capi::AttrOpaque1* AsFFI(); - inline static const AttrOpaque1Renamed* FromFFI(const capi::AttrOpaque1* ptr); - inline static AttrOpaque1Renamed* FromFFI(capi::AttrOpaque1* ptr); + inline static const ns::AttrOpaque1Renamed* FromFFI(const capi::AttrOpaque1* ptr); + inline static ns::AttrOpaque1Renamed* FromFFI(capi::AttrOpaque1* ptr); inline static void operator delete(void* ptr); private: AttrOpaque1Renamed() = delete; - AttrOpaque1Renamed(const AttrOpaque1Renamed&) = delete; - AttrOpaque1Renamed(AttrOpaque1Renamed&&) noexcept = delete; - AttrOpaque1Renamed operator=(const AttrOpaque1Renamed&) = delete; - AttrOpaque1Renamed operator=(AttrOpaque1Renamed&&) noexcept = delete; + AttrOpaque1Renamed(const ns::AttrOpaque1Renamed&) = delete; + AttrOpaque1Renamed(ns::AttrOpaque1Renamed&&) noexcept = delete; + AttrOpaque1Renamed operator=(const ns::AttrOpaque1Renamed&) = delete; + AttrOpaque1Renamed operator=(ns::AttrOpaque1Renamed&&) noexcept = delete; static void operator delete[](void*, size_t) = delete; }; - +} #endif // AttrOpaque1Renamed_D_HPP diff --git a/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp b/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp index 6bd740af7..bd53660e2 100644 --- a/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp +++ b/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp @@ -13,38 +13,38 @@ #include "AttrOpaque1.h" -inline std::unique_ptr AttrOpaque1Renamed::totally_not_new() { +inline std::unique_ptr ns::AttrOpaque1Renamed::totally_not_new() { auto result = capi::namespace_AttrOpaque1_new(); - return std::unique_ptr(AttrOpaque1Renamed::FromFFI(result)); + return std::unique_ptr(ns::AttrOpaque1Renamed::FromFFI(result)); } -inline uint8_t AttrOpaque1Renamed::method_renamed() const { +inline uint8_t ns::AttrOpaque1Renamed::method_renamed() const { auto result = capi::namespace_AttrOpaque1_method(this->AsFFI()); return result; } -inline uint8_t AttrOpaque1Renamed::abirenamed() const { +inline uint8_t ns::AttrOpaque1Renamed::abirenamed() const { auto result = capi::renamed_on_abi_only(this->AsFFI()); return result; } -inline const capi::AttrOpaque1* AttrOpaque1Renamed::AsFFI() const { +inline const capi::AttrOpaque1* ns::AttrOpaque1Renamed::AsFFI() const { return reinterpret_cast(this); } -inline capi::AttrOpaque1* AttrOpaque1Renamed::AsFFI() { +inline capi::AttrOpaque1* ns::AttrOpaque1Renamed::AsFFI() { return reinterpret_cast(this); } -inline const AttrOpaque1Renamed* AttrOpaque1Renamed::FromFFI(const capi::AttrOpaque1* ptr) { - return reinterpret_cast(ptr); +inline const ns::AttrOpaque1Renamed* ns::AttrOpaque1Renamed::FromFFI(const capi::AttrOpaque1* ptr) { + return reinterpret_cast(ptr); } -inline AttrOpaque1Renamed* AttrOpaque1Renamed::FromFFI(capi::AttrOpaque1* ptr) { - return reinterpret_cast(ptr); +inline ns::AttrOpaque1Renamed* ns::AttrOpaque1Renamed::FromFFI(capi::AttrOpaque1* ptr) { + return reinterpret_cast(ptr); } -inline void AttrOpaque1Renamed::operator delete(void* ptr) { +inline void ns::AttrOpaque1Renamed::operator delete(void* ptr) { capi::namespace_AttrOpaque1_destroy(reinterpret_cast(ptr)); } diff --git a/feature_tests/cpp2/include/CPPRenamedAttrEnum.d.hpp b/feature_tests/cpp2/include/CPPRenamedAttrEnum.d.hpp index e962a8f37..65a013b41 100644 --- a/feature_tests/cpp2/include/CPPRenamedAttrEnum.d.hpp +++ b/feature_tests/cpp2/include/CPPRenamedAttrEnum.d.hpp @@ -11,6 +11,7 @@ #include "AttrEnum.d.h" +namespace ns { class CPPRenamedAttrEnum { capi::AttrEnum value; @@ -21,12 +22,12 @@ class CPPRenamedAttrEnum { CPPRenamed, }; - inline CPPRenamedAttrEnum(CPPRenamedAttrEnum::Value cpp_value); + inline CPPRenamedAttrEnum(ns::CPPRenamedAttrEnum::Value cpp_value); inline CPPRenamedAttrEnum(capi::AttrEnum c_enum) : value(c_enum) {}; inline capi::AttrEnum AsFFI() const; - inline static CPPRenamedAttrEnum FromFFI(capi::AttrEnum c_enum); + inline static ns::CPPRenamedAttrEnum FromFFI(capi::AttrEnum c_enum); }; - +} #endif // CPPRenamedAttrEnum_D_HPP diff --git a/feature_tests/cpp2/include/CPPRenamedAttrEnum.hpp b/feature_tests/cpp2/include/CPPRenamedAttrEnum.hpp index 6e23e6ac8..8aaa573cc 100644 --- a/feature_tests/cpp2/include/CPPRenamedAttrEnum.hpp +++ b/feature_tests/cpp2/include/CPPRenamedAttrEnum.hpp @@ -13,7 +13,7 @@ #include "AttrEnum.h" -inline CPPRenamedAttrEnum::CPPRenamedAttrEnum(CPPRenamedAttrEnum::Value cpp_value) { +inline ns::CPPRenamedAttrEnum::CPPRenamedAttrEnum(ns::CPPRenamedAttrEnum::Value cpp_value) { switch (cpp_value) { case A: value = capi::AttrEnum_A; @@ -29,12 +29,12 @@ inline CPPRenamedAttrEnum::CPPRenamedAttrEnum(CPPRenamedAttrEnum::Value cpp_valu } } -inline capi::AttrEnum CPPRenamedAttrEnum::AsFFI() const { +inline capi::AttrEnum ns::CPPRenamedAttrEnum::AsFFI() const { return value; } -inline CPPRenamedAttrEnum CPPRenamedAttrEnum::FromFFI(capi::AttrEnum c_enum) { - return CPPRenamedAttrEnum(c_enum); +inline ns::CPPRenamedAttrEnum ns::CPPRenamedAttrEnum::FromFFI(capi::AttrEnum c_enum) { + return ns::CPPRenamedAttrEnum(c_enum); } #endif // CPPRenamedAttrEnum_HPP diff --git a/feature_tests/cpp2/tests/attrs.cpp b/feature_tests/cpp2/tests/attrs.cpp index 6c212c7e8..847527dfc 100644 --- a/feature_tests/cpp2/tests/attrs.cpp +++ b/feature_tests/cpp2/tests/attrs.cpp @@ -4,7 +4,7 @@ #include "assert.hpp" int main(int argc, char *argv[]) { - std::unique_ptr r = AttrOpaque1Renamed::totally_not_new(); + std::unique_ptr r = ns::AttrOpaque1Renamed::totally_not_new(); simple_assert_eq("method should call", r->method_renamed(), 77); simple_assert_eq("method should call", r->abirenamed(), 123); @@ -14,5 +14,5 @@ int main(int argc, char *argv[]) { renamed = (void*)capi::namespace_AttrOpaque1_method; std::cout<<"Renamed function at "< Date: Mon, 12 Feb 2024 15:24:02 -0800 Subject: [PATCH 04/16] empty namespace = reset --- core/src/hir/attrs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/hir/attrs.rs b/core/src/hir/attrs.rs index 21c5d5adb..3c7de0bca 100644 --- a/core/src/hir/attrs.rs +++ b/core/src/hir/attrs.rs @@ -105,6 +105,7 @@ impl Attrs { continue; } match StandardAttribute::from_meta(&attr.meta) { + Ok(StandardAttribute::String(s)) if s.is_empty() => this.namespace = None, Ok(StandardAttribute::String(s)) => this.namespace = Some(s), Ok(_) | Err(_) => { errors.push(LoweringError::Other( From b5298c465ff77cb7875bad2301ee134533b9d3c2 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 15:43:42 -0800 Subject: [PATCH 05/16] test for mixing namespaced and unnamespaced --- feature_tests/cpp2/tests/attrs.cpp | 5 +++++ feature_tests/src/attrs.rs | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/feature_tests/cpp2/tests/attrs.cpp b/feature_tests/cpp2/tests/attrs.cpp index 847527dfc..a33035505 100644 --- a/feature_tests/cpp2/tests/attrs.cpp +++ b/feature_tests/cpp2/tests/attrs.cpp @@ -1,6 +1,7 @@ #include #include "../include/AttrOpaque1Renamed.hpp" #include "../include/CPPRenamedAttrEnum.hpp" +#include "../include/Unnamespaced.hpp" #include "assert.hpp" int main(int argc, char *argv[]) { @@ -15,4 +16,8 @@ int main(int argc, char *argv[]) { std::cout<<"Renamed function at "< un = Unnamespaced::make(e); + un->use_namespaced(*r); + r->use_unnamespaced(*un); } diff --git a/feature_tests/src/attrs.rs b/feature_tests/src/attrs.rs index 91f3cb94e..70fb5b8f2 100644 --- a/feature_tests/src/attrs.rs +++ b/feature_tests/src/attrs.rs @@ -27,6 +27,8 @@ pub mod ffi { pub fn method_disabledcpp(&self) { println!("disabled in cpp"); } + + pub fn use_unnamespaced(&self, _un: &Unnamespaced) {} } #[diplomat::opaque] @@ -39,4 +41,17 @@ pub mod ffi { #[diplomat::attr(cpp2, rename = "CPPRenamed")] C, } + + #[diplomat::opaque] + #[diplomat::attr(cpp2, namespace = "")] + #[diplomat::attr(cpp2, rename = "Unnamespaced")] + pub struct Unnamespaced; + + impl Unnamespaced { + pub fn make(e: AttrEnum) -> Box { + Box::new(Self) + } + + pub fn use_namespaced(&self, _n: &AttrOpaque1) {} + } } From 2da6de7907a3bb6ee64b94f8f7b5829efaebeda3 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 16:01:59 -0800 Subject: [PATCH 06/16] wip mixing --- tool/src/cpp2/header.rs | 50 ++++++++++++++++++++++---------- tool/src/cpp2/ty.rs | 34 +++++++++++++--------- tool/templates/cpp2/base.h.jinja | 10 ++++++- 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/tool/src/cpp2/header.rs b/tool/src/cpp2/header.rs index 96191e95f..bb8bbc6a7 100644 --- a/tool/src/cpp2/header.rs +++ b/tool/src/cpp2/header.rs @@ -1,6 +1,7 @@ use askama::Template; +use diplomat_core::hir::TypeDef; use std::borrow::{Borrow, Cow}; -use std::collections::BTreeSet; +use std::collections::{BTreeMap, BTreeSet}; use std::fmt::{self, Write}; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] @@ -12,24 +13,13 @@ pub enum Forward { EnumStruct(String), } -// NOTE: This isn't exactly a valid impl of Borrow, but it makes things more convenient -impl Borrow for Forward { - fn borrow(&self) -> &str { - match self { - Forward::Class(s) => s, - Forward::Struct(s) => s, - Forward::EnumStruct(s) => s, - } - } -} - #[derive(Template)] #[template(path = "cpp2/base.h.jinja", escape = "none")] struct HeaderTemplate<'a> { header_guard: Cow<'a, str>, decl_include: Option>, includes: Vec>, - forwards: Vec, + forwards: &'a BTreeMap, BTreeSet>, body: Cow<'a, str>, } @@ -57,7 +47,7 @@ pub struct Header { /// typedef struct Foo Foo; /// typedef struct Bar Bar; /// ``` - pub forwards: BTreeSet, + pub forwards: BTreeMap, BTreeSet>, /// The actual meat of the header: usually will contain a type definition and methods /// /// Example: @@ -80,11 +70,39 @@ impl Header { path, includes: BTreeSet::new(), decl_include: None, - forwards: BTreeSet::new(), + forwards: BTreeMap::new(), body: String::new(), indent_str: " ", } } + + fn forward_for(def: TypeDef, ty_name_unnamespaced: &str) -> Forward { + match def { + TypeDef::Enum(..) => Forward::EnumStruct(ty_name_unnamespaced.into()), + TypeDef::Opaque(..) => Forward::Class(ty_name_unnamespaced.into()), + TypeDef::Struct(..) | TypeDef::OutStruct(..) => { + Forward::Struct(ty_name_unnamespaced.into()) + } + _ => unimplemented!("no other TypeDef variants!"), + } + } + + pub fn append_forward(&mut self, def: TypeDef, ty_name_unnamespaced: &str) { + let forward = Self::forward_for(def, ty_name_unnamespaced); + + let ns = def.attrs().namespace.clone(); + self.forwards.entry(ns).or_default().insert(forward); + } + pub fn rm_forward(&mut self, def: TypeDef, ty_name_unnamespaced: &str) { + let ns = &def.attrs().namespace; + let forward = Self::forward_for(def, ty_name_unnamespaced); + if let Some(ns_table) = self.forwards.get_mut(&ns) { + ns_table.remove(&forward); + if ns_table.is_empty() { + self.forwards.remove(&ns); + } + } + } } impl fmt::Write for Header { @@ -121,7 +139,7 @@ impl fmt::Display for Header { .iter() .map(|s| Cow::Borrowed(s.as_str())) .collect(), - forwards: self.forwards.iter().cloned().collect(), + forwards: &self.forwards, body, } .render_into(f) diff --git a/tool/src/cpp2/ty.rs b/tool/src/cpp2/ty.rs index a81613ea4..ffd379795 100644 --- a/tool/src/cpp2/ty.rs +++ b/tool/src/cpp2/ty.rs @@ -1,4 +1,4 @@ -use super::header::{Forward, Header}; +use super::header::Header; use super::Cpp2Context; use super::Cpp2Formatter; use askama::Template; @@ -15,6 +15,7 @@ impl<'tcx> super::Cpp2Context<'tcx> { return; } let type_name = self.formatter.fmt_type_name(id); + let type_name_unnamespaced = self.formatter.fmt_type_name(id); let decl_header_path = self.formatter.fmt_decl_header_path(id); let mut decl_header = Header::new(decl_header_path.clone()); let impl_header_path = self.formatter.fmt_impl_header_path(id); @@ -39,8 +40,8 @@ impl<'tcx> super::Cpp2Context<'tcx> { // a header will get its own forwards and includes. Instead of // trying to avoid pushing them, it's cleaner to just pull them out // once done - context.decl_header.forwards.remove(&*type_name); - context.impl_header.forwards.remove(&*type_name); + context.decl_header.rm_forward(ty, &*type_name_unnamespaced); + context.impl_header.rm_forward(ty, &*type_name_unnamespaced); context.decl_header.includes.remove(&*decl_header_path); context.impl_header.includes.remove(&*impl_header_path); context.impl_header.includes.remove(&*decl_header_path); @@ -410,8 +411,10 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { Type::Opaque(ref op) => { let op_id = op.tcx_id.into(); let type_name = self.cx.formatter.fmt_type_name(op_id); + let type_name_unnamespaced = self.cx.formatter.fmt_type_name_unnamespaced(op_id); + let def = self.cx.tcx.resolve_type(op_id); - if self.cx.tcx.resolve_type(op_id).attrs().disable { + if def.attrs().disable { self.cx .errors .push_error(format!("Found usage of disabled type {type_name}")) @@ -429,8 +432,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { let ret = ret.into_owned().into(); self.decl_header - .forwards - .insert(Forward::Class(type_name.into_owned())); + .append_forward(def, &type_name_unnamespaced); self.impl_header .includes .insert(self.cx.formatter.fmt_impl_header_path(op_id)); @@ -439,14 +441,16 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { Type::Struct(ref st) => { let id = st.id(); let type_name = self.cx.formatter.fmt_type_name(id); - if self.cx.tcx.resolve_type(id).attrs().disable { + let type_name_unnamespaced = self.cx.formatter.fmt_type_name_unnamespaced(id); + let def = self.cx.tcx.resolve_type(id); + if def.attrs().disable { self.cx .errors .push_error(format!("Found usage of disabled type {type_name}")) } - self.decl_header.forwards.insert(Forward::Struct( - self.cx.formatter.fmt_type_name(id).into_owned(), - )); + + self.decl_header + .append_forward(def, &type_name_unnamespaced); self.decl_header .includes .insert(self.cx.formatter.fmt_decl_header_path(id)); @@ -458,14 +462,16 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { Type::Enum(ref e) => { let id = e.tcx_id.into(); let type_name = self.cx.formatter.fmt_type_name(id); - if self.cx.tcx.resolve_type(id).attrs().disable { + let type_name_unnamespaced = self.cx.formatter.fmt_type_name_unnamespaced(id); + let def = self.cx.tcx.resolve_type(id); + if def.attrs().disable { self.cx .errors .push_error(format!("Found usage of disabled type {type_name}")) } - self.decl_header.forwards.insert(Forward::EnumStruct( - self.cx.formatter.fmt_type_name(id).into_owned(), - )); + + self.decl_header + .append_forward(def, &type_name_unnamespaced); self.decl_header .includes .insert(self.cx.formatter.fmt_decl_header_path(id)); diff --git a/tool/templates/cpp2/base.h.jinja b/tool/templates/cpp2/base.h.jinja index 399e2e018..a7326d0f7 100644 --- a/tool/templates/cpp2/base.h.jinja +++ b/tool/templates/cpp2/base.h.jinja @@ -19,7 +19,11 @@ {%- endfor %} {%~ if forwards.len() > 0 %} -{%- for forward in forwards %} +{%- for namespace_forward in forwards %} +{%- if let Some(ns) = namespace_forward.0 -%} +namespace {{ns}} { +{%- endif-%} +{%- for forward in namespace_forward.1 %} {%- match forward %} {%- when Forward::Class with (name) ~%} class {{ name }}; @@ -29,6 +33,10 @@ class {{ name }}; {%- endmatch %} {%- endfor %} +{%- if namespace_forward.0.is_some() %} +} +{%-endif %} +{%- endfor %} {% endif %} {{ body }} From f60e23f0288af0e6d1d56bbc17aeea218a815557 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 16:02:07 -0800 Subject: [PATCH 07/16] regen --- feature_tests/cpp2/include/AttrOpaque1.h | 4 ++ .../cpp2/include/AttrOpaque1Renamed.d.hpp | 6 +++ .../cpp2/include/AttrOpaque1Renamed.hpp | 6 +++ feature_tests/cpp2/include/Unnamespaced.d.h | 24 +++++++++ feature_tests/cpp2/include/Unnamespaced.d.hpp | 41 ++++++++++++++++ feature_tests/cpp2/include/Unnamespaced.h | 34 +++++++++++++ feature_tests/cpp2/include/Unnamespaced.hpp | 49 +++++++++++++++++++ 7 files changed, 164 insertions(+) create mode 100644 feature_tests/cpp2/include/Unnamespaced.d.h create mode 100644 feature_tests/cpp2/include/Unnamespaced.d.hpp create mode 100644 feature_tests/cpp2/include/Unnamespaced.h create mode 100644 feature_tests/cpp2/include/Unnamespaced.hpp diff --git a/feature_tests/cpp2/include/AttrOpaque1.h b/feature_tests/cpp2/include/AttrOpaque1.h index 970110828..0789623e4 100644 --- a/feature_tests/cpp2/include/AttrOpaque1.h +++ b/feature_tests/cpp2/include/AttrOpaque1.h @@ -6,6 +6,8 @@ #include #include #include "diplomat_runtime.h" +#include "Unnamespaced.d.h" +#include "Unnamespaced.h" #include "AttrOpaque1.d.h" @@ -21,6 +23,8 @@ uint8_t namespace_AttrOpaque1_method(const AttrOpaque1* self); uint8_t renamed_on_abi_only(const AttrOpaque1* self); +void namespace_AttrOpaque1_use_unnamespaced(const AttrOpaque1* self, const Unnamespaced* _un); + void namespace_AttrOpaque1_destroy(AttrOpaque1* self); diff --git a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp index e9082bed2..3b1e0aa7e 100644 --- a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp +++ b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp @@ -10,6 +10,10 @@ #include "diplomat_runtime.hpp" #include "AttrOpaque1.d.h" +class Unnamespaced;namespace ns { +class AttrOpaque1Renamed; +} + namespace ns { class AttrOpaque1Renamed { @@ -21,6 +25,8 @@ class AttrOpaque1Renamed { inline uint8_t abirenamed() const; + inline void use_unnamespaced(const Unnamespaced& _un) const; + inline const capi::AttrOpaque1* AsFFI() const; inline capi::AttrOpaque1* AsFFI(); inline static const ns::AttrOpaque1Renamed* FromFFI(const capi::AttrOpaque1* ptr); diff --git a/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp b/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp index bd53660e2..c28804f16 100644 --- a/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp +++ b/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp @@ -11,6 +11,7 @@ #include #include "diplomat_runtime.hpp" #include "AttrOpaque1.h" +#include "Unnamespaced.hpp" inline std::unique_ptr ns::AttrOpaque1Renamed::totally_not_new() { @@ -28,6 +29,11 @@ inline uint8_t ns::AttrOpaque1Renamed::abirenamed() const { return result; } +inline void ns::AttrOpaque1Renamed::use_unnamespaced(const Unnamespaced& _un) const { + capi::namespace_AttrOpaque1_use_unnamespaced(this->AsFFI(), + _un.AsFFI()); +} + inline const capi::AttrOpaque1* ns::AttrOpaque1Renamed::AsFFI() const { return reinterpret_cast(this); } diff --git a/feature_tests/cpp2/include/Unnamespaced.d.h b/feature_tests/cpp2/include/Unnamespaced.d.h new file mode 100644 index 000000000..01e2ea4a3 --- /dev/null +++ b/feature_tests/cpp2/include/Unnamespaced.d.h @@ -0,0 +1,24 @@ +#ifndef Unnamespaced_D_H +#define Unnamespaced_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +namespace capi { +extern "C" { +#endif // __cplusplus + + +typedef struct Unnamespaced Unnamespaced; + + +#ifdef __cplusplus +} // extern "C" +} // namespace capi +#endif // __cplusplus + +#endif // Unnamespaced_D_H diff --git a/feature_tests/cpp2/include/Unnamespaced.d.hpp b/feature_tests/cpp2/include/Unnamespaced.d.hpp new file mode 100644 index 000000000..01725a1bd --- /dev/null +++ b/feature_tests/cpp2/include/Unnamespaced.d.hpp @@ -0,0 +1,41 @@ +#ifndef Unnamespaced_D_HPP +#define Unnamespaced_D_HPP + +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +#include "CPPRenamedAttrEnum.d.hpp" +#include "Unnamespaced.d.h" +namespace ns { +class AttrOpaque1Renamed; +class CPPRenamedAttrEnum; +} + + +class Unnamespaced { +public: + + inline static std::unique_ptr make(ns::CPPRenamedAttrEnum e); + + inline void use_namespaced(const ns::AttrOpaque1Renamed& _n) const; + + inline const capi::Unnamespaced* AsFFI() const; + inline capi::Unnamespaced* AsFFI(); + inline static const Unnamespaced* FromFFI(const capi::Unnamespaced* ptr); + inline static Unnamespaced* FromFFI(capi::Unnamespaced* ptr); + inline static void operator delete(void* ptr); +private: + Unnamespaced() = delete; + Unnamespaced(const Unnamespaced&) = delete; + Unnamespaced(Unnamespaced&&) noexcept = delete; + Unnamespaced operator=(const Unnamespaced&) = delete; + Unnamespaced operator=(Unnamespaced&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + + +#endif // Unnamespaced_D_HPP diff --git a/feature_tests/cpp2/include/Unnamespaced.h b/feature_tests/cpp2/include/Unnamespaced.h new file mode 100644 index 000000000..65eb5d88f --- /dev/null +++ b/feature_tests/cpp2/include/Unnamespaced.h @@ -0,0 +1,34 @@ +#ifndef Unnamespaced_H +#define Unnamespaced_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" +#include "AttrEnum.d.h" +#include "AttrEnum.h" +#include "AttrOpaque1.d.h" +#include "AttrOpaque1.h" + +#include "Unnamespaced.d.h" + +#ifdef __cplusplus +namespace capi { +extern "C" { +#endif // __cplusplus + + +Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); + +void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); + +void namespace_Unnamespaced_destroy(Unnamespaced* self); + + +#ifdef __cplusplus +} // extern "C" +} // namespace capi +#endif // __cplusplus + +#endif // Unnamespaced_H diff --git a/feature_tests/cpp2/include/Unnamespaced.hpp b/feature_tests/cpp2/include/Unnamespaced.hpp new file mode 100644 index 000000000..568b59d8d --- /dev/null +++ b/feature_tests/cpp2/include/Unnamespaced.hpp @@ -0,0 +1,49 @@ +#ifndef Unnamespaced_HPP +#define Unnamespaced_HPP + +#include "Unnamespaced.d.hpp" + +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" +#include "AttrOpaque1Renamed.hpp" +#include "CPPRenamedAttrEnum.hpp" +#include "Unnamespaced.h" + + +inline std::unique_ptr Unnamespaced::make(ns::CPPRenamedAttrEnum e) { + auto result = capi::namespace_Unnamespaced_make(e.AsFFI()); + return std::unique_ptr(Unnamespaced::FromFFI(result)); +} + +inline void Unnamespaced::use_namespaced(const ns::AttrOpaque1Renamed& _n) const { + capi::namespace_Unnamespaced_use_namespaced(this->AsFFI(), + _n.AsFFI()); +} + +inline const capi::Unnamespaced* Unnamespaced::AsFFI() const { + return reinterpret_cast(this); +} + +inline capi::Unnamespaced* Unnamespaced::AsFFI() { + return reinterpret_cast(this); +} + +inline const Unnamespaced* Unnamespaced::FromFFI(const capi::Unnamespaced* ptr) { + return reinterpret_cast(ptr); +} + +inline Unnamespaced* Unnamespaced::FromFFI(capi::Unnamespaced* ptr) { + return reinterpret_cast(ptr); +} + +inline void Unnamespaced::operator delete(void* ptr) { + capi::namespace_Unnamespaced_destroy(reinterpret_cast(ptr)); +} + + +#endif // Unnamespaced_HPP From 6ab8a2b4f44a66bef57c582c1a84013076d75622 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 16:28:35 -0800 Subject: [PATCH 08/16] add test for mixing types within the same namespace --- feature_tests/cpp2/include/AttrOpaque1.h | 4 ++++ feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp | 4 ++++ feature_tests/cpp2/include/AttrOpaque1Renamed.hpp | 6 ++++++ feature_tests/cpp2/tests/attrs.cpp | 1 + feature_tests/src/attrs.rs | 1 + 5 files changed, 16 insertions(+) diff --git a/feature_tests/cpp2/include/AttrOpaque1.h b/feature_tests/cpp2/include/AttrOpaque1.h index 0789623e4..7286029cd 100644 --- a/feature_tests/cpp2/include/AttrOpaque1.h +++ b/feature_tests/cpp2/include/AttrOpaque1.h @@ -6,6 +6,8 @@ #include #include #include "diplomat_runtime.h" +#include "AttrEnum.d.h" +#include "AttrEnum.h" #include "Unnamespaced.d.h" #include "Unnamespaced.h" @@ -25,6 +27,8 @@ uint8_t renamed_on_abi_only(const AttrOpaque1* self); void namespace_AttrOpaque1_use_unnamespaced(const AttrOpaque1* self, const Unnamespaced* _un); +void namespace_AttrOpaque1_use_namespaced(const AttrOpaque1* self, AttrEnum _n); + void namespace_AttrOpaque1_destroy(AttrOpaque1* self); diff --git a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp index 3b1e0aa7e..110976c4d 100644 --- a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp +++ b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp @@ -9,9 +9,11 @@ #include #include "diplomat_runtime.hpp" #include "AttrOpaque1.d.h" +#include "CPPRenamedAttrEnum.d.hpp" class Unnamespaced;namespace ns { class AttrOpaque1Renamed; +class CPPRenamedAttrEnum; } @@ -27,6 +29,8 @@ class AttrOpaque1Renamed { inline void use_unnamespaced(const Unnamespaced& _un) const; + inline void use_namespaced(ns::CPPRenamedAttrEnum _n) const; + inline const capi::AttrOpaque1* AsFFI() const; inline capi::AttrOpaque1* AsFFI(); inline static const ns::AttrOpaque1Renamed* FromFFI(const capi::AttrOpaque1* ptr); diff --git a/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp b/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp index c28804f16..21b85bef9 100644 --- a/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp +++ b/feature_tests/cpp2/include/AttrOpaque1Renamed.hpp @@ -11,6 +11,7 @@ #include #include "diplomat_runtime.hpp" #include "AttrOpaque1.h" +#include "CPPRenamedAttrEnum.hpp" #include "Unnamespaced.hpp" @@ -34,6 +35,11 @@ inline void ns::AttrOpaque1Renamed::use_unnamespaced(const Unnamespaced& _un) co _un.AsFFI()); } +inline void ns::AttrOpaque1Renamed::use_namespaced(ns::CPPRenamedAttrEnum _n) const { + capi::namespace_AttrOpaque1_use_namespaced(this->AsFFI(), + _n.AsFFI()); +} + inline const capi::AttrOpaque1* ns::AttrOpaque1Renamed::AsFFI() const { return reinterpret_cast(this); } diff --git a/feature_tests/cpp2/tests/attrs.cpp b/feature_tests/cpp2/tests/attrs.cpp index a33035505..97ef3d64c 100644 --- a/feature_tests/cpp2/tests/attrs.cpp +++ b/feature_tests/cpp2/tests/attrs.cpp @@ -20,4 +20,5 @@ int main(int argc, char *argv[]) { std::unique_ptr un = Unnamespaced::make(e); un->use_namespaced(*r); r->use_unnamespaced(*un); + r->use_namespaced(e); } diff --git a/feature_tests/src/attrs.rs b/feature_tests/src/attrs.rs index 70fb5b8f2..5197b6a11 100644 --- a/feature_tests/src/attrs.rs +++ b/feature_tests/src/attrs.rs @@ -29,6 +29,7 @@ pub mod ffi { } pub fn use_unnamespaced(&self, _un: &Unnamespaced) {} + pub fn use_namespaced(&self, _n: AttrEnum) {} } #[diplomat::opaque] From 103df290d2b6bedf2311dd0bda0625996756cf6d Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 16:29:14 -0800 Subject: [PATCH 09/16] regen everyone else --- feature_tests/c/include/AttrOpaque1.h | 6 ++ feature_tests/c/include/Unnamespaced.h | 33 +++++++ feature_tests/c2/include/AttrOpaque1.h | 8 ++ feature_tests/c2/include/Unnamespaced.d.h | 24 +++++ feature_tests/c2/include/Unnamespaced.h | 34 +++++++ feature_tests/cpp/docs/source/attrs_ffi.rst | 14 +++ feature_tests/cpp/include/AttrOpaque1.h | 6 ++ feature_tests/cpp/include/AttrOpaque1.hpp | 11 +++ feature_tests/cpp/include/Unnamespaced.h | 33 +++++++ feature_tests/cpp/include/Unnamespaced.hpp | 48 ++++++++++ feature_tests/dart/lib/src/AttrOpaque1.g.dart | 16 ++++ .../dart/lib/src/Unnamespaced.g.dart | 47 +++++++++ feature_tests/dart/lib/src/lib.g.dart | 1 + .../dotnet/Lib/Generated/AttrOpaque1.cs | 32 +++++++ .../dotnet/Lib/Generated/RawAttrOpaque1.cs | 6 ++ .../dotnet/Lib/Generated/RawUnnamespaced.cs | 27 ++++++ .../dotnet/Lib/Generated/Unnamespaced.cs | 95 +++++++++++++++++++ feature_tests/js/api/AttrOpaque1.d.ts | 10 ++ feature_tests/js/api/AttrOpaque1.mjs | 9 ++ feature_tests/js/api/Unnamespaced.d.ts | 15 +++ feature_tests/js/api/Unnamespaced.mjs | 26 +++++ feature_tests/js/api/index.d.ts | 1 + feature_tests/js/api/index.mjs | 1 + feature_tests/js/docs/source/attrs_ffi.rst | 10 ++ 24 files changed, 513 insertions(+) create mode 100644 feature_tests/c/include/Unnamespaced.h create mode 100644 feature_tests/c2/include/Unnamespaced.d.h create mode 100644 feature_tests/c2/include/Unnamespaced.h create mode 100644 feature_tests/cpp/include/Unnamespaced.h create mode 100644 feature_tests/cpp/include/Unnamespaced.hpp create mode 100644 feature_tests/dart/lib/src/Unnamespaced.g.dart create mode 100644 feature_tests/dotnet/Lib/Generated/RawUnnamespaced.cs create mode 100644 feature_tests/dotnet/Lib/Generated/Unnamespaced.cs create mode 100644 feature_tests/js/api/Unnamespaced.d.ts create mode 100644 feature_tests/js/api/Unnamespaced.mjs diff --git a/feature_tests/c/include/AttrOpaque1.h b/feature_tests/c/include/AttrOpaque1.h index 1b710c343..72ae8390e 100644 --- a/feature_tests/c/include/AttrOpaque1.h +++ b/feature_tests/c/include/AttrOpaque1.h @@ -14,6 +14,8 @@ typedef struct AttrOpaque1 AttrOpaque1; #ifdef __cplusplus } // namespace capi #endif +#include "Unnamespaced.h" +#include "AttrEnum.h" #ifdef __cplusplus namespace capi { extern "C" { @@ -26,6 +28,10 @@ uint8_t namespace_AttrOpaque1_method(const AttrOpaque1* self); uint8_t renamed_on_abi_only(const AttrOpaque1* self); void namespace_AttrOpaque1_method_disabledcpp(const AttrOpaque1* self); + +void namespace_AttrOpaque1_use_unnamespaced(const AttrOpaque1* self, const Unnamespaced* _un); + +void namespace_AttrOpaque1_use_namespaced(const AttrOpaque1* self, AttrEnum _n); void namespace_AttrOpaque1_destroy(AttrOpaque1* self); #ifdef __cplusplus diff --git a/feature_tests/c/include/Unnamespaced.h b/feature_tests/c/include/Unnamespaced.h new file mode 100644 index 000000000..2d6d936f4 --- /dev/null +++ b/feature_tests/c/include/Unnamespaced.h @@ -0,0 +1,33 @@ +#ifndef Unnamespaced_H +#define Unnamespaced_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +namespace capi { +#endif + +typedef struct Unnamespaced Unnamespaced; +#ifdef __cplusplus +} // namespace capi +#endif +#include "AttrEnum.h" +#include "AttrOpaque1.h" +#ifdef __cplusplus +namespace capi { +extern "C" { +#endif + +Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); + +void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); +void namespace_Unnamespaced_destroy(Unnamespaced* self); + +#ifdef __cplusplus +} // extern "C" +} // namespace capi +#endif +#endif diff --git a/feature_tests/c2/include/AttrOpaque1.h b/feature_tests/c2/include/AttrOpaque1.h index 617dbd060..5cf025596 100644 --- a/feature_tests/c2/include/AttrOpaque1.h +++ b/feature_tests/c2/include/AttrOpaque1.h @@ -6,6 +6,10 @@ #include #include #include "diplomat_runtime.h" +#include "AttrEnum.d.h" +#include "AttrEnum.h" +#include "Unnamespaced.d.h" +#include "Unnamespaced.h" #include "AttrOpaque1.d.h" @@ -23,6 +27,10 @@ uint8_t renamed_on_abi_only(const AttrOpaque1* self); void namespace_AttrOpaque1_method_disabledcpp(const AttrOpaque1* self); +void namespace_AttrOpaque1_use_unnamespaced(const AttrOpaque1* self, const Unnamespaced* _un); + +void namespace_AttrOpaque1_use_namespaced(const AttrOpaque1* self, AttrEnum _n); + void namespace_AttrOpaque1_destroy(AttrOpaque1* self); diff --git a/feature_tests/c2/include/Unnamespaced.d.h b/feature_tests/c2/include/Unnamespaced.d.h new file mode 100644 index 000000000..01e2ea4a3 --- /dev/null +++ b/feature_tests/c2/include/Unnamespaced.d.h @@ -0,0 +1,24 @@ +#ifndef Unnamespaced_D_H +#define Unnamespaced_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +namespace capi { +extern "C" { +#endif // __cplusplus + + +typedef struct Unnamespaced Unnamespaced; + + +#ifdef __cplusplus +} // extern "C" +} // namespace capi +#endif // __cplusplus + +#endif // Unnamespaced_D_H diff --git a/feature_tests/c2/include/Unnamespaced.h b/feature_tests/c2/include/Unnamespaced.h new file mode 100644 index 000000000..65eb5d88f --- /dev/null +++ b/feature_tests/c2/include/Unnamespaced.h @@ -0,0 +1,34 @@ +#ifndef Unnamespaced_H +#define Unnamespaced_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" +#include "AttrEnum.d.h" +#include "AttrEnum.h" +#include "AttrOpaque1.d.h" +#include "AttrOpaque1.h" + +#include "Unnamespaced.d.h" + +#ifdef __cplusplus +namespace capi { +extern "C" { +#endif // __cplusplus + + +Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); + +void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); + +void namespace_Unnamespaced_destroy(Unnamespaced* self); + + +#ifdef __cplusplus +} // extern "C" +} // namespace capi +#endif // __cplusplus + +#endif // Unnamespaced_H diff --git a/feature_tests/cpp/docs/source/attrs_ffi.rst b/feature_tests/cpp/docs/source/attrs_ffi.rst index df86cdc20..c957c64a1 100644 --- a/feature_tests/cpp/docs/source/attrs_ffi.rst +++ b/feature_tests/cpp/docs/source/attrs_ffi.rst @@ -23,4 +23,18 @@ .. cpp:function:: void method_disabledcpp() const + .. cpp:function:: void use_unnamespaced(const Unnamespaced& _un) const + + + .. cpp:function:: void use_namespaced(AttrEnum _n) const + + .. cpp:class:: AttrOpaque2 + +.. cpp:class:: Unnamespaced + + .. cpp:function:: static Unnamespaced make(AttrEnum e) + + + .. cpp:function:: void use_namespaced(const AttrOpaque1& _n) const + diff --git a/feature_tests/cpp/include/AttrOpaque1.h b/feature_tests/cpp/include/AttrOpaque1.h index 1b710c343..72ae8390e 100644 --- a/feature_tests/cpp/include/AttrOpaque1.h +++ b/feature_tests/cpp/include/AttrOpaque1.h @@ -14,6 +14,8 @@ typedef struct AttrOpaque1 AttrOpaque1; #ifdef __cplusplus } // namespace capi #endif +#include "Unnamespaced.h" +#include "AttrEnum.h" #ifdef __cplusplus namespace capi { extern "C" { @@ -26,6 +28,10 @@ uint8_t namespace_AttrOpaque1_method(const AttrOpaque1* self); uint8_t renamed_on_abi_only(const AttrOpaque1* self); void namespace_AttrOpaque1_method_disabledcpp(const AttrOpaque1* self); + +void namespace_AttrOpaque1_use_unnamespaced(const AttrOpaque1* self, const Unnamespaced* _un); + +void namespace_AttrOpaque1_use_namespaced(const AttrOpaque1* self, AttrEnum _n); void namespace_AttrOpaque1_destroy(AttrOpaque1* self); #ifdef __cplusplus diff --git a/feature_tests/cpp/include/AttrOpaque1.hpp b/feature_tests/cpp/include/AttrOpaque1.hpp index 1c8b25ce2..5de5c90eb 100644 --- a/feature_tests/cpp/include/AttrOpaque1.hpp +++ b/feature_tests/cpp/include/AttrOpaque1.hpp @@ -12,6 +12,8 @@ #include "AttrOpaque1.h" class AttrOpaque1; +class Unnamespaced; +#include "AttrEnum.hpp" /** * A destruction policy for using AttrOpaque1 with std::unique_ptr. @@ -27,6 +29,8 @@ class AttrOpaque1 { uint8_t method() const; uint8_t abirenamed() const; void method_disabledcpp() const; + void use_unnamespaced(const Unnamespaced& _un) const; + void use_namespaced(AttrEnum _n) const; inline const capi::AttrOpaque1* AsFFI() const { return this->inner.get(); } inline capi::AttrOpaque1* AsFFIMut() { return this->inner.get(); } inline explicit AttrOpaque1(capi::AttrOpaque1* i) : inner(i) {} @@ -37,6 +41,7 @@ class AttrOpaque1 { std::unique_ptr inner; }; +#include "Unnamespaced.hpp" inline AttrOpaque1 AttrOpaque1::new_() { return AttrOpaque1(capi::namespace_AttrOpaque1_new()); @@ -50,4 +55,10 @@ inline uint8_t AttrOpaque1::abirenamed() const { inline void AttrOpaque1::method_disabledcpp() const { capi::namespace_AttrOpaque1_method_disabledcpp(this->inner.get()); } +inline void AttrOpaque1::use_unnamespaced(const Unnamespaced& _un) const { + capi::namespace_AttrOpaque1_use_unnamespaced(this->inner.get(), _un.AsFFI()); +} +inline void AttrOpaque1::use_namespaced(AttrEnum _n) const { + capi::namespace_AttrOpaque1_use_namespaced(this->inner.get(), static_cast(_n)); +} #endif diff --git a/feature_tests/cpp/include/Unnamespaced.h b/feature_tests/cpp/include/Unnamespaced.h new file mode 100644 index 000000000..2d6d936f4 --- /dev/null +++ b/feature_tests/cpp/include/Unnamespaced.h @@ -0,0 +1,33 @@ +#ifndef Unnamespaced_H +#define Unnamespaced_H +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#ifdef __cplusplus +namespace capi { +#endif + +typedef struct Unnamespaced Unnamespaced; +#ifdef __cplusplus +} // namespace capi +#endif +#include "AttrEnum.h" +#include "AttrOpaque1.h" +#ifdef __cplusplus +namespace capi { +extern "C" { +#endif + +Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); + +void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); +void namespace_Unnamespaced_destroy(Unnamespaced* self); + +#ifdef __cplusplus +} // extern "C" +} // namespace capi +#endif +#endif diff --git a/feature_tests/cpp/include/Unnamespaced.hpp b/feature_tests/cpp/include/Unnamespaced.hpp new file mode 100644 index 000000000..887a02c3a --- /dev/null +++ b/feature_tests/cpp/include/Unnamespaced.hpp @@ -0,0 +1,48 @@ +#ifndef Unnamespaced_HPP +#define Unnamespaced_HPP +#include +#include +#include +#include +#include +#include +#include +#include "diplomat_runtime.hpp" + +#include "Unnamespaced.h" + +#include "AttrEnum.hpp" +class Unnamespaced; +class AttrOpaque1; + +/** + * A destruction policy for using Unnamespaced with std::unique_ptr. + */ +struct UnnamespacedDeleter { + void operator()(capi::Unnamespaced* l) const noexcept { + capi::namespace_Unnamespaced_destroy(l); + } +}; +class Unnamespaced { + public: + static Unnamespaced make(AttrEnum e); + void use_namespaced(const AttrOpaque1& _n) const; + inline const capi::Unnamespaced* AsFFI() const { return this->inner.get(); } + inline capi::Unnamespaced* AsFFIMut() { return this->inner.get(); } + inline explicit Unnamespaced(capi::Unnamespaced* i) : inner(i) {} + Unnamespaced() = default; + Unnamespaced(Unnamespaced&&) noexcept = default; + Unnamespaced& operator=(Unnamespaced&& other) noexcept = default; + private: + std::unique_ptr inner; +}; + +#include "AttrOpaque1.hpp" + +inline Unnamespaced Unnamespaced::make(AttrEnum e) { + return Unnamespaced(capi::namespace_Unnamespaced_make(static_cast(e))); +} +inline void Unnamespaced::use_namespaced(const AttrOpaque1& _n) const { + capi::namespace_Unnamespaced_use_namespaced(this->inner.get(), _n.AsFFI()); +} +#endif diff --git a/feature_tests/dart/lib/src/AttrOpaque1.g.dart b/feature_tests/dart/lib/src/AttrOpaque1.g.dart index 6395a7507..cbd78f3f4 100644 --- a/feature_tests/dart/lib/src/AttrOpaque1.g.dart +++ b/feature_tests/dart/lib/src/AttrOpaque1.g.dart @@ -42,6 +42,14 @@ final class AttrOpaque1 implements ffi.Finalizable { void methodDisabledcpp() { _namespace_AttrOpaque1_method_disabledcpp(_underlying); } + + void useUnnamespaced(Unnamespaced un) { + _namespace_AttrOpaque1_use_unnamespaced(_underlying, un._underlying); + } + + void useNamespaced(AttrEnum n) { + _namespace_AttrOpaque1_use_namespaced(_underlying, n.index); + } } @ffi.Native)>(isLeaf: true, symbol: 'namespace_AttrOpaque1_destroy') @@ -63,3 +71,11 @@ external int _renamed_on_abi_only(ffi.Pointer self); @ffi.Native)>(isLeaf: true, symbol: 'namespace_AttrOpaque1_method_disabledcpp') // ignore: non_constant_identifier_names external void _namespace_AttrOpaque1_method_disabledcpp(ffi.Pointer self); + +@ffi.Native, ffi.Pointer)>(isLeaf: true, symbol: 'namespace_AttrOpaque1_use_unnamespaced') +// ignore: non_constant_identifier_names +external void _namespace_AttrOpaque1_use_unnamespaced(ffi.Pointer self, ffi.Pointer un); + +@ffi.Native, ffi.Int32)>(isLeaf: true, symbol: 'namespace_AttrOpaque1_use_namespaced') +// ignore: non_constant_identifier_names +external void _namespace_AttrOpaque1_use_namespaced(ffi.Pointer self, int n); diff --git a/feature_tests/dart/lib/src/Unnamespaced.g.dart b/feature_tests/dart/lib/src/Unnamespaced.g.dart new file mode 100644 index 000000000..30d9bf8a9 --- /dev/null +++ b/feature_tests/dart/lib/src/Unnamespaced.g.dart @@ -0,0 +1,47 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +final class Unnamespaced implements ffi.Finalizable { + final ffi.Pointer _underlying; + + final core.List _edge_self; + + // Internal constructor from FFI. + // isOwned is whether this is owned (has finalizer) or not + // This also takes in a list of lifetime edges (including for &self borrows) + // corresponding to data this may borrow from. These should be flat arrays containing + // references to objects, and this object will hold on to them to keep them alive and + // maintain borrow validity. + Unnamespaced._(this._underlying, bool isOwned, this._edge_self) { + if (isOwned) { + _finalizer.attach(this, _underlying.cast()); + } + } + + static final _finalizer = ffi.NativeFinalizer(ffi.Native.addressOf(_namespace_Unnamespaced_destroy)); + + factory Unnamespaced.make(AttrEnum e) { + final result = _namespace_Unnamespaced_make(e.index); + return Unnamespaced._(result, true, []); + } + + void useNamespaced(AttrOpaque1 n) { + _namespace_Unnamespaced_use_namespaced(_underlying, n._underlying); + } +} + +@ffi.Native)>(isLeaf: true, symbol: 'namespace_Unnamespaced_destroy') +// ignore: non_constant_identifier_names +external void _namespace_Unnamespaced_destroy(ffi.Pointer self); + +@ffi.Native Function(ffi.Int32)>(isLeaf: true, symbol: 'namespace_Unnamespaced_make') +// ignore: non_constant_identifier_names +external ffi.Pointer _namespace_Unnamespaced_make(int e); + +@ffi.Native, ffi.Pointer)>(isLeaf: true, symbol: 'namespace_Unnamespaced_use_namespaced') +// ignore: non_constant_identifier_names +external void _namespace_Unnamespaced_use_namespaced(ffi.Pointer self, ffi.Pointer n); diff --git a/feature_tests/dart/lib/src/lib.g.dart b/feature_tests/dart/lib/src/lib.g.dart index 654f74fae..fe94dc7ca 100644 --- a/feature_tests/dart/lib/src/lib.g.dart +++ b/feature_tests/dart/lib/src/lib.g.dart @@ -36,6 +36,7 @@ part 'RefListParameter.g.dart'; part 'ResultOpaque.g.dart'; part 'Two.g.dart'; part 'UnimportedEnum.g.dart'; +part 'Unnamespaced.g.dart'; /// A [Rune] is a Unicode code point, such as `a`, or `💡`. /// diff --git a/feature_tests/dotnet/Lib/Generated/AttrOpaque1.cs b/feature_tests/dotnet/Lib/Generated/AttrOpaque1.cs index dbc50129f..1dacf8711 100644 --- a/feature_tests/dotnet/Lib/Generated/AttrOpaque1.cs +++ b/feature_tests/dotnet/Lib/Generated/AttrOpaque1.cs @@ -79,6 +79,38 @@ public void MethodDisabledcpp() } } + public void UseUnnamespaced(Unnamespaced un) + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("AttrOpaque1"); + } + Raw.Unnamespaced* unRaw; + unRaw = un.AsFFI(); + if (unRaw == null) + { + throw new ObjectDisposedException("Unnamespaced"); + } + Raw.AttrOpaque1.UseUnnamespaced(_inner, unRaw); + } + } + + public void UseNamespaced(AttrEnum n) + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("AttrOpaque1"); + } + Raw.AttrEnum nRaw; + nRaw = (Raw.AttrEnum)n; + Raw.AttrOpaque1.UseNamespaced(_inner, nRaw); + } + } + /// /// Returns the underlying raw handle. /// diff --git a/feature_tests/dotnet/Lib/Generated/RawAttrOpaque1.cs b/feature_tests/dotnet/Lib/Generated/RawAttrOpaque1.cs index 05a914390..aaee804b7 100644 --- a/feature_tests/dotnet/Lib/Generated/RawAttrOpaque1.cs +++ b/feature_tests/dotnet/Lib/Generated/RawAttrOpaque1.cs @@ -28,6 +28,12 @@ public partial struct AttrOpaque1 [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "namespace_AttrOpaque1_method_disabledcpp", ExactSpelling = true)] public static unsafe extern void NamespaceMethodDisabledcpp(AttrOpaque1* self); + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "namespace_AttrOpaque1_use_unnamespaced", ExactSpelling = true)] + public static unsafe extern void NamespaceUseUnnamespaced(AttrOpaque1* self, Unnamespaced* un); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "namespace_AttrOpaque1_use_namespaced", ExactSpelling = true)] + public static unsafe extern void NamespaceUseNamespaced(AttrOpaque1* self, AttrEnum n); + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "namespace_AttrOpaque1_destroy", ExactSpelling = true)] public static unsafe extern void Destroy(AttrOpaque1* self); } diff --git a/feature_tests/dotnet/Lib/Generated/RawUnnamespaced.cs b/feature_tests/dotnet/Lib/Generated/RawUnnamespaced.cs new file mode 100644 index 000000000..c4a239f7f --- /dev/null +++ b/feature_tests/dotnet/Lib/Generated/RawUnnamespaced.cs @@ -0,0 +1,27 @@ +// by Diplomat + +#pragma warning disable 0105 +using System; +using System.Runtime.InteropServices; + +using DiplomatFeatures.Diplomat; +#pragma warning restore 0105 + +namespace DiplomatFeatures.Raw; + +#nullable enable + +[StructLayout(LayoutKind.Sequential)] +public partial struct Unnamespaced +{ + private const string NativeLib = "diplomat_feature_tests"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "namespace_Unnamespaced_make", ExactSpelling = true)] + public static unsafe extern Unnamespaced* NamespaceMake(AttrEnum e); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "namespace_Unnamespaced_use_namespaced", ExactSpelling = true)] + public static unsafe extern void NamespaceUseNamespaced(Unnamespaced* self, AttrOpaque1* n); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "namespace_Unnamespaced_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(Unnamespaced* self); +} diff --git a/feature_tests/dotnet/Lib/Generated/Unnamespaced.cs b/feature_tests/dotnet/Lib/Generated/Unnamespaced.cs new file mode 100644 index 000000000..000b2418d --- /dev/null +++ b/feature_tests/dotnet/Lib/Generated/Unnamespaced.cs @@ -0,0 +1,95 @@ +// by Diplomat + +#pragma warning disable 0105 +using System; +using System.Runtime.InteropServices; + +using DiplomatFeatures.Diplomat; +#pragma warning restore 0105 + +namespace DiplomatFeatures; + +#nullable enable + +public partial class Unnamespaced: IDisposable +{ + private unsafe Raw.Unnamespaced* _inner; + + /// + /// Creates a managed Unnamespaced from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe Unnamespaced(Raw.Unnamespaced* handle) + { + _inner = handle; + } + + /// + /// A Unnamespaced allocated on Rust side. + /// + public static Unnamespaced Make(AttrEnum e) + { + unsafe + { + Raw.AttrEnum eRaw; + eRaw = (Raw.AttrEnum)e; + Raw.Unnamespaced* retVal = Raw.Unnamespaced.Make(eRaw); + return new Unnamespaced(retVal); + } + } + + public void UseNamespaced(AttrOpaque1 n) + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("Unnamespaced"); + } + Raw.AttrOpaque1* nRaw; + nRaw = n.AsFFI(); + if (nRaw == null) + { + throw new ObjectDisposedException("AttrOpaque1"); + } + Raw.Unnamespaced.UseNamespaced(_inner, nRaw); + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.Unnamespaced* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.Unnamespaced.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~Unnamespaced() + { + Dispose(); + } +} diff --git a/feature_tests/js/api/AttrOpaque1.d.ts b/feature_tests/js/api/AttrOpaque1.d.ts index 9239449c5..c9df7cf29 100644 --- a/feature_tests/js/api/AttrOpaque1.d.ts +++ b/feature_tests/js/api/AttrOpaque1.d.ts @@ -1,4 +1,6 @@ import { u8 } from "./diplomat-runtime" +import { AttrEnum } from "./AttrEnum"; +import { Unnamespaced } from "./Unnamespaced"; /** */ @@ -19,4 +21,12 @@ export class AttrOpaque1 { /** */ method_disabledcpp(): void; + + /** + */ + use_unnamespaced(_un: Unnamespaced): void; + + /** + */ + use_namespaced(_n: AttrEnum): void; } diff --git a/feature_tests/js/api/AttrOpaque1.mjs b/feature_tests/js/api/AttrOpaque1.mjs index 418d9af36..57fe6b353 100644 --- a/feature_tests/js/api/AttrOpaque1.mjs +++ b/feature_tests/js/api/AttrOpaque1.mjs @@ -1,5 +1,6 @@ import wasm from "./diplomat-wasm.mjs" import * as diplomatRuntime from "./diplomat-runtime.mjs" +import { AttrEnum_js_to_rust, AttrEnum_rust_to_js } from "./AttrEnum.mjs" const AttrOpaque1_box_destroy_registry = new FinalizationRegistry(underlying => { wasm.namespace_AttrOpaque1_destroy(underlying); @@ -30,4 +31,12 @@ export class AttrOpaque1 { method_disabledcpp() { wasm.namespace_AttrOpaque1_method_disabledcpp(this.underlying); } + + use_unnamespaced(arg__un) { + wasm.namespace_AttrOpaque1_use_unnamespaced(this.underlying, arg__un.underlying); + } + + use_namespaced(arg__n) { + wasm.namespace_AttrOpaque1_use_namespaced(this.underlying, AttrEnum_js_to_rust[arg__n]); + } } diff --git a/feature_tests/js/api/Unnamespaced.d.ts b/feature_tests/js/api/Unnamespaced.d.ts new file mode 100644 index 000000000..95678c799 --- /dev/null +++ b/feature_tests/js/api/Unnamespaced.d.ts @@ -0,0 +1,15 @@ +import { AttrEnum } from "./AttrEnum"; +import { AttrOpaque1 } from "./AttrOpaque1"; + +/** + */ +export class Unnamespaced { + + /** + */ + static make(e: AttrEnum): Unnamespaced; + + /** + */ + use_namespaced(_n: AttrOpaque1): void; +} diff --git a/feature_tests/js/api/Unnamespaced.mjs b/feature_tests/js/api/Unnamespaced.mjs new file mode 100644 index 000000000..da3d79f38 --- /dev/null +++ b/feature_tests/js/api/Unnamespaced.mjs @@ -0,0 +1,26 @@ +import wasm from "./diplomat-wasm.mjs" +import * as diplomatRuntime from "./diplomat-runtime.mjs" +import { AttrEnum_js_to_rust, AttrEnum_rust_to_js } from "./AttrEnum.mjs" + +const Unnamespaced_box_destroy_registry = new FinalizationRegistry(underlying => { + wasm.namespace_Unnamespaced_destroy(underlying); +}); + +export class Unnamespaced { + #lifetimeEdges = []; + constructor(underlying, owned, edges) { + this.underlying = underlying; + this.#lifetimeEdges.push(...edges); + if (owned) { + Unnamespaced_box_destroy_registry.register(this, underlying); + } + } + + static make(arg_e) { + return new Unnamespaced(wasm.namespace_Unnamespaced_make(AttrEnum_js_to_rust[arg_e]), true, []); + } + + use_namespaced(arg__n) { + wasm.namespace_Unnamespaced_use_namespaced(this.underlying, arg__n.underlying); + } +} diff --git a/feature_tests/js/api/index.d.ts b/feature_tests/js/api/index.d.ts index 245defa92..342d4b81b 100644 --- a/feature_tests/js/api/index.d.ts +++ b/feature_tests/js/api/index.d.ts @@ -25,3 +25,4 @@ export { RefListParameter } from './RefListParameter'; export { ResultOpaque } from './ResultOpaque'; export { Two } from './Two'; export { UnimportedEnum } from './UnimportedEnum'; +export { Unnamespaced } from './Unnamespaced'; diff --git a/feature_tests/js/api/index.mjs b/feature_tests/js/api/index.mjs index 8e2819c45..cebec86fa 100644 --- a/feature_tests/js/api/index.mjs +++ b/feature_tests/js/api/index.mjs @@ -25,3 +25,4 @@ export { RefListParameter } from './RefListParameter.mjs'; export { ResultOpaque } from './ResultOpaque.mjs'; export { Two } from './Two.mjs'; export { UnimportedEnum } from './UnimportedEnum.mjs'; +export { Unnamespaced } from './Unnamespaced.mjs'; diff --git a/feature_tests/js/docs/source/attrs_ffi.rst b/feature_tests/js/docs/source/attrs_ffi.rst index 3b050ba2b..7ef0d5690 100644 --- a/feature_tests/js/docs/source/attrs_ffi.rst +++ b/feature_tests/js/docs/source/attrs_ffi.rst @@ -13,4 +13,14 @@ .. js:method:: method_disabledcpp() + .. js:method:: use_unnamespaced(_un) + + .. js:method:: use_namespaced(_n) + .. js:class:: AttrOpaque2 + +.. js:class:: Unnamespaced + + .. js:function:: make(e) + + .. js:method:: use_namespaced(_n) From 8ec93a12b371e57db2d9229205c9279742974dd0 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Feb 2024 16:32:42 -0800 Subject: [PATCH 10/16] clippy --- tool/src/cpp2/header.rs | 6 +++--- tool/src/cpp2/ty.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tool/src/cpp2/header.rs b/tool/src/cpp2/header.rs index bb8bbc6a7..457416a35 100644 --- a/tool/src/cpp2/header.rs +++ b/tool/src/cpp2/header.rs @@ -1,6 +1,6 @@ use askama::Template; use diplomat_core::hir::TypeDef; -use std::borrow::{Borrow, Cow}; +use std::borrow::{Cow}; use std::collections::{BTreeMap, BTreeSet}; use std::fmt::{self, Write}; @@ -96,10 +96,10 @@ impl Header { pub fn rm_forward(&mut self, def: TypeDef, ty_name_unnamespaced: &str) { let ns = &def.attrs().namespace; let forward = Self::forward_for(def, ty_name_unnamespaced); - if let Some(ns_table) = self.forwards.get_mut(&ns) { + if let Some(ns_table) = self.forwards.get_mut(ns) { ns_table.remove(&forward); if ns_table.is_empty() { - self.forwards.remove(&ns); + self.forwards.remove(ns); } } } diff --git a/tool/src/cpp2/ty.rs b/tool/src/cpp2/ty.rs index ffd379795..207fc1566 100644 --- a/tool/src/cpp2/ty.rs +++ b/tool/src/cpp2/ty.rs @@ -14,7 +14,7 @@ impl<'tcx> super::Cpp2Context<'tcx> { // Skip type if disabled return; } - let type_name = self.formatter.fmt_type_name(id); + let _type_name = self.formatter.fmt_type_name(id); let type_name_unnamespaced = self.formatter.fmt_type_name(id); let decl_header_path = self.formatter.fmt_decl_header_path(id); let mut decl_header = Header::new(decl_header_path.clone()); @@ -40,8 +40,8 @@ impl<'tcx> super::Cpp2Context<'tcx> { // a header will get its own forwards and includes. Instead of // trying to avoid pushing them, it's cleaner to just pull them out // once done - context.decl_header.rm_forward(ty, &*type_name_unnamespaced); - context.impl_header.rm_forward(ty, &*type_name_unnamespaced); + context.decl_header.rm_forward(ty, &type_name_unnamespaced); + context.impl_header.rm_forward(ty, &type_name_unnamespaced); context.decl_header.includes.remove(&*decl_header_path); context.impl_header.includes.remove(&*impl_header_path); context.impl_header.includes.remove(&*decl_header_path); @@ -146,7 +146,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &type_name, ctype: &ctype, methods: methods.as_slice(), - namespace: ty.attrs.namespace.as_ref().map(|x| &**x), + namespace: ty.attrs.namespace.as_deref(), type_name_unnamespaced: &type_name_unnamespaced, } .render_into(self.decl_header) @@ -209,7 +209,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { type_name: &type_name, ctype: &ctype, methods: methods.as_slice(), - namespace: ty.attrs.namespace.as_ref().map(|x| &**x), + namespace: ty.attrs.namespace.as_deref(), type_name_unnamespaced: &type_name_unnamespaced, } .render_into(self.decl_header) @@ -291,7 +291,7 @@ impl<'ccx, 'tcx: 'ccx, 'header> TyGenContext<'ccx, 'tcx, 'header> { ctype: &ctype, fields: field_decls.as_slice(), methods: methods.as_slice(), - namespace: def.attrs.namespace.as_ref().map(|x| &**x), + namespace: def.attrs.namespace.as_deref(), type_name_unnamespaced: &type_name_unnamespaced, } .render_into(self.decl_header) From 42ba120893640aabb190577c04bd739ece04ebd5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 13 Feb 2024 08:56:11 -0800 Subject: [PATCH 11/16] fmt --- tool/src/cpp2/header.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/src/cpp2/header.rs b/tool/src/cpp2/header.rs index 457416a35..0596aefad 100644 --- a/tool/src/cpp2/header.rs +++ b/tool/src/cpp2/header.rs @@ -1,6 +1,6 @@ use askama::Template; use diplomat_core::hir::TypeDef; -use std::borrow::{Cow}; +use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet}; use std::fmt::{self, Write}; From 9356d1b686286894e2a6eeeb264c187bbafe757e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 13 Feb 2024 09:20:12 -0800 Subject: [PATCH 12/16] make --- feature_tests/src/attrs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature_tests/src/attrs.rs b/feature_tests/src/attrs.rs index 5197b6a11..5cd443384 100644 --- a/feature_tests/src/attrs.rs +++ b/feature_tests/src/attrs.rs @@ -49,7 +49,7 @@ pub mod ffi { pub struct Unnamespaced; impl Unnamespaced { - pub fn make(e: AttrEnum) -> Box { + pub fn make(_e: AttrEnum) -> Box { Box::new(Self) } From dee7b56bfda6ad8becfd6985860b34fc36232e7d Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 20 Feb 2024 09:15:12 -0800 Subject: [PATCH 13/16] regen rebase --- feature_tests/c/include/Unnamespaced.h | 2 +- feature_tests/c2/include/Unnamespaced.h | 2 +- feature_tests/cpp/docs/source/attrs_ffi.rst | 2 +- feature_tests/cpp/include/Unnamespaced.h | 2 +- feature_tests/cpp/include/Unnamespaced.hpp | 6 +++--- feature_tests/cpp2/include/Unnamespaced.d.hpp | 2 +- feature_tests/cpp2/include/Unnamespaced.h | 2 +- feature_tests/cpp2/include/Unnamespaced.hpp | 4 ++-- feature_tests/js/api/Unnamespaced.d.ts | 2 +- feature_tests/js/api/Unnamespaced.mjs | 4 ++-- feature_tests/js/docs/source/attrs_ffi.rst | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/feature_tests/c/include/Unnamespaced.h b/feature_tests/c/include/Unnamespaced.h index 2d6d936f4..e16224164 100644 --- a/feature_tests/c/include/Unnamespaced.h +++ b/feature_tests/c/include/Unnamespaced.h @@ -21,7 +21,7 @@ namespace capi { extern "C" { #endif -Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); +Unnamespaced* namespace_Unnamespaced_make(AttrEnum _e); void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); void namespace_Unnamespaced_destroy(Unnamespaced* self); diff --git a/feature_tests/c2/include/Unnamespaced.h b/feature_tests/c2/include/Unnamespaced.h index 65eb5d88f..7ee8aab6b 100644 --- a/feature_tests/c2/include/Unnamespaced.h +++ b/feature_tests/c2/include/Unnamespaced.h @@ -19,7 +19,7 @@ extern "C" { #endif // __cplusplus -Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); +Unnamespaced* namespace_Unnamespaced_make(AttrEnum _e); void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); diff --git a/feature_tests/cpp/docs/source/attrs_ffi.rst b/feature_tests/cpp/docs/source/attrs_ffi.rst index c957c64a1..5346791af 100644 --- a/feature_tests/cpp/docs/source/attrs_ffi.rst +++ b/feature_tests/cpp/docs/source/attrs_ffi.rst @@ -33,7 +33,7 @@ .. cpp:class:: Unnamespaced - .. cpp:function:: static Unnamespaced make(AttrEnum e) + .. cpp:function:: static Unnamespaced make(AttrEnum _e) .. cpp:function:: void use_namespaced(const AttrOpaque1& _n) const diff --git a/feature_tests/cpp/include/Unnamespaced.h b/feature_tests/cpp/include/Unnamespaced.h index 2d6d936f4..e16224164 100644 --- a/feature_tests/cpp/include/Unnamespaced.h +++ b/feature_tests/cpp/include/Unnamespaced.h @@ -21,7 +21,7 @@ namespace capi { extern "C" { #endif -Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); +Unnamespaced* namespace_Unnamespaced_make(AttrEnum _e); void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); void namespace_Unnamespaced_destroy(Unnamespaced* self); diff --git a/feature_tests/cpp/include/Unnamespaced.hpp b/feature_tests/cpp/include/Unnamespaced.hpp index 887a02c3a..9466c7938 100644 --- a/feature_tests/cpp/include/Unnamespaced.hpp +++ b/feature_tests/cpp/include/Unnamespaced.hpp @@ -25,7 +25,7 @@ struct UnnamespacedDeleter { }; class Unnamespaced { public: - static Unnamespaced make(AttrEnum e); + static Unnamespaced make(AttrEnum _e); void use_namespaced(const AttrOpaque1& _n) const; inline const capi::Unnamespaced* AsFFI() const { return this->inner.get(); } inline capi::Unnamespaced* AsFFIMut() { return this->inner.get(); } @@ -39,8 +39,8 @@ class Unnamespaced { #include "AttrOpaque1.hpp" -inline Unnamespaced Unnamespaced::make(AttrEnum e) { - return Unnamespaced(capi::namespace_Unnamespaced_make(static_cast(e))); +inline Unnamespaced Unnamespaced::make(AttrEnum _e) { + return Unnamespaced(capi::namespace_Unnamespaced_make(static_cast(_e))); } inline void Unnamespaced::use_namespaced(const AttrOpaque1& _n) const { capi::namespace_Unnamespaced_use_namespaced(this->inner.get(), _n.AsFFI()); diff --git a/feature_tests/cpp2/include/Unnamespaced.d.hpp b/feature_tests/cpp2/include/Unnamespaced.d.hpp index 01725a1bd..b5b9043ad 100644 --- a/feature_tests/cpp2/include/Unnamespaced.d.hpp +++ b/feature_tests/cpp2/include/Unnamespaced.d.hpp @@ -19,7 +19,7 @@ class CPPRenamedAttrEnum; class Unnamespaced { public: - inline static std::unique_ptr make(ns::CPPRenamedAttrEnum e); + inline static std::unique_ptr make(ns::CPPRenamedAttrEnum _e); inline void use_namespaced(const ns::AttrOpaque1Renamed& _n) const; diff --git a/feature_tests/cpp2/include/Unnamespaced.h b/feature_tests/cpp2/include/Unnamespaced.h index 65eb5d88f..7ee8aab6b 100644 --- a/feature_tests/cpp2/include/Unnamespaced.h +++ b/feature_tests/cpp2/include/Unnamespaced.h @@ -19,7 +19,7 @@ extern "C" { #endif // __cplusplus -Unnamespaced* namespace_Unnamespaced_make(AttrEnum e); +Unnamespaced* namespace_Unnamespaced_make(AttrEnum _e); void namespace_Unnamespaced_use_namespaced(const Unnamespaced* self, const AttrOpaque1* _n); diff --git a/feature_tests/cpp2/include/Unnamespaced.hpp b/feature_tests/cpp2/include/Unnamespaced.hpp index 568b59d8d..bbe0fb0b3 100644 --- a/feature_tests/cpp2/include/Unnamespaced.hpp +++ b/feature_tests/cpp2/include/Unnamespaced.hpp @@ -15,8 +15,8 @@ #include "Unnamespaced.h" -inline std::unique_ptr Unnamespaced::make(ns::CPPRenamedAttrEnum e) { - auto result = capi::namespace_Unnamespaced_make(e.AsFFI()); +inline std::unique_ptr Unnamespaced::make(ns::CPPRenamedAttrEnum _e) { + auto result = capi::namespace_Unnamespaced_make(_e.AsFFI()); return std::unique_ptr(Unnamespaced::FromFFI(result)); } diff --git a/feature_tests/js/api/Unnamespaced.d.ts b/feature_tests/js/api/Unnamespaced.d.ts index 95678c799..eb19c1116 100644 --- a/feature_tests/js/api/Unnamespaced.d.ts +++ b/feature_tests/js/api/Unnamespaced.d.ts @@ -7,7 +7,7 @@ export class Unnamespaced { /** */ - static make(e: AttrEnum): Unnamespaced; + static make(_e: AttrEnum): Unnamespaced; /** */ diff --git a/feature_tests/js/api/Unnamespaced.mjs b/feature_tests/js/api/Unnamespaced.mjs index da3d79f38..c1d0ccaf1 100644 --- a/feature_tests/js/api/Unnamespaced.mjs +++ b/feature_tests/js/api/Unnamespaced.mjs @@ -16,8 +16,8 @@ export class Unnamespaced { } } - static make(arg_e) { - return new Unnamespaced(wasm.namespace_Unnamespaced_make(AttrEnum_js_to_rust[arg_e]), true, []); + static make(arg__e) { + return new Unnamespaced(wasm.namespace_Unnamespaced_make(AttrEnum_js_to_rust[arg__e]), true, []); } use_namespaced(arg__n) { diff --git a/feature_tests/js/docs/source/attrs_ffi.rst b/feature_tests/js/docs/source/attrs_ffi.rst index 7ef0d5690..b75118a98 100644 --- a/feature_tests/js/docs/source/attrs_ffi.rst +++ b/feature_tests/js/docs/source/attrs_ffi.rst @@ -21,6 +21,6 @@ .. js:class:: Unnamespaced - .. js:function:: make(e) + .. js:function:: make(_e) .. js:method:: use_namespaced(_n) From 642bbb1aedd9071527790693336845494176e267 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 21 Feb 2024 15:00:30 -0800 Subject: [PATCH 14/16] spacing --- feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp | 3 ++- feature_tests/cpp2/include/Unnamespaced.d.hpp | 1 + tool/templates/cpp2/base.h.jinja | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp index 110976c4d..7268655f1 100644 --- a/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp +++ b/feature_tests/cpp2/include/AttrOpaque1Renamed.d.hpp @@ -11,7 +11,8 @@ #include "AttrOpaque1.d.h" #include "CPPRenamedAttrEnum.d.hpp" -class Unnamespaced;namespace ns { +class Unnamespaced; +namespace ns { class AttrOpaque1Renamed; class CPPRenamedAttrEnum; } diff --git a/feature_tests/cpp2/include/Unnamespaced.d.hpp b/feature_tests/cpp2/include/Unnamespaced.d.hpp index b5b9043ad..9a289f55a 100644 --- a/feature_tests/cpp2/include/Unnamespaced.d.hpp +++ b/feature_tests/cpp2/include/Unnamespaced.d.hpp @@ -10,6 +10,7 @@ #include "diplomat_runtime.hpp" #include "CPPRenamedAttrEnum.d.hpp" #include "Unnamespaced.d.h" + namespace ns { class AttrOpaque1Renamed; class CPPRenamedAttrEnum; diff --git a/tool/templates/cpp2/base.h.jinja b/tool/templates/cpp2/base.h.jinja index a7326d0f7..b8eecd257 100644 --- a/tool/templates/cpp2/base.h.jinja +++ b/tool/templates/cpp2/base.h.jinja @@ -20,7 +20,7 @@ {%~ if forwards.len() > 0 %} {%- for namespace_forward in forwards %} -{%- if let Some(ns) = namespace_forward.0 -%} +{%- if let Some(ns) = namespace_forward.0 %} namespace {{ns}} { {%- endif-%} {%- for forward in namespace_forward.1 %} From 46a6eff8079fffdbac985938d81cd9604614e462 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 21 Feb 2024 15:00:38 -0800 Subject: [PATCH 15/16] unused --- tool/src/cpp2/ty.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tool/src/cpp2/ty.rs b/tool/src/cpp2/ty.rs index 207fc1566..5d557d098 100644 --- a/tool/src/cpp2/ty.rs +++ b/tool/src/cpp2/ty.rs @@ -14,7 +14,6 @@ impl<'tcx> super::Cpp2Context<'tcx> { // Skip type if disabled return; } - let _type_name = self.formatter.fmt_type_name(id); let type_name_unnamespaced = self.formatter.fmt_type_name(id); let decl_header_path = self.formatter.fmt_decl_header_path(id); let mut decl_header = Header::new(decl_header_path.clone()); From 7cdd08a8f40c78b51813926b5140535c67c68995 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 21 Feb 2024 15:05:45 -0800 Subject: [PATCH 16/16] comment --- tool/src/cpp2/header.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tool/src/cpp2/header.rs b/tool/src/cpp2/header.rs index 0596aefad..118c7a625 100644 --- a/tool/src/cpp2/header.rs +++ b/tool/src/cpp2/header.rs @@ -40,7 +40,9 @@ pub struct Header { pub includes: BTreeSet, /// The decl file corresponding to this impl file. Empty if this is not an impl file. pub decl_include: Option, - /// The struct forward decls necessary + /// The struct forward decls necessary. + /// + /// The keys on this map are the namespaces (None = root namespace) /// /// Example: /// ```c