nitro
nitro copied to clipboard
`Record<string, number>` generates wrong code on Kotlin
What's happening?
Using a typescript type with a nested record type results in C++ compiler errors in nitrogen-generated code, due to lack of JSI-type wrapping.
Reproduceable Code
interface DataPoint {
point: Record<string, number>;
tooltipText?: string;
}
Relevant log output
.../fbjni-0.7.0/prefab/modules/fbjni/include/fbjni/detail/References.h:190:25: error: implicit instantiation of undefined template 'facebook::jni::detail::RefReprType<double>'
Device
Android
Nitro Modules Version
0.31.7
Nitrogen Version
0.31.7
Can you reproduce this issue in the Nitro Example app here?
I didn't try (⚠️ your issue might get ignored & closed if you don't try this)
Additional information
- [ ] I am using Expo
- [x] I am using nitrogen
- [x] I have read and followed the Troubleshooting Guide.
- [ ] I created a reproduction PR to reproduce this issue here in the nitro repo. (See Contributing for more information)
- [x] I searched for similar issues in this repository and found none.
The TS code above generates the following C++ code:
DataPoint toCpp() const {
static const auto clazz = javaClassStatic();
static const auto fieldPoint = clazz->getField<jni::JMap<jni::JString, double>>("point");
jni::local_ref<jni::JMap<jni::JString, double>> point = this->getFieldValue(fieldPoint);
static const auto fieldTooltipText = clazz->getField<jni::JString>("tooltipText");
jni::local_ref<jni::JString> tooltipText = this->getFieldValue(fieldTooltipText);
return DataPoint(
[&]() {
std::unordered_map<std::string, double> __map;
__map.reserve(point->size());
for (const auto& __entry : *point) {
__map.emplace(__entry.first->toStdString(), __entry.second);
}
return __map;
}(),
tooltipText != nullptr ? std::make_optional(tooltipText->toStdString()) : std::nullopt
);
}
Notice that the point map is declared as jni::JMap<jni::JString, double> instead of jni::JMap<jni::JString, jsi::JDouble>. This in turn results in the compiler error above when trying to iterate over it.
Patching the file manually to use jsi::JDouble (as below), resolves the issue:
diff --git a/snip/nitrogen/generated/android/c++/JDataPoint.hpp b/snip/nitrogen/generated/android/c++/JDataPoint.hpp
index 7e561156..756a82b9 100644
--- a/snip/nitrogen/generated/android/c++/JDataPoint.hpp
+++ b/snip/nitrogen/generated/android/c++/JDataPoint.hpp
@@ -33,8 +33,8 @@ namespace margelo::nitro::mymodule {
[[nodiscard]]
DataPoint toCpp() const {
static const auto clazz = javaClassStatic();
- static const auto fieldPoint = clazz->getField<jni::JMap<jni::JString, double>>("point");
- jni::local_ref<jni::JMap<jni::JString, double>> point = this->getFieldValue(fieldPoint);
+ static const auto fieldPoint = clazz->getField<jni::JMap<jni::JString, jni::JDouble>>("point");
+ jni::local_ref<jni::JMap<jni::JString, jni::JDouble>> point = this->getFieldValue(fieldPoint);
static const auto fieldTooltipText = clazz->getField<jni::JString>("tooltipText");
jni::local_ref<jni::JString> tooltipText = this->getFieldValue(fieldTooltipText);
return DataPoint(
@@ -42,7 +42,7 @@ namespace margelo::nitro::mymodule {
std::unordered_map<std::string, double> __map;
__map.reserve(point->size());
for (const auto& __entry : *point) {
- __map.emplace(__entry.first->toStdString(), __entry.second);
+ __map.emplace(__entry.first->toStdString(), __entry.second->doubleValue());
}
return __map;
}(),
@@ -56,15 +56,15 @@ namespace margelo::nitro::mymodule {
*/
[[maybe_unused]]
static jni::local_ref<JDataPoint::javaobject> fromCpp(const DataPoint& value) {
- using JSignature = JDataPoint(jni::alias_ref<jni::JMap<jni::JString, double>>, jni::alias_ref<jni::JString>);
+ using JSignature = JDataPoint(jni::alias_ref<jni::JMap<jni::JString, jni::JDouble>>, jni::alias_ref<jni::JString>);
static const auto clazz = javaClassStatic();
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
return create(
clazz,
- [&]() -> jni::local_ref<jni::JMap<jni::JString, double>> {
- auto __map = jni::JHashMap<jni::JString, double>::create(value.point.size());
+ [&]() -> jni::local_ref<jni::JMap<jni::JString, jni::JDouble>> {
+ auto __map = jni::JHashMap<jni::JString, jni::JDouble>::create(value.point.size());
for (const auto& __entry : value.point) {
- __map->put(jni::make_jstring(__entry.first), __entry.second);
+ __map->put(jni::make_jstring(__entry.first), jni::JDouble::valueOf(__entry.second));
}
return __map;
}(),
fixed in https://github.com/mrousavy/nitro/pull/1061